db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject cvs commit: db-ojb/src/test/org/apache/ojb OJB.properties
Date Sat, 18 Dec 2004 13:40:49 GMT
arminw      2004/12/18 05:40:49

  Modified:    src/java/org/apache/ojb/broker/metadata/fieldaccess
                        PersistentFieldAutoProxyImpl.java
                        PersistentFieldBase.java
                        PersistentFieldIntrospectorImpl.java
                        PersistentFieldPrivilegedImpl.java
               src/test/org/apache/ojb OJB.properties
  Added:       src/java/org/apache/ojb/broker/metadata/fieldaccess
                        PersistentFieldDirectImpl.java
                        PersistentFieldDynaBeanImpl.java
  Removed:     src/java/org/apache/ojb/broker/metadata/fieldaccess
                        AbstractPersistentField.java
                        PersistentFieldAutoProxyImplNew.java
                        PersistentFieldDirectAccessImpl.java
                        PersistentFieldDirectAccessImplNew.java
                        PersistentFieldDynaBeanAccessImpl.java
                        PersistentFieldDynaBeanImplNew.java
                        PersistentFieldIntrospectorImplNew.java
                        PersistentFieldPrivilegedImplNew.java
  Log:
  replace old PersistentField implementation with new ones (xxxImplNew classes), rename classes
  
  Revision  Changes    Path
  1.12      +120 -201  db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldAutoProxyImpl.java
  
  Index: PersistentFieldAutoProxyImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldAutoProxyImpl.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- PersistentFieldAutoProxyImpl.java	14 Nov 2004 09:36:10 -0000	1.11
  +++ PersistentFieldAutoProxyImpl.java	18 Dec 2004 13:40:48 -0000	1.12
  @@ -1,6 +1,6 @@
   package org.apache.ojb.broker.metadata.fieldaccess;
   
  -/* Copyright 2003-2004 The Apache Software Foundation
  +/* Copyright 2002-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.
  @@ -15,10 +15,8 @@
    * limitations under the License.
    */
   
  -import java.lang.reflect.Field;
  -import java.lang.reflect.Member;
  +import java.io.Serializable;
   
  -import org.apache.commons.beanutils.DynaBean;
   import org.apache.ojb.broker.metadata.MetadataException;
   import org.apache.ojb.broker.util.ClassHelper;
   
  @@ -26,271 +24,192 @@
    * PeristentField implementation that attempts to detect the nature of
    * the field it is persisting.
    * <p>
  - * First checks to see if it is a Field, then Property, then DynaBean
  + * First checks to see if it is a Field, then Property, then DynaBean. Dependend
  + * on the made checks this implementation internal use one of the following implementations:
    * <p>
  + * - {@link PersistentFieldDirectImpl} <br/>
  + * - {@link PersistentFieldIntrospectorImpl} <br/>
  + * - {@link PersistentFieldPrivilegedImpl} <br/>
  + * - {@link PersistentFieldDynaBeanImpl} <br/>
    * It will match in that order.
  + *
  + * @version $Id$
    */
  -public class PersistentFieldAutoProxyImpl extends AbstractPersistentField
  +public class PersistentFieldAutoProxyImpl extends PersistentFieldBase
   {
  -    private static final long serialVersionUID = 6148669985786992032L;
  -
  -    /** The actual field handler */
  -    private AbstractPersistentField wrapped;
  -    /** Whether we actually found a field handler, or it is still the default one */
  -    private boolean hasBeenDetermined = false;
  +    static final long serialVersionUID = 6286229945422476325L;
   
       /**
  -     * Creates a new auto handler object for the indicated field.
  -     * 
  -     * @param type      The type of the object containing the field
  -     * @param fieldName The name of the field
  +     * Define the number and ordering of the used {@link PersistentField}
  +     * implementaions. Override this field to add new classes or to change
  +     * setection order.
        */
  -    public PersistentFieldAutoProxyImpl(Class type, String fieldName)
  +    protected Class[] persistentFieldClasses = new Class[]{
  +        PersistentFieldDirectImpl.class
  +        , PersistentFieldIntrospectorImpl.class
  +        , PersistentFieldPrivilegedImpl.class
  +        , PersistentFieldDynaBeanImpl.class};
  +
  +    private PersistentField currentPF;
  +    private ExceptionWrapper latestException;
  +    int index = 0;
  +
  +    public PersistentFieldAutoProxyImpl(Class clazz, String fieldname)
       {
  -        super(type, fieldName);
  +        super(clazz, fieldname);
       }
   
  -    /**
  -     * Creates an instance of the given field handler type.
  -     * 
  -     * @param handlerType The field handler type
  -     * @return The handler instance
  -     * @throws MetadataException If the handler could not be found, or cannot handle the
field
  -     */
  -    private AbstractPersistentField getFieldImpl(Class handlerType) throws MetadataException
  +    private PersistentField getCurrent()
       {
  -        Class[]  types = { Class.class, String.class };
  -        Object[] args  = { rootObjectType, fieldName };
  -
  -        try
  -        {
  -            return (AbstractPersistentField)ClassHelper.newInstance(handlerType, types,
args);
  -        }
  -        catch (Exception ex)
  +        if (currentPF == null)
           {
  -            if (ex instanceof MetadataException)
  +            if(index >= persistentFieldClasses.length)
               {
  -                throw (MetadataException)ex;
  +                index = 0;
  +                currentPF = null;
  +                throw new AutoDetectException("Can't autodetect valid PersistentField implementation:
"
  +                        + latestException.message, latestException.exception);
               }
  -            else
  +            try
               {
  -                throw new MetadataException(ex);
  +                currentPF = createPersistentFieldForIndex();
  +            }
  +            catch (Exception e)
  +            {
  +                throw new AutoDetectException("Can't create instance for " + persistentFieldClasses[index],
e);
               }
           }
  +        return currentPF;
       }
   
  -    /**
  -     * Returns an instance of the field-direct handler.
  -     * 
  -     * @return The handler instance
  -     * @throws MetadataException If the handler could not be found, or cannot handle the
field
  -     */
  -    private AbstractPersistentField getDirectImpl() throws MetadataException
  +    private void handleException(String message, Exception e)
       {
  -        return getFieldImpl(PersistentFieldDirectAccessImpl.class);
  +        latestException = new ExceptionWrapper(message, e);
  +        currentPF = null;
  +        ++index;
       }
   
  -    /**
  -     * Returns an instance of the privileged field-direct handler.
  -     * 
  -     * @return The handler instance
  -     * @throws MetadataException If the handler could not be found, or cannot handle the
field
  -     */
  -    private AbstractPersistentField getPrivilegedDirectImpl() throws MetadataException
  -    {
  -        return getFieldImpl(PersistentFieldPrivilegedImpl.class);
  -    }
   
  -    /**
  -     * Returns an instance of the dyna bean handler.
  -     * 
  -     * @return The handler instance
  -     * @throws MetadataException If the handler could not be found, or cannot handle the
field
  -     */
  -    private AbstractPersistentField getDynaBeanImpl() throws MetadataException
  +    public Object get(Object anObject) throws MetadataException
       {
  -        return getFieldImpl(PersistentFieldDynaBeanAccessImpl.class);
  -    }
  -
  -    /**
  -     * Returns an instance of the bean-property handler.
  -     * 
  -     * @return The handler instance
  -     * @throws MetadataException If the handler could not be found, or cannot handle the
field
  -     */
  -    private AbstractPersistentField getPropertyImpl() throws MetadataException
  -    {
  -        return getFieldImpl(PersistentFieldIntrospectorImpl.class);
  -    }
  -
  -    /**
  -     * Returns the actual field handler. If none is determined yet, it first tries to
  -     * find one for the field.
  -     * 
  -     * @return The wrapped field handler
  -     * @throws MetadataException If no handler for the field could be found
  -     */
  -    private AbstractPersistentField getWrapped() throws MetadataException
  -    {
  -        // 1. direct field 
  -        // 2. bean
  -        // 3. dyna bean
  -        if (wrapped != null)
  +        try
           {
  -            return wrapped;
  +            return getCurrent().get(anObject);
           }
  -
  -        /*
  -         * this switches on a series of exceptions. Sadly, it is the only real way to detect
  -         * which one works. --Brian
  -         */
  -
  -        try
  +        catch (Exception e)
           {
  -            Field           field   = AbstractPersistentField.computeField(rootObjectType,
fieldName, isNestedField(), false);
  -            SecurityManager manager = System.getSecurityManager();
  -
  -            // ok we have a real field,
  -            // however, for non-public fields we have to check whether we're allowed to
access
  -            // it directly; this is guarded by the security manager, so we ask it
  -            try
  +            if(e instanceof AutoDetectException)
               {
  -                if ((manager != null) && !field.isAccessible())
  -                {
  -                    // this throws an exception if we're not allowed to the access the
declared members
  -                    manager.checkMemberAccess(field.getDeclaringClass(), Member.DECLARED);
  -                }
  -                // no security manager or we're allowed to access the field
  -                wrapped = getDirectImpl();
  +                throw (MetadataException) e;
               }
  -            catch (SecurityException ex)
  +            else
               {
  -                wrapped = getPrivilegedDirectImpl();
  +                handleException("Can't extract field value for field " + getName()
  +                        + " from object " + (anObject != null ? anObject.getClass() : null),
e);
  +                return get(anObject);
               }
  -            hasBeenDetermined = true;
  -            return wrapped;
  -        }
  -        catch (MetadataException ex)
  -        {
  -            // no direct field to use
           }
  +    }
   
  +    public void set(Object obj, Object value) throws MetadataException
  +    {
           try
           {
  -            if (PersistentFieldIntrospectorImpl.findPropertyDescriptor(rootObjectType,
fieldName) != null)
  -            {
  -                wrapped           = getPropertyImpl();
  -                hasBeenDetermined = true;
  -                return wrapped;
  -            }
  +            getCurrent().set(obj, value);
           }
  -        catch (MetadataException ex)
  +        catch (Exception e)
           {
  -            // no bean property either
  +            if(e instanceof AutoDetectException)
  +            {
  +                throw (MetadataException) e;
  +            }
  +            else
  +            {
  +                handleException("Can't set value for field " + getName()
  +                        + " to object " + (obj != null ? obj.getClass() : null), e);
  +                set(obj, value);
  +            }
           }
  +    }
   
  -        // Only option left is for it to be a dynabean which we'll use as the default
  -        // as we can check it only when actually doing something
  -        // of course, we can only use the dyna bean if the library is present
  +    public Class getType()
  +    {
           try
           {
  -            wrapped = getDynaBeanImpl();
  -            return wrapped;
  -        }
  -        catch (NoClassDefFoundError ex)
  -        {
  -            String message = "Could not use dyna beans (not in classpath), and no field
or property matches " + rootObjectType.getName() + "." + fieldName;
  -
  -            getLog().error(message);
  -            throw new MetadataException(message);
  +            return getCurrent().getType();
           }
  -    }
  -
  -    /**
  -     * Returns the wrapped field handler. This method is also able to check whether the
default
  -     * handler (dyna bean) can actually be used as it has an actual object whose field
shall be
  -     * accessed (which then must be a dyna bean).
  -     * 
  -     * @param targetObject The object whose field is accessed
  -     * @return The wrapped field handler
  -     * @throws MetadataException If no handler for the field could be found
  -     */
  -    private AbstractPersistentField getWrapped(Object targetObject) throws MetadataException
  -    {
  -        // ensure that we at least tried to find the handler
  -        AbstractPersistentField result = getWrapped();
  -
  -        if (!hasBeenDetermined)
  +        catch (Exception e)
           {
  -            // still the default handler, so this is the first time that we can check for
dyna beans
  -            if (targetObject instanceof DynaBean)
  +            if(e instanceof AutoDetectException)
               {
  -                // the default dyna bean is ok
  -                hasBeenDetermined = true;
  +                throw (MetadataException) e;
               }
               else
               {
  -                // no handler could be found -> error
  -                String message = "No field, property, or DynaProperty can be found to match
" + rootObjectType.getName() + "." + fieldName;
  -
  -                getLog().error(message);
  -                throw new MetadataException(message);
  +                handleException("Can't identify field type for field " + getName(), null);
  +                return getType();
               }
           }
  -        return result;
       }
   
  -    /* These are all the implementation methods delagating to the wrapped impl*/
  -
  -    /**
  -     * Set the field value for the given target object.
  -     * 
  -     * @param targetObject The object that contains the field to set
  -     * @param value        The value to set
  -     */
  -    public void doSet(Object targetObject, Object value)
  +    protected boolean makeAccessible()
       {
  -        getWrapped(targetObject).doSet(targetObject, value);
  +        return false;
       }
   
  -    /**
  -     * Gets the field value from the given target object.
  -     * 
  -     * @param targetObject The object that contains the field to set
  -     * @return The field's value
  -     */
  -    public Object doGet(Object targetObject)
  +    public boolean usesAccessorsAndMutators()
       {
  -        return getWrapped(targetObject).doGet(targetObject);
  +        return false;
       }
   
  -    public Class getDeclaringClass()
  +    private PersistentField createPersistentFieldForIndex() throws Exception
       {
  -        return getWrapped().getDeclaringClass();
  +        return newInstance(persistentFieldClasses[index]);
       }
   
  -    public boolean usesAccessorsAndMutators()
  +    private PersistentField newInstance(Class pfClass) throws Exception
       {
  -        return getWrapped().usesAccessorsAndMutators();
  +        Class[] types = new Class[]{Class.class, String.class};
  +        Object[] args = new Object[]{getDeclaringClass(), getName()};
  +        return (PersistentField) ClassHelper.newInstance(pfClass, types, args);
       }
   
  -    public String getName()
  +    private static class ExceptionWrapper implements Serializable
       {
  -        return getWrapped().getName();
  -    }
  +        private static final long serialVersionUID = 3979512977080088567L;
   
  -    public Class getType()
  -    {
  -        return getWrapped().getType();
  -    }
  +        Exception exception;
  +        String message;
   
  -    public boolean makeAccessible()
  -    {
  -        return getWrapped().makeAccessible();
  +        public ExceptionWrapper(String message, Exception exception)
  +        {
  +            this.message = message;
  +            this.exception = exception;
  +        }
       }
   
  -    public String toString()
  +    private static class AutoDetectException extends MetadataException
       {
  -        return getWrapped().toString();
  +        private static final long serialVersionUID = -48339524725993565L;
  +
  +        public AutoDetectException()
  +        {
  +            super();
  +        }
  +
  +        public AutoDetectException(Throwable t)
  +        {
  +            super(t);
  +        }
  +
  +        public AutoDetectException(String message)
  +        {
  +            super(message);
  +        }
  +
  +        public AutoDetectException(String message, Throwable t)
  +        {
  +            super(message, t);
  +        }
       }
   }
  
  
  
  1.4       +1 -1      db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldBase.java
  
  Index: PersistentFieldBase.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldBase.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  
  
  
  1.13      +121 -70   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.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- PersistentFieldIntrospectorImpl.java	14 Nov 2004 09:36:10 -0000	1.12
  +++ PersistentFieldIntrospectorImpl.java	18 Dec 2004 13:40:48 -0000	1.13
  @@ -20,58 +20,122 @@
   import java.beans.Introspector;
   import java.beans.PropertyDescriptor;
   import java.lang.reflect.Method;
  +import java.util.ArrayList;
  +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.
  + * No Reflection is needed. But for each attribute 'xxx' there must be
  + * 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 transient PropertyDescriptor propertyDescriptor;
  +    private Class type;
  +    private transient List propertyGraph;
   
       public PersistentFieldIntrospectorImpl(Class aClass, String aPropertyName)
       {
           super(aClass, aPropertyName);
       }
   
  -
  -    /*
  -    need to overwrite these three methods to avoid
  -    building of Field instances
  -    */
  -    public String getName()
  +    public Class getType()
       {
  -        return this.fieldName;
  +        if (type == null)
  +        {
  +            type = getPropertyDescriptor().getPropertyType();
  +        }
  +        return type;
       }
  -    public Class getType()
  +
  +    public void set(Object target, Object value) throws MetadataException
       {
  -        return getPropertyDescriptor().getPropertyType();
  +        if(target == null) return;
  +        List propertyDescriptors = getPropertyGraph();
  +        int size = propertyDescriptors.size() - 1;
  +        PropertyDescriptor pd;
  +        for (int i = 0; i < size; i++)
  +        {
  +            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);
       }
  -    public Class getDeclaringClass()
  +
  +    public Object get(Object target) throws MetadataException
       {
  -        return this.rootObjectType;
  +        List propertyDescriptors = getPropertyGraph();
  +        for (int i = 0; i < propertyDescriptors.size(); 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;
  +        Method m = pd.getReadMethod();
  +        if (m != null)
  +        {
  +            try
  +            {
  +                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());
  +        }
  +    }
   
  -    /**
  -     * Sets aValue for anObject
  -     */
  -    public void doSet(Object anObject, Object aValue) throws MetadataException
  +    private void setValueFor(PropertyDescriptor pd, Object target, Object value)
       {
  -        if(anObject == null) return;
  -        Method m = getPropertyDescriptor().getWriteMethod();
  -        Object[] args = {aValue};
  +        Method m = pd.getWriteMethod();
  +        Object[] args = {value};
           if (m != null)
           {
               try
  @@ -82,53 +146,51 @@
                    * we need to be able to set values to null. We can only set something
to null if
                    * the type is not a primitive (assignable from Object).
                    */
  -                if ((aValue != null) || !m.getParameterTypes()[0].isPrimitive())
  +                if ((value != null) || !m.getParameterTypes()[0].isPrimitive())
                   {
  -                    m.invoke(anObject, args);
  +                    m.invoke(ProxyHelper.getRealObject(target), args);
                   }
               }
               catch (Throwable e)
               {
  -                logProblem(anObject, aValue, e.getClass().getName());
  -                throw new MetadataException("Error invoking method:" + m.getName() + "
in object:" + anObject.getClass().getName(), 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
           {
  -            logProblem(anObject, aValue, "set: getWriteMethod returned null");
  -            throw new MetadataException(
  -                    "Can't get WriteMethod for property:" + getPropertyDescriptor().getName()
+ " in object:" + anObject.getClass().getName());
  +            throw new MetadataException("Can't get WriteMethod for property:" + pd.getName()
+ " in object:" + target.getClass().getName());
           }
       }
   
  -    /**
  -     * Get the Value from anObject
  -     */
  -    public Object doGet(Object anObject) throws MetadataException
  +    private List getPropertyGraph()
       {
  -        if(anObject == null) return null;
  -        Method m = getPropertyDescriptor().getReadMethod();
  -        Object[] args = null;
  +        if (propertyGraph == null)
  +        {
  +            propertyGraph = buildPropertyGraph();
  +        }
  +        return propertyGraph;
  +    }
   
  -        if (m != null)
  +    private List buildPropertyGraph()
  +    {
  +        List result = new ArrayList();
  +        String[] fields = StringUtils.split(getName(), PATH_TOKEN);
  +        PropertyDescriptor pd = null;
  +        for (int i = 0; i < fields.length; i++)
           {
  -            try
  +            String fieldName = fields[i];
  +            if (pd == null)
               {
  -                Object result = m.invoke(anObject, args);
  -                return result;
  +                pd = findPropertyDescriptor(getDeclaringClass(), fieldName);
               }
  -            catch (Throwable e)
  +            else
               {
  -                logProblem(anObject, null, e.getClass().getName());
  -                throw new MetadataException("Error invoking method:" + m.getName() + "
in object:" + anObject.getClass().getName(), e);
  +                pd = findPropertyDescriptor(pd.getPropertyType(), fieldName);
               }
  +            result.add(pd);
           }
  -        else
  -        {
  -            logProblem(anObject, null, "get: getReadMethod returned null");
  -            throw new MetadataException(
  -                    "Can't get ReadMethod for property:" + getPropertyDescriptor().getName()
+ " in object:" + anObject.getClass().getName());
  -        }
  +        return result;
       }
   
       /**
  @@ -170,34 +232,22 @@
   			 */
               throw new MetadataException("Can't find property " + aPropertyName + " in "
+ aClass.getName(), ex);
           }
  -
       }
   
       /**
        * Returns the PropertyDescriptor.
  +     *
        * @return java.beans.PropertyDescriptor
        */
       protected PropertyDescriptor getPropertyDescriptor()
       {
  -        if (propertyDescriptor == null)
  -        {
  -            setPropertyDescriptor(findPropertyDescriptor(getDeclaringClass(), getName()));
  -        }
  -        return propertyDescriptor;
  -    }
  -
  -    /**
  -     * Set PropertyDescriptor.
  -     * @param newPropertyDescriptor java.beans.PropertyDescriptor
  -     */
  -    protected void setPropertyDescriptor(PropertyDescriptor newPropertyDescriptor)
  -    {
  -        propertyDescriptor = newPropertyDescriptor;
  +        return (PropertyDescriptor) getPropertyGraph().get(getPropertyGraph().size() -
1);
       }
   
       /**
        * This implementation returns always 'false'.
  -     * @see AbstractPersistentField#makeAccessible()
  +     *
  +     * @see PersistentFieldBase#makeAccessible()
        */
       public boolean makeAccessible()
       {
  @@ -206,6 +256,7 @@
   
       /**
        * Always returns 'false'.
  +     *
        * @see PersistentField#usesAccessorsAndMutators
        */
       public boolean usesAccessorsAndMutators()
  @@ -216,13 +267,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.13      +29 -32    db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldPrivilegedImpl.java
  
  Index: PersistentFieldPrivilegedImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldPrivilegedImpl.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- PersistentFieldPrivilegedImpl.java	14 Nov 2004 09:36:10 -0000	1.12
  +++ PersistentFieldPrivilegedImpl.java	18 Dec 2004 13:40:48 -0000	1.13
  @@ -15,8 +15,6 @@
    * limitations under the License.
    */
   
  -import org.apache.ojb.broker.metadata.MetadataException;
  -
   import java.io.Serializable;
   import java.lang.reflect.Field;
   import java.security.AccessController;
  @@ -28,16 +26,15 @@
    * AccessController and do not suppress the java
    * language access check.
    *
  - * @see PersistentFieldDirectAccessImpl
  - *
    * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
    * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
    * @version $Id$
  + * @see PersistentFieldDirectImpl
    */
  -public class PersistentFieldPrivilegedImpl extends PersistentFieldDirectAccessImpl
  +public class PersistentFieldPrivilegedImpl extends PersistentFieldDirectImpl
   {
       private static final long serialVersionUID = -6110158693763128846L;
  -    
  +
       private SetAccessibleAction setAccessibleAction = new SetAccessibleAction();
       private UnsetAccessibleAction unsetAccessibleAction = new UnsetAccessibleAction();
       private static final int ACCESSIBLE_STATE_UNKOWN = 0;
  @@ -49,63 +46,60 @@
           super(type, fieldname);
       }
   
  -    /**
  -     *
  -     */
  -    public synchronized void doSet(Object obj, Object value) throws MetadataException
  +    protected Object getValueFrom(Field field, Object target)
       {
           int accessibleState = ACCESSIBLE_STATE_UNKOWN;
  -        Field fld = getField();
  -        if (!fld.isAccessible()) accessibleState = ACCESSIBLE_STATE_FALSE;
  +        Object result = null;
  +        if (!field.isAccessible()) accessibleState = ACCESSIBLE_STATE_FALSE;
           if (accessibleState == ACCESSIBLE_STATE_FALSE)
           {
               accessibleState = ACCESSIBLE_STATE_SET_TRUE;
  +            setAccessibleAction.current = field;
               AccessController.doPrivileged(setAccessibleAction);
           }
           try
           {
  -            super.doSet(obj, value);
  +            result = super.getValueFrom(field, target);
           }
           finally
           {
               if (accessibleState == ACCESSIBLE_STATE_SET_TRUE)
               {
  +                unsetAccessibleAction.current = field;
                   AccessController.doPrivileged(unsetAccessibleAction);
               }
           }
  +        return result;
       }
   
  -    /**
  -     *
  -     */
  -    public synchronized Object doGet(Object obj) throws MetadataException
  +    protected void setValueFor(Field field, Object target, Object value)
       {
           int accessibleState = ACCESSIBLE_STATE_UNKOWN;
  -        Field fld = getField();
  -        Object result = null;
  -        if (!fld.isAccessible()) accessibleState = ACCESSIBLE_STATE_FALSE;
  +        if (!field.isAccessible()) accessibleState = ACCESSIBLE_STATE_FALSE;
           if (accessibleState == ACCESSIBLE_STATE_FALSE)
           {
               accessibleState = ACCESSIBLE_STATE_SET_TRUE;
  +            setAccessibleAction.current = field;
               AccessController.doPrivileged(setAccessibleAction);
           }
           try
           {
  -            result = super.doGet(obj);
  +            super.setValueFor(field, target, value);
           }
           finally
           {
               if (accessibleState == ACCESSIBLE_STATE_SET_TRUE)
               {
  +                unsetAccessibleAction.current = field;
                   AccessController.doPrivileged(unsetAccessibleAction);
               }
           }
  -        return result;
       }
   
       /**
        * This implementation returns always 'false'.
  -     * @see AbstractPersistentField#makeAccessible()
  +     *
  +     * @see PersistentFieldBase#makeAccessible()
        */
       public boolean makeAccessible()
       {
  @@ -114,6 +108,7 @@
   
       /**
        * Always returns 'false'.
  +     *
        * @see PersistentField#usesAccessorsAndMutators
        */
       public boolean usesAccessorsAndMutators()
  @@ -124,24 +119,26 @@
       //************************************************************
       // inner class
       //************************************************************
  -    private class SetAccessibleAction implements PrivilegedAction, Serializable
  +    private static class SetAccessibleAction implements PrivilegedAction, Serializable
       {
  -		static final long serialVersionUID = 8152025069698028050L;        
  -        
  +        static final long serialVersionUID = 8152025069698028050L;
  +        transient Field current;
  +
           public Object run()
           {
  -            getField().setAccessible(true);
  +            current.setAccessible(true);
               return null;
           }
       }
   
  -    private class UnsetAccessibleAction implements PrivilegedAction, Serializable
  +    private static class UnsetAccessibleAction implements PrivilegedAction, Serializable
       {
  -		static final long serialVersionUID = -2284913657454430305L;        
  -        
  +        static final long serialVersionUID = -2284913657454430305L;
  +        transient Field current;
  +
           public Object run()
           {
  -            getField().setAccessible(false);
  +            current.setAccessible(false);
               return null;
           }
       }
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldDirectImpl.java
  
  Index: PersistentFieldDirectImpl.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.List;
  
  import org.apache.ojb.broker.core.proxy.ProxyHelper;
  import org.apache.ojb.broker.metadata.MetadataException;
  import org.apache.ojb.broker.util.ClassHelper;
  
  /**
   * This {@link PersistentField} implementation
   * is the high-speed version of the access strategies.
   * <br/>
   * It does not cooperate with an AccessController (like {@link PersistentFieldPrivilegedImpl}),
   * but accesses the fields directly. This implementation persistent
   * attributes don't need getters and setters
   * and don't have to be declared public or protected. Only the
   * metadata field names have to match the class fields.
   *
   * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
   * @version $Id: PersistentFieldDirectImpl.java,v 1.1 2004/12/18 13:40:48 arminw Exp $
   */
  public class PersistentFieldDirectImpl extends PersistentFieldBase
  {
      private static final long serialVersionUID = -5458024240998909205L;
  
      private transient boolean isInitialized;
      private transient List fieldsList;
      private transient Field field;
      private transient boolean nonNested;
  
      public PersistentFieldDirectImpl(Class type, String fieldname)
      {
          super(type, fieldname);
      }
  
      public Class getType()
      {
          return getField().getType();
      }
  
      /**
       * Returns the underlying field object.
       * If parameter <tt>setAccessible</tt> is true the
       * field access checking was suppressed.
       */
      protected Field getField()
      {
          // make sure class was initialized
          if (!isInitialized)
          {
              /*
              first we build a graph of fields for nested fields support,
              but for best performance on non-nested fields we also keep
              the latest field separate and set a 'is nested' flag.
              */
              fieldsList = getFieldGraph(makeAccessible());
              field = (Field) fieldsList.get(fieldsList.size() - 1);
              nonNested = fieldsList.size() == 1;
              isInitialized = true;
          }
          return field;
      }
  
      private List getFieldsList()
      {
          // make sure class was initialized
          if (!isInitialized) getField();
          return fieldsList;
      }
  
      protected boolean isNestedField()
      {
          return !nonNested;
      }
  
      /**
       * do not override this method, have a look at {@link #setValueFor(java.lang.reflect.Field,
Object, Object)}
       */
      public void set(Object target, Object value) throws MetadataException
      {
          // if target null, we have nothing to do
          if(target == null) return;
          Object current = target;
          if (isNestedField())
          {
              List fields = getFieldsList();
              int size = fields.size() - 1;
              Field field;
              for (int i = 0; i < size; i++)
              {
                  field = (Field) fields.get(i);
                  Object attribute = null;
                  try
                  {
                      attribute = getValueFrom(field, current);
                  }
                  catch (Exception e)
                  {
                      throw new MetadataException("Can't read field '" + field.getName() +
"' of type " + field.getType().getName(), e);
                  }
                  if (attribute != null || value != null)
                  {
                      // if the intermediary nested object is null, we have to create
                      // a new instance to set the value
                      if (attribute == null)
                      {
                          try
                          {
                              attribute = ClassHelper.newInstance(field.getType());
                          }
                          catch (Exception e)
                          {
                              throw new MetadataException("Can't create nested object of type
'"
                                      + field.getType() + "' for field '"
                                      + field.getName() + "'", e);
                          }
                      }
                      try
                      {
                          //field.set(current, attribute);
                          setValueFor(field, current, attribute);
                      }
                      //catch (IllegalAccessException e)
                      catch (Exception e)
                      {
                          throw new MetadataException("Can't set nested object of type '"
                                      + field.getType() + "' for field '"
                                      + field.getName() + "'", e);
                      }
                  }
                  else
                  {
                      return;
                  }
                  current = attribute;
              }
          }
          setValueFor(getField(), current, value);
      }
  
      /**
       * do not override this method, have a look at {@link #getValueFrom(java.lang.reflect.Field,
Object)}
       */
      public Object get(Object target) throws MetadataException
      {
          Object result = target;
          if (isNestedField())
          {
              List fields = getFieldsList();
              for (int i = 0; i < fields.size(); i++)
              {
                  if (result == null) break;
                  result = getValueFrom((Field) fields.get(i), result);
              }
          }
          else
          {
              result = result != null ? getValueFrom(getField(), result) : null;
          }
          return result;
      }
  
      protected Object getValueFrom(Field field, Object target)
      {
          try
          {
              return field.get(ProxyHelper.getRealObject(target));
          }
          catch (IllegalAccessException e)
          {
              throw new MetadataException(
                      "IllegalAccess error getting field:" +
                      (field != null ? field.getName() : null) + " in object:"
                      + target != null ? target.getClass().getName() : null, e);
          }
      }
  
      protected void setValueFor(Field field, Object target, final Object value)
      {
          try
          {
              /**
               * MBAIRD
               * we need to be able to set values to null. We can only set something to null
if
               * the type is not a primitive (assignable from Object).
               */
              // thanks to Tomasz Wysocki for this trick
              if ((value != null) || !field.getType().isPrimitive())
              {
                  // System.err.println("## t: " + target + "  v: " + value);
                  field.set(ProxyHelper.getRealObject(target), value);
              }
          }
          catch (NullPointerException ignored)
          {
              getLog().info("Target object '" + (target != null ? target.getClass().getName()
: null)
                      + "' for field '" + (field != null ? field.getName() : null)
                      + "' of type '" + (field != null ? field.getType().getName() : null)
                      + "' seems to be null. Can't write into null.", ignored);
          }
          catch (Exception e)
          {
              getLog().error("while set field: " + buildMessageString(target, value, field));
              throw new MetadataException("IllegalAccess error setting field '" +
                      (field != null ? field.getName() : null) + "' in object '" + target.getClass().getName()+"'",
e);
          }
      }
  
      /**
       * This implementation returns always 'true'.
       * @see PersistentFieldBase#makeAccessible()
       */
      protected boolean makeAccessible()
      {
          return true;
      }
  
      /**
       * Always returns 'false'.
       * @see PersistentField#usesAccessorsAndMutators
       */
      public boolean usesAccessorsAndMutators()
      {
          return false;
      }
  }
  
  
  
  1.7       +48 -109   db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldDynaBeanImpl.java
  
  
  
  
  1.79      +5 -13     db-ojb/src/test/org/apache/ojb/OJB.properties
  
  Index: OJB.properties
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/OJB.properties,v
  retrieving revision 1.78
  retrieving revision 1.79
  diff -u -r1.78 -r1.79
  --- OJB.properties	14 Nov 2004 09:41:31 -0000	1.78
  +++ OJB.properties	18 Dec 2004 13:40:49 -0000	1.79
  @@ -343,30 +343,22 @@
   #   suppress the java language access check (but is slow compared with direct access).
   # - PersistentFieldIntrospectorImpl
   #   uses JavaBeans compliant calls only to access persistent attributes.
  -#   No Reflection is needed. But for each attribute xxx there must be
  +#   No Reflection is needed. But for each attribute 'xxx' there must be
   #   public getXxx() and setXxx() methods.
   # - PersistentFieldDynaBeanAccessImpl
   #   implementation used to access a property from a
   #   org.apache.commons.beanutils.DynaBean.
  +#   (Note: DynaBean implementation does not support nested fields)
   # - PersistentFieldAutoProxyImpl
   #   for each field determines upon first access how to access this particular field
   #   (directly, as a bean, as a dyna bean) and then uses that strategy
   #
  -#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDirectAccessImpl
  +PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDirectImpl
   #PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldPrivilegedImpl
   #PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldIntrospectorImpl
  -#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDynaBeanAccessImpl
  +#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDynaBeanImpl
   #PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldAutoProxyImpl
   #
  -# Here are the new upcoming PersistentField implementations. These classes will replace
the
  -# 'old' ones on next release. They pass the test-suite, but should be tested by community
too.
  -# The new implementations are about 50 times faster in handling nested fields.
  -PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDirectAccessImplNew
  -#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldPrivilegedImplNew
  -#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldIntrospectorImplNew
  -#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldAutoProxyImpl
  -#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDynaBeanImplNew
  -#(DynaBean implementation does not support nested fields)
   #
   #----------------------------------------------------------------------------------------
   # Component Intercepting for Profiling and Tracing
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message