You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2004/06/25 18:02:28 UTC
cvs commit: db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess PersistentFieldBase.java PersistentFieldIntrospectorImpl.java
arminw 2004/06/25 09:02:28
Modified: src/java/org/apache/ojb/broker/metadata/fieldaccess
PersistentFieldIntrospectorImpl.java
Added: src/java/org/apache/ojb/broker/metadata/fieldaccess
PersistentFieldBase.java
Log:
update support for nested fields
Revision Changes Path
1.9 +61 -47 db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldIntrospectorImpl.java
Index: PersistentFieldIntrospectorImpl.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldIntrospectorImpl.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- PersistentFieldIntrospectorImpl.java 24 Jun 2004 22:05:15 -0000 1.8
+++ PersistentFieldIntrospectorImpl.java 25 Jun 2004 16:02:28 -0000 1.9
@@ -24,21 +24,23 @@
import java.util.List;
import org.apache.commons.lang.StringUtils;
+import org.apache.ojb.broker.core.proxy.ProxyHelper;
import org.apache.ojb.broker.metadata.MetadataException;
+import org.apache.ojb.broker.util.ClassHelper;
import org.apache.ojb.broker.util.logging.Logger;
-import org.apache.ojb.broker.util.logging.LoggerFactory;
/**
* A {@link PersistentField} implementation using
* JavaBeans compliant calls only to access persistent attributes.
* No Reflection is needed. But for each attribute xxx there must be
- * public getXxx() and setXxx() methods.
+ * public getXxx() and setXxx() methods. In metadata the field name must be
+ * the bean compliant 'xxx'.
*
* @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
* @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
* @version $Id$
*/
-public class PersistentFieldIntrospectorImpl extends AbstractPersistentField
+public class PersistentFieldIntrospectorImpl extends PersistentFieldBase
{
private static final long serialVersionUID = 8805309492150404444L;
private Class type;
@@ -54,18 +56,9 @@
super(aClass, aPropertyName);
}
- /*
- need to overwrite these three methods to avoid
- building of Field instances
- */
- public String getName()
- {
- return this.fieldName;
- }
-
public Class getType()
{
- if(type == null)
+ if (type == null)
{
type = getPropertyDescriptor().getPropertyType();
}
@@ -77,6 +70,16 @@
return this.rootObjectType;
}
+ public void set(Object obj, Object value) throws MetadataException
+ {
+ writeValue(obj, value);
+ }
+
+ public Object get(Object anObject) throws MetadataException
+ {
+ return readValue(anObject);
+ }
+
private void writeValue(Object target, Object value)
{
List propertyDescriptors = getPropertyGraph();
@@ -84,8 +87,31 @@
PropertyDescriptor pd;
for (int i = 0; i < size; i++)
{
- pd = (PropertyDescriptor) propertyDescriptors.get(i);
- target = getValueFrom(pd, target);
+ Object attribute = null;
+ pd = (PropertyDescriptor) propertyDescriptors.get(i);
+ attribute = getValueFrom(pd, target);
+ if (attribute != null || value != null)
+ {
+ if (attribute == null)
+ {
+ try
+ {
+ attribute = ClassHelper.newInstance(pd.getPropertyType());
+ }
+ catch (Exception e)
+ {
+ throw new MetadataException("Can't instantiate nested object of type '"
+ + pd.getPropertyType() + "' for field '"
+ + pd.getName() + "'", e);
+ }
+ }
+ setValueFor(pd, target, attribute);
+ }
+ else
+ {
+ return;
+ }
+ target = attribute;
}
pd = (PropertyDescriptor) propertyDescriptors.get(size);
setValueFor(pd, target, value);
@@ -96,31 +122,32 @@
List propertyDescriptors = getPropertyGraph();
for (int i = 0; i < propertyDescriptors.size(); i++)
{
- PropertyDescriptor pd = (PropertyDescriptor) propertyDescriptors.get(i);
+ PropertyDescriptor pd = (PropertyDescriptor) propertyDescriptors.get(i);
target = getValueFrom(pd, target);
+ if (target == null) break;
}
return target;
}
private Object getValueFrom(PropertyDescriptor pd, Object target)
{
- if(target == null) return null;
+ if (target == null) return null;
Method m = pd.getReadMethod();
if (m != null)
{
try
{
- return m.invoke(target, null);
+ return m.invoke(ProxyHelper.getRealObject(target), null);
}
catch (Throwable e)
{
+ logProblem(pd, target, null, "Can't read value from given object");
throw new MetadataException("Error invoking method:" + m.getName() + " in object " + target.getClass().getName(), e);
}
}
else
{
- throw new MetadataException(
- "Can't get ReadMethod for property:" + pd.getName() + " in object " + target.getClass().getName());
+ throw new MetadataException("Can't get ReadMethod for property:" + pd.getName() + " in object " + target.getClass().getName());
}
}
@@ -140,24 +167,24 @@
*/
if ((value != null) || !m.getParameterTypes()[0].isPrimitive())
{
- m.invoke(target, args);
+ m.invoke(ProxyHelper.getRealObject(target), args);
}
}
catch (Throwable e)
{
+ logProblem(pd, target, value, "Can't set value on given object.");
throw new MetadataException("Error invoking method:" + m.getName() + " in object:" + target.getClass().getName(), e);
}
}
else
{
- throw new MetadataException(
- "Can't get WriteMethod for property:" + pd.getName() + " in object:" + target.getClass().getName());
+ throw new MetadataException("Can't get WriteMethod for property:" + pd.getName() + " in object:" + target.getClass().getName());
}
}
private List getPropertyGraph()
{
- if(propertyGraph == null)
+ if (propertyGraph == null)
{
propertyGraph = buildPropertyGraph();
}
@@ -172,9 +199,9 @@
for (int i = 0; i < fields.length; i++)
{
String fieldName = fields[i];
- if(pd == null)
+ if (pd == null)
{
- pd = findPropertyDescriptor( getDeclaringClass(), fieldName);
+ pd = findPropertyDescriptor(getDeclaringClass(), fieldName);
}
else
{
@@ -186,22 +213,6 @@
}
/**
- * Sets aValue for anObject
- */
- public void doSet(Object anObject, Object aValue) throws MetadataException
- {
- writeValue(anObject, aValue);
- }
-
- /**
- * Get the Value from anObject
- */
- public Object doGet(Object anObject) throws MetadataException
- {
- return readValue(anObject);
- }
-
- /**
* Get the PropertyDescriptor for aClass and aPropertyName
*/
protected static PropertyDescriptor findPropertyDescriptor(Class aClass, String aPropertyName)
@@ -244,15 +255,17 @@
/**
* Returns the PropertyDescriptor.
+ *
* @return java.beans.PropertyDescriptor
*/
protected PropertyDescriptor getPropertyDescriptor()
{
- return (PropertyDescriptor) getPropertyGraph().get(getPropertyGraph().size()-1);
+ return (PropertyDescriptor) getPropertyGraph().get(getPropertyGraph().size() - 1);
}
/**
* This implementation returns always 'false'.
+ *
* @see AbstractPersistentField#makeAccessible()
*/
public boolean makeAccessible()
@@ -262,6 +275,7 @@
/**
* Always returns 'false'.
+ *
* @see PersistentField#usesAccessorsAndMutators
*/
public boolean usesAccessorsAndMutators()
@@ -272,13 +286,13 @@
/**
* Let's give the user some hints as to what could be wrong.
*/
- protected void logProblem(Object anObject, Object aValue, String msg)
+ protected void logProblem(PropertyDescriptor pd, Object anObject, Object aValue, String msg)
{
- Logger logger = LoggerFactory.getDefaultLogger();
+ Logger logger = getLog();
logger.error("Error in [PersistentFieldPropertyImpl], " + msg);
logger.error("Declaring class [" + getDeclaringClass().getName() + "]");
logger.error("Property Name [" + getName() + "]");
- logger.error("Property Type [" + getPropertyDescriptor().getPropertyType().getName() + "]");
+ logger.error("Property Type [" + pd.getPropertyType().getName() + "]");
if (anObject != null)
{
1.1 db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldBase.java
Index: PersistentFieldBase.java
===================================================================
package org.apache.ojb.broker.metadata.fieldaccess;
/* Copyright 2003-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.ojb.broker.metadata.MetadataException;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
/**
* Abstract {@link PersistentField} base implementation class.
*
* @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
* @version $Id: PersistentFieldBase.java,v 1.1 2004/06/25 16:02:28 arminw Exp $
*/
public abstract class PersistentFieldBase implements PersistentField
{
public static final String PATH_TOKEN = "::";
private String fieldName;
protected Class rootObjectType;
/**
* For internal use only!!
* TODO: Default constructor only needed to support
* PersistentFieldFactory#usesAccessorsAndMutators()
* method - find a better solution. Make 'public' to
* allow helper class to instantiate class.
*/
public PersistentFieldBase()
{
}
public PersistentFieldBase(Class clazz, String fieldname)
{
this.rootObjectType = clazz;
this.fieldName = fieldname;
}
/**
* A value of true indicates that this field should
* suppress Java language access checking when it is used.
*/
protected abstract boolean makeAccessible();
public String getName()
{
return fieldName;
}
protected List getFieldGraph(boolean makeAccessible)
{
List result = new ArrayList();
String[] fields = StringUtils.split(getName(), PATH_TOKEN);
Field fld = null;
for (int i = 0; i < fields.length; i++)
{
String fieldName = fields[i];
try
{
if (fld == null)
{
fld = getFieldRecursive(rootObjectType, fieldName);
}
else
{
fld = getFieldRecursive(fld.getType(), fieldName);
}
if (makeAccessible)
{
fld.setAccessible(true);
}
}
catch (NoSuchFieldException e)
{
throw new MetadataException("Can't find member '"
+ fieldName + "' in class " + (fld != null ? fld.getDeclaringClass() : rootObjectType), e);
}
result.add(fld);
}
return result;
}
/**
* try to find a field in class c, recurse through class hierarchy if necessary
*
* @throws NoSuchFieldException if no Field was found into the class hierarchy
*/
private Field getFieldRecursive(Class c, String name) throws NoSuchFieldException
{
try
{
Field f = c.getDeclaredField(name);
return f;
}
catch (NoSuchFieldException e)
{
// if field could not be found in the inheritance hierarchy, signal error
if ((c == Object.class) || (c.getSuperclass() == null) || c.isInterface())
{
throw e;
}
// if field could not be found in class c try in superclass
else
{
return getFieldRecursive(c.getSuperclass(), name);
}
}
}
protected Logger getLog()
{
return LoggerFactory.getLogger("PersistentField");
}
public String toString()
{
ToStringBuilder buf = new ToStringBuilder(this);
buf.append("rootType", rootObjectType);
buf.append("fieldName", fieldName);
return buf.toString();
}
/**
* Build a String representation of given arguments.
*/
protected String buildMessageString(Object obj, Object value, Field aField)
{
String eol = SystemUtils.LINE_SEPARATOR;
StringBuffer buf = new StringBuffer();
buf
.append(eol + "[try to set 'object value' in 'target object'")
.append(eol + "target obj class: " + (obj != null ? obj.getClass().getName() : null))
.append(eol + "target field name: " + (aField != null ? aField.getName() : null))
.append(eol + "target field type: " + (aField != null ? aField.getType() : null))
.append(eol + "object value class: " + (value != null ? value.getClass().getName() : null))
.append(eol + "object value: " + (value != null ? value : null))
.append(eol + "]");
return buf.toString();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org