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/05/06 20:54:44 UTC
cvs commit: db-ojb/src/java/org/apache/ojb/broker/util ClassHelper.java
arminw 2004/05/06 11:54:44
Modified: src/java/org/apache/ojb/broker/accesslayer
RowReaderDefaultImpl.java
src/java/org/apache/ojb/broker/util ClassHelper.java
Log:
refactoring, avoid duplicated code
Revision Changes Path
1.30 +92 -156 db-ojb/src/java/org/apache/ojb/broker/accesslayer/RowReaderDefaultImpl.java
Index: RowReaderDefaultImpl.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/RowReaderDefaultImpl.java,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- RowReaderDefaultImpl.java 4 Apr 2004 23:53:31 -0000 1.29
+++ RowReaderDefaultImpl.java 6 May 2004 18:54:44 -0000 1.30
@@ -15,27 +15,31 @@
* limitations under the License.
*/
+import java.lang.reflect.Method;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
import org.apache.ojb.broker.PBFactoryException;
import org.apache.ojb.broker.PersistenceBrokerException;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.FieldDescriptor;
-import org.apache.ojb.broker.util.ConstructorHelper;
+import org.apache.ojb.broker.util.ClassHelper;
import org.apache.ojb.broker.util.logging.LoggerFactory;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-
/**
+ * Default implementation of the {@link RowReader} interface.
+ *
* @version $Id$
*/
public class RowReaderDefaultImpl implements RowReader
{
+ /**
+ * represents a zero sized parameter array
+ */
+ private static final Object[] NO_ARGS = {};
+
private ClassDescriptor m_cld;
public RowReaderDefaultImpl(ClassDescriptor cld)
@@ -74,7 +78,66 @@
{
// allow to select a specific classdescriptor
ClassDescriptor cld = selectClassDescriptor(row);
- return buildWithReflection(row, cld);
+ return buildOrRefreshObject(row, cld, null);
+ }
+
+ /**
+ * @see org.apache.ojb.broker.accesslayer.RowReader#refreshObject(Object, Map)
+ */
+ public void refreshObject(Object instance, Map row)
+ {
+ // 1. select target ClassDescriptor
+ ClassDescriptor targetClassDescriptor = selectClassDescriptor(row);
+ // 2. fill all scalar attributes of the existing object
+ buildOrRefreshObject(row, targetClassDescriptor, instance);
+ }
+
+ /**
+ * Creates an object instance according to clb, and fills its fileds width data provided by row.
+ * @param row A {@link Map} contain the Object/Row mapping for the object.
+ * @param targetClassDescriptor If the "ojbConcreteClass" feature was used, the target
+ * {@link org.apache.ojb.broker.metadata.ClassDescriptor} could differ from the descriptor
+ * this class was associated - see {@link #selectClassDescriptor}.
+ * @param targetObject If 'null' a new object instance is build, else fields of object will
+ * be refreshed.
+ * @throws PersistenceBrokerException if there ewas an error creating the new object
+ */
+ protected Object buildOrRefreshObject(Map row, ClassDescriptor targetClassDescriptor, Object targetObject)
+ {
+ Object result = targetObject;
+ FieldDescriptor fmd = null;
+
+ if(targetObject == null)
+ {
+ // 1. create new object instance if needed
+ result = ClassHelper.buildNewObjectInstance(targetClassDescriptor);
+ }
+
+ // 2. fill all scalar attributes of the new object
+ FieldDescriptor[] fields = targetClassDescriptor.getFieldDescriptions();
+ for (int i = 0; i < fields.length; i++)
+ {
+ fmd = fields[i];
+ fmd.getPersistentField().set(result, row.get(fmd.getColumnName()));
+ }
+
+ if(targetObject == null)
+ {
+ // 3. for new build objects, invoke the initialization method for the class if one is provided
+ Method initializationMethod = targetClassDescriptor.getInitializationMethod();
+ if (initializationMethod != null)
+ {
+ try
+ {
+ initializationMethod.invoke(result, NO_ARGS);
+ }
+ catch (Exception ex)
+ {
+ throw new PersistenceBrokerException("Unable to invoke initialization method:" + initializationMethod.getName() + " for class:" + m_cld.getClassOfObject(), ex);
+ }
+ }
+ }
+ return result;
}
/**
@@ -98,7 +161,6 @@
public void readObjectArrayFrom(ResultSet rs, Map row)
{
FieldDescriptor[] fields = null;
-
if (m_cld.getSuperClass() != null)
{
/**
@@ -110,13 +172,27 @@
else
{
fields = m_cld.getRepository().getFieldDescriptorsForMultiMappedTable(m_cld);
-
}
+ readValuesFrom(rs, row, fields);
+ }
+
+ /*
+ * @see RowReader#readPkValuesFrom(ResultSet, ClassDescriptor, Map)
+ * @throws PersistenceBrokerException if there is an error accessing the access layer
+ */
+ public void readPkValuesFrom(ResultSet rs, Map row)
+ {
+ FieldDescriptor[] pkFields = m_cld.getPkFields();
+ readValuesFrom(rs, row, pkFields);
+ }
+
+ protected void readValuesFrom(ResultSet rs, Map row, FieldDescriptor[] fields)
+ {
int size = fields.length;
Object val = null;
+ FieldDescriptor fld = null;
try
{
- FieldDescriptor fld;
for (int j = 0; j < size; j++)
{
fld = fields[j];
@@ -126,7 +202,8 @@
}
catch (SQLException t)
{
- throw new PersistenceBrokerException("Error reading class type: " + m_cld.getClassNameOfObject() + " from result set", t);
+ throw new PersistenceBrokerException("Error reading class type: " + m_cld.getClassNameOfObject()
+ + " from result set, current read field was " + (fld != null ? fld.getPersistentField().getName() : null), t);
}
}
@@ -173,128 +250,6 @@
}
}
- /**
- * Creates an object instance according to clb, and fills its fileds width data provided by row.
- * @param row A {@link Map} contain the Object/Row mapping for the object.
- * @param targetClassDescriptor If the "ojbConcreteClass" feature was used, the target
- * {@link org.apache.ojb.broker.metadata.ClassDescriptor} could differ from the descriptor
- * this class was associated - see {@link #selectClassDescriptor}.
- * @throws PersistenceBrokerException if there ewas an error creating the new object
- */
- protected Object buildWithReflection(Map row, ClassDescriptor targetClassDescriptor)
- {
- Object result = null;
- FieldDescriptor fmd = null;
-
- // If either the factory class and/or factory method is null,
- // just follow the normal code path and create via constructor
- if (null == targetClassDescriptor.getFactoryClass() || null == targetClassDescriptor.getFactoryMethod())
- {
- try
- {
- // 1. create an empty Object (persistent classes need a public default constructor)
- Constructor con = targetClassDescriptor.getZeroArgumentConstructor();
- result = ConstructorHelper.instantiate(con);
- }
- catch (Exception ex)
- {
- throw new PersistenceBrokerException("Unable to build object instance (MAYBE you don't have a constructor available):" + m_cld.getClassOfObject(), ex);
- }
- }
- else
- {
- try
- {
- // 1. create an empty Object by calling the no-parms factory method
- Method method = targetClassDescriptor.getFactoryMethod();
-
- if (Modifier.isStatic(method.getModifiers()))
- {
- // method is static so call it directly
- result = method.invoke(null, null);
- }
- else
- {
- // method is not static, so create an object of the factory first
- // note that this requires a public no-parameter (default) constructor
- Object factoryInstance = targetClassDescriptor.getFactoryClass().newInstance();
-
- result = method.invoke(factoryInstance, null);
- }
- }
- catch (Exception ex)
- {
- throw new PersistenceBrokerException(
- "Unable to build object instance of class " + m_cld.getClassOfObject() + " from factory:" + m_cld.getFactoryClass() + "." + m_cld.getFactoryMethod(),
- ex);
- }
- }
-
- if (null != result)
- {
- // 2. fill all scalar attributes of the new object
- FieldDescriptor[] fields = targetClassDescriptor.getFieldDescriptions();
- for (int i = 0; i < fields.length; i++)
- {
- fmd = fields[i];
- fmd.getPersistentField().set(result, row.get(fmd.getColumnName()));
- }
-
- // 3. invoke the initialization method for the class if one is provided
- Method initializationMethod = targetClassDescriptor.getInitializationMethod();
- Object[] noArgs = {
- };
- if (initializationMethod != null)
- {
- try
- {
- initializationMethod.invoke(result, noArgs);
- }
- catch (Exception ex)
- {
- throw new PersistenceBrokerException("Unable to invoke initialization method:" + initializationMethod.getName() + " for class:" + m_cld.getClassOfObject(), ex);
- }
- }
- }
-
- return result;
- }
-
- protected Object buildWithMultiArgsConstructor(Map row, Constructor multiArgsConstructor)
- throws SQLException, InstantiationException, IllegalAccessException,
- InvocationTargetException, PersistenceBrokerException
- {
- Object result;
- // 1. call the constructor to build the object
- Object[] rowArray = row.values().toArray();
- result = multiArgsConstructor.newInstance(rowArray);
- return result;
- }
-
- /*
- * @see RowReader#readPkValuesFrom(ResultSet, ClassDescriptor, Map)
- * @throws PersistenceBrokerException if there is an error accessing the access layer
- */
- public void readPkValuesFrom(ResultSet rs, Map row)
- {
- try
- {
- FieldDescriptor[] pkFields = m_cld.getPkFields();
- Object val;
- FieldDescriptor fld;
- for (int i = 0; i < pkFields.length; i++)
- {
- fld = pkFields[i];
- val = fld.getJdbcType().getObjectFromColumn(rs, fld.getColumnName());
- row.put(fld.getColumnName(), fld.getFieldConversion().sqlToJava(val));
- }
- }
- catch (SQLException t)
- {
- throw new PersistenceBrokerException("Error reading from result set", t);
- }
- }
-
public void setClassDescriptor(ClassDescriptor cld)
{
this.m_cld = cld;
@@ -304,23 +259,4 @@
{
return m_cld;
}
-
- /**
- * @see org.apache.ojb.broker.accesslayer.RowReader#refreshObject(Object, Map)
- */
- public void refreshObject(Object instance, Map row)
- {
- // 1. select target ClassDescriptor
- ClassDescriptor targetClassDescriptor = selectClassDescriptor(row);
- // 2. fill all scalar attributes of the existing object
- FieldDescriptor[] fields = targetClassDescriptor.getFieldDescriptions();
- FieldDescriptor fmd;
- for (int i = 0; i < fields.length; i++)
- {
- fmd = fields[i];
- fmd.getPersistentField().set(instance, row.get(fmd.getColumnName()));
- }
-
- }
-
}
1.8 +58 -1 db-ojb/src/java/org/apache/ojb/broker/util/ClassHelper.java
Index: ClassHelper.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/util/ClassHelper.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- ClassHelper.java 3 May 2004 23:05:56 -0000 1.7
+++ ClassHelper.java 6 May 2004 18:54:44 -0000 1.8
@@ -19,8 +19,12 @@
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
import org.apache.ojb.broker.OJBRuntimeException;
+import org.apache.ojb.broker.PersistenceBrokerException;
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
/**
* Helper class with static methods for class, method, field handling.
@@ -243,5 +247,58 @@
{
}
return method;
+ }
+
+ /**
+ * Builds a new object instance based on the given {@link org.apache.ojb.broker.metadata.ClassDescriptor}.
+ */
+ public static Object buildNewObjectInstance(ClassDescriptor cld)
+ {
+ Object result = null;
+ // If either the factory class and/or factory method is null,
+ // just follow the normal code path and create via constructor
+ if (cld.getFactoryClass() == null || cld.getFactoryMethod() == null)
+ {
+ try
+ {
+ // 1. create an empty Object (persistent classes need a public default constructor)
+ Constructor con = cld.getZeroArgumentConstructor();
+ result = ConstructorHelper.instantiate(con);
+ }
+ catch(InstantiationException e)
+ {
+ throw new ClassNotPersistenceCapableException(
+ "Can't instantiate class '" + cld.getClassNameOfObject()+"'");
+ }
+ }
+ else
+ {
+ try
+ {
+ // 1. create an empty Object by calling the no-parms factory method
+ Method method = cld.getFactoryMethod();
+
+ if (Modifier.isStatic(method.getModifiers()))
+ {
+ // method is static so call it directly
+ result = method.invoke(null, null);
+ }
+ else
+ {
+ // method is not static, so create an object of the factory first
+ // note that this requires a public no-parameter (default) constructor
+ Object factoryInstance = cld.getFactoryClass().newInstance();
+
+ result = method.invoke(factoryInstance, null);
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new PersistenceBrokerException("Unable to build object instance of class '"
+ + cld.getClassNameOfObject() + "' from factory:" + cld.getFactoryClass()
+ + "." + cld.getFactoryMethod(), ex);
+ }
+ }
+ return result;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org