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