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 to...@apache.org on 2004/11/14 10:28:02 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/core/configuration HierarchyAwarePicoContainer.java PicoComponentContainer.java SpringComponentContainer.java AdaptedBeanFactory.java ComponentContainer.java AdaptedComponentAdapter.java ComponentContainerBase.java

tomdz       2004/11/14 01:28:02

  Modified:    src/java/org/apache/ojb/broker/core/configuration
                        PicoComponentContainer.java
                        SpringComponentContainer.java
                        AdaptedBeanFactory.java ComponentContainer.java
                        AdaptedComponentAdapter.java
                        ComponentContainerBase.java
  Added:       src/java/org/apache/ojb/broker/core/configuration
                        HierarchyAwarePicoContainer.java
  Log:
  Bug fixes
  
  Revision  Changes    Path
  1.3       +65 -12    db-ojb/src/java/org/apache/ojb/broker/core/configuration/PicoComponentContainer.java
  
  Index: PicoComponentContainer.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/configuration/PicoComponentContainer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PicoComponentContainer.java	5 Nov 2004 19:43:22 -0000	1.2
  +++ PicoComponentContainer.java	14 Nov 2004 09:28:02 -0000	1.3
  @@ -20,7 +20,6 @@
   import org.picocontainer.ComponentAdapter;
   import org.picocontainer.MutablePicoContainer;
   import org.picocontainer.PicoException;
  -import org.picocontainer.defaults.DefaultPicoContainer;
   
   /**
    * A PicoContainer {@link org.apache.ojb.broker.core.configuration.ComponentContainer}
  @@ -39,7 +38,7 @@
       public PicoComponentContainer()
       {
           super();
  -        _pico = new DefaultPicoContainer(new AdaptedComponentAdapterFactory());
  +        _pico = new HierarchyAwarePicoContainer(new AdaptedComponentAdapterFactory());
           _pico.registerComponentInstance(this);
       }
       
  @@ -51,11 +50,20 @@
       private PicoComponentContainer(PicoComponentContainer parent)
       {
           super(parent);
  -        _pico = new DefaultPicoContainer(new AdaptedComponentAdapterFactory(), parent._pico);
  +        _pico = new HierarchyAwarePicoContainer(new AdaptedComponentAdapterFactory(), parent._pico);
           _pico.registerComponentInstance(this);
       }
   
       /* (non-Javadoc)
  +     * @see java.lang.Object#finalize()
  +     */
  +    protected void finalize() throws Throwable
  +    {
  +        _pico.dispose();
  +        super.finalize();
  +    }
  +
  +    /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#getChildFactory()
        */
       public ComponentContainer createChildContainer()
  @@ -64,40 +72,75 @@
       }
   
       /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#hasImplementationClass(java.lang.Class)
  +     */
  +    public boolean hasImplementationClass(Class type)
  +    {
  +        ComponentAdapter adapter = _pico.getComponentAdapter(type);
  +
  +        if (adapter == null)
  +        {
  +            return getParentContainer() != null ? getParentContainer().hasImplementationClass(type) : false;
  +        }
  +        else
  +        {
  +            return true;
  +        }
  +    }
  +
  +    /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#getImplementationClass(java.lang.Class)
        */
       public Class getImplementationClass(Class type)
       {
           ComponentAdapter adapter = _pico.getComponentAdapter(type);
   
  -        return adapter == null ? null : adapter.getComponentImplementation();
  +        if (adapter == null)
  +        {
  +            return getParentContainer() != null ? getParentContainer().getImplementationClass(type) : null;
  +        }
  +        else
  +        {
  +            return adapter.getComponentImplementation();
  +        }
  +    }
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#isSingletonImplementationClass(java.lang.Class)
  +     */
  +    public boolean isSingletonImplementationClass(Class type)
  +    {
  +        AdaptedComponentAdapter adapter = (AdaptedComponentAdapter)_pico.getComponentAdapter(type);
  +
  +        return adapter == null ? false : adapter.isCaching();
       }
   
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setImplementationClass(java.lang.Class, java.lang.Class, boolean)
        */
  -    public void setImplementationClass(Class type, Class implClass, boolean isSingleton)
  +    public synchronized void setImplementationClass(Class type, Class implClass, boolean isSingleton)
       {
           _pico.unregisterComponent(type);
   
  -        AdaptedComponentAdapter adapter = (AdaptedComponentAdapter)_pico.registerComponentImplementation(type, implClass);
  +        AdaptedComponentAdapter newAdapter = (AdaptedComponentAdapter)_pico.registerComponentImplementation(type, implClass);
   
  -        adapter.setCaching(isSingleton);
  +        newAdapter.setCaching(isSingleton);
       }
   
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setSingletonInstance(java.lang.Class, java.lang.Object)
        */
  -    public void setSingletonInstance(Class type, Object obj)
  +    public synchronized void setSingletonInstance(Class type, Object obj)
       {
           _pico.unregisterComponent(type);
   
           // we're not using PicoContainer#registerComponentInstance because that
           // does not use our adapter but instead a InstanceComponentAdapter
  -        AdaptedComponentAdapter adapter = (AdaptedComponentAdapter)_pico.registerComponentImplementation(type, obj.getClass());
   
  -        adapter.setCaching(true);
  -        adapter.setComponentInstance(obj);
  +        AdaptedComponentAdapter newAdapter = (AdaptedComponentAdapter)_pico.registerComponentImplementation(type, obj.getClass());
  +
  +        newAdapter.setCaching(true);
  +        newAdapter.setComponentInstance(obj);
       }
   
       /* (non-Javadoc)
  @@ -143,12 +186,22 @@
       }
   
       /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#hasSingletonInstance(java.lang.Class)
  +     */
  +    public boolean hasSingletonInstance(Class type)
  +    {
  +        AdaptedComponentAdapter adapter = (AdaptedComponentAdapter)_pico.getComponentAdapter(type);
  +
  +        return (adapter != null) && adapter.isCaching() && (adapter.getComponentInstanceInternal() != null);
  +    }
  +
  +    /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#isSingletonInstance(java.lang.Class, java.lang.Object)
        */
       public boolean isSingletonInstance(Class type, Object obj)
       {
           AdaptedComponentAdapter adapter = (AdaptedComponentAdapter)_pico.getComponentAdapter(type);
   
  -        return adapter.isCaching() && adapter.isInstance(obj);
  +        return (adapter != null) && adapter.isCaching() && (obj == adapter.getComponentInstanceInternal());
       }
   }
  
  
  
  1.3       +72 -16    db-ojb/src/java/org/apache/ojb/broker/core/configuration/SpringComponentContainer.java
  
  Index: SpringComponentContainer.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/configuration/SpringComponentContainer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SpringComponentContainer.java	5 Nov 2004 19:43:22 -0000	1.2
  +++ SpringComponentContainer.java	14 Nov 2004 09:28:02 -0000	1.3
  @@ -51,7 +51,7 @@
        * the this container will create a bean factory of its own that is a child of the given
        * bean factory. 
        * 
  -     * @param beanFactory The bean factory to use
  +     * @param beanFactory The parent bean factory
        */
       public SpringComponentContainer(BeanFactory beanFactory)
       {
  @@ -80,36 +80,68 @@
       }
   
       /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#hasImplementationClass(java.lang.Class)
  +     */
  +    public boolean hasImplementationClass(Class type)
  +    {
  +        try
  +        {
  +            return _beanFactory.getBeanDefinition(type.getName()) != null;
  +        }
  +        catch (NoSuchBeanDefinitionException ex)
  +        {
  +            return false;
  +        }
  +    }
  +
  +    /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#getImplementationClass(java.lang.Class)
        */
       public Class getImplementationClass(Class type)
       {
  +        BeanDefinition beanDef = null;
  +
  +        try
  +        {
  +            beanDef = _beanFactory.getBeanDefinition(type.getName());
  +        }
  +        catch (NoSuchBeanDefinitionException ex)
  +        {}
  +        if (beanDef == null)
  +        {
  +            return getParentContainer() != null ? getParentContainer().getImplementationClass(type) : null;
  +        }
  +        else
  +        {
  +            return beanDef.getBeanClass();
  +        }
  +    }
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#isSingletonImplementationClass(java.lang.Class)
  +     */
  +    public boolean isSingletonImplementationClass(Class type)
  +    {
           try
           {
               BeanDefinition beanDef = _beanFactory.getBeanDefinition(type.getName());
   
  -            if (beanDef == null)
  -            {
  -                return getParentContainer() != null ? getParentContainer().getImplementationClass(type) : null;
  -            }
  -            else
  -            {
  -                return beanDef.getBeanClass();
  -            }
  +            return beanDef != null ? beanDef.isSingleton() : false;
           }
           catch (NoSuchBeanDefinitionException ex)
           {
  -            return null;
  +            return false;
           }
       }
   
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setImplementationClass(java.lang.Class, java.lang.Class, boolean)
        */
  -    public void setImplementationClass(Class type, Class implClass, boolean isSingleton)
  +    public synchronized void setImplementationClass(Class type, Class implClass, boolean isSingleton)
       {
  -        BeanDefinition     curBeanDef = null;
  -        RootBeanDefinition newBeanDef = null;
  +        BeanDefinition     curBeanDef   = null;
  +        RootBeanDefinition newBeanDef   = null;
  +        Class              oldImplClass = null;
   
           try
           {
  @@ -118,9 +150,18 @@
           catch (NoSuchBeanDefinitionException ex)
           {}
   
  -        if ((curBeanDef != null) && (curBeanDef instanceof RootBeanDefinition))
  +        if (curBeanDef != null)
           {
  -            newBeanDef = (RootBeanDefinition)curBeanDef;
  +            oldImplClass = curBeanDef.getBeanClass();
  +            if (curBeanDef instanceof RootBeanDefinition)
  +            {
  +                newBeanDef = (RootBeanDefinition)curBeanDef;
  +                if (newBeanDef.isSingleton() && (oldImplClass != implClass))
  +                {
  +                    // removing a singleton of the old class if present
  +                    _beanFactory.registerSingleton(type.getName(), null);
  +                }
  +            }
           }
           else
           {
  @@ -141,7 +182,7 @@
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setSingletonInstance(java.lang.Class, java.lang.Object)
        */
  -    public void setSingletonInstance(Class type, Object obj)
  +    public synchronized void setSingletonInstance(Class type, Object obj)
       {
           _beanFactory.registerSingleton(type.getName(), obj);
           setImplementationClass(type, obj.getClass());
  @@ -193,6 +234,21 @@
               }
           }
           return obj;
  +    }
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#hasSingletonInstance(java.lang.Class)
  +     */
  +    public boolean hasSingletonInstance(Class type)
  +    {
  +        if (_beanFactory.isSingleton(type.getName()))
  +        {
  +            return _beanFactory.containsBean(type.getName());
  +        }
  +        else
  +        {
  +            return false;
  +        }
       }
   
       /* (non-Javadoc)
  
  
  
  1.2       +4 -2      db-ojb/src/java/org/apache/ojb/broker/core/configuration/AdaptedBeanFactory.java
  
  Index: AdaptedBeanFactory.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/configuration/AdaptedBeanFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AdaptedBeanFactory.java	27 Oct 2004 20:34:26 -0000	1.1
  +++ AdaptedBeanFactory.java	14 Nov 2004 09:28:02 -0000	1.2
  @@ -27,7 +27,6 @@
    */
   public class AdaptedBeanFactory extends DefaultListableBeanFactory
   {
  -
       /**
        * Creates a new bean factory.
        */
  @@ -53,6 +52,9 @@
       public void registerSingleton(String beanName, Object singletonObject) throws BeanDefinitionStoreException
       {
           removeSingleton(beanName);
  -        super.registerSingleton(beanName, singletonObject);
  +        if (singletonObject != null)
  +        {
  +            super.registerSingleton(beanName, singletonObject);
  +        }
       }
   }
  
  
  
  1.3       +78 -14    db-ojb/src/java/org/apache/ojb/broker/core/configuration/ComponentContainer.java
  
  Index: ComponentContainer.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/configuration/ComponentContainer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ComponentContainer.java	5 Nov 2004 19:43:22 -0000	1.2
  +++ ComponentContainer.java	14 Nov 2004 09:28:02 -0000	1.3
  @@ -28,7 +28,7 @@
    */
   public interface ComponentContainer
   {
  -    // TODO: In the 1.0 version, there exists the possibility to define an interceptor
  +    // TODO: In the 1.0 OJB version, there exists the possibility to define an interceptor
       //       (property InterceptorClass) which acts as a wrapper around components
       //       This could be easily provided by the ComponentContainer, too
   
  @@ -40,28 +40,38 @@
       public ComponentContainer createChildContainer();
   
       /**
  -     * Sets the parent container.
  +     * Returns the parent container if any.
        * 
  -     * @param parent The parent container
  +     * @return The parent container
        */
  -    public void setParentContainer(ComponentContainer parent);
  +    public ComponentContainer getParentContainer();
   
       /**
  -     * Returns the parent container if any.
  +     * Determines whether an implementation class for the given type is
  +     * registered.
        * 
  -     * @return The parent container
  +     * @param type The type to check
  +     * @return The registered class
        */
  -    public ComponentContainer getParentContainer();
  +    public boolean hasImplementationClass(Class type);
   
       /**
        * Returns the registered implementation class for the given type.
        * 
  -     * @param type The type to register the implementation for
  +     * @param type The type to get the implementation class for
        * @return The registered class
        */
       public Class getImplementationClass(Class type);
   
       /**
  +     * Determines whether the implementation class for the given type generates singletons.
  +     * 
  +     * @param type The class
  +     * @return <code>true</code> if a singleton will be or has been generated for the type
  +     */
  +    public boolean isSingletonImplementationClass(Class type);
  +
  +    /**
        * Registers an implementation class for the given type.
        * 
        * @param type      The type to register the implementation for
  @@ -80,6 +90,26 @@
       public void setImplementationClass(Class type, Class implClass, boolean isSingleton);
   
       /**
  +     * Registers an implementation class for the given type if none is already defined
  +     * in this or a parent container.
  +     * 
  +     * @param type      The type to register the implementation for
  +     * @param implClass The implementation class to register
  +     */
  +    public void ensureImplementationClass(Class type, Class implClass);
  +
  +    /**
  +     * Registers an implementation class for the given type if none is already defined
  +     * in this or a parent container.
  +     * 
  +     * @param type        The type to register the implementation for
  +     * @param implClass   The implementation class to register
  +     * @param isSingleton Whether exactly one instance of this type
  +     *                    shall be created
  +     */
  +    public void ensureImplementationClass(Class type, Class implClass, boolean isSingleton);
  +
  +    /**
        * Registers the given object as the singleton instance for the given type. Note that
        * singleton instances are assumed to be already configured.
        * 
  @@ -89,6 +119,15 @@
       public void setSingletonInstance(Class type, Object obj);
   
       /**
  +     * Registers the given object as the singleton instance for all its types with the exception
  +     * of <code>java.lang.Object</code>, <code>java.lang.Cloneable</code> and
  +     * <code>java.io.Serializable</code>.
  +     * 
  +     * @param obj The object
  +     */
  +    public void setSingletonInstance(Object obj);
  +
  +    /**
        * Return a new instance of the implementation for the given class.
        * If a singleton instance is registered for this type, then this instance
        * is returned. The instance will be configured except if it is a singleton
  @@ -110,9 +149,18 @@
       public Object getInstance(Class type) throws ObjectCreationException, ObjectConfigurationException;
   
       /**
  +     * Determines whether there exists a singleton instance of the given class.
  +     * 
  +     * @param type The class
  +     * @return <code>true</code> if a singleton instance exists
  +     */
  +    public boolean hasSingletonInstance(Class type);
  +
  +    /**
        * Return the singleton instance of the implementation for the given class.
  -     * If no singleton is yet set for this class, then a new object will be created
  -     * using {@link #getInstance(Class)} and set as the singleton.
  +     * If no singleton is yet set for this class at this or a parent container, then a
  +     * new object will be created in this container using {@link #getInstance(Class)}
  +     * and set as the singleton.
        * 
        * @param type The class
        * @return The instance
  @@ -125,7 +173,7 @@
        * Determines whether the given object is the singleton instance of the given class.
        * 
        * @param type The class
  -     * @param obj   The object
  +     * @param obj  The object
        * @return <code>true</code> if the object is the singleton instance
        */
       public boolean isSingletonInstance(Class type, Object obj);
  @@ -133,6 +181,14 @@
       /**
        * Returns the given property.
        * 
  +     * @param qualifiedName The fully qualified property name, i.e. "type.name"
  +     * @return The value or <code>null</code> if there is no such property
  +     */
  +    public Object getProperty(String qualifiedName);
  +
  +    /**
  +     * Returns the given property.
  +     * 
        * @param type The type that the property is set for
        * @param name  The property name
        * @return The value or <code>null</code> if there is no such property
  @@ -140,14 +196,22 @@
       public Object getProperty(Class type, String name);
   
       /**
  -     * Returns all properties specifically defined for the specified type. Note that the "class"
  -     * property if set will be not be part of the hashmap because it is directly used with the
  -     * {@link #setImplementationClass(Class, Class)} method.
  +     * Returns all properties specifically defined for the specified type.
        * 
        * @param type The type
        * @return The properties or <code>null</code> if no properties are defined for this type
        */
       public HashMap getProperties(Class type);
  +
  +    /**
  +     * Sets the given property.
  +     * 
  +     * @param qualifiedName The fully qualified property name, i.e. "type.name"
  +     * @param value         The value; use <code>null</code> to unset the property
  +     * @param force         If <code>true</code> then an existing property will be overriden, otherwise
  +     *                      it will only be set if not yet defined
  +     */
  +    public void setProperty(String qualifiedName, Object value, boolean force); 
   
       /**
        * Sets the given property.
  
  
  
  1.2       +4 -5      db-ojb/src/java/org/apache/ojb/broker/core/configuration/AdaptedComponentAdapter.java
  
  Index: AdaptedComponentAdapter.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/configuration/AdaptedComponentAdapter.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AdaptedComponentAdapter.java	5 Nov 2004 19:43:22 -0000	1.1
  +++ AdaptedComponentAdapter.java	14 Nov 2004 09:28:02 -0000	1.2
  @@ -80,14 +80,13 @@
       }
   
       /**
  -     * Determines whether this adapter contains the given object.
  +     * Returns the instance currently saved in this adapter.
        * 
  -     * @param obj The object
  -     * @return <code>true</code> if it is the object currently contained in this adapter
  +     * @return obj The object
        */
  -    public boolean isInstance(Object obj)
  +    public Object getComponentInstanceInternal()
       {
  -        return _reference.get() == obj;
  +        return _reference.get();
       }
   
       /* (non-Javadoc)
  
  
  
  1.3       +150 -65   db-ojb/src/java/org/apache/ojb/broker/core/configuration/ComponentContainerBase.java
  
  Index: ComponentContainerBase.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/configuration/ComponentContainerBase.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ComponentContainerBase.java	5 Nov 2004 19:43:22 -0000	1.2
  +++ ComponentContainerBase.java	14 Nov 2004 09:28:02 -0000	1.3
  @@ -15,6 +15,7 @@
    * limitations under the License.
    */
   
  +import java.io.Serializable;
   import java.util.ArrayList;
   import java.util.HashMap;
   import java.util.Iterator;
  @@ -23,6 +24,7 @@
   import java.util.Map.Entry;
   
   import org.apache.commons.beanutils.BeanUtils;
  +import org.apache.ojb.broker.util.ClassHelper;
   
   /**
    * Convenience base class for component containers.
  @@ -55,14 +57,6 @@
       }
   
       /* (non-Javadoc)
  -     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setParentFactory(org.apache.ojb.broker.core.configuration.ComponentContainer)
  -     */
  -    public void setParentContainer(ComponentContainer parent)
  -    {
  -        _parentContainer = parent;
  -    }
  -
  -    /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#getParentFactory()
        */
       public ComponentContainer getParentContainer()
  @@ -73,12 +67,54 @@
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setImplementationClass(java.lang.Class, java.lang.Class)
        */
  -    public void setImplementationClass(Class type, Class implClass)
  +    public synchronized void setImplementationClass(Class type, Class implClass)
       {
           setImplementationClass(type, implClass, false);
       }
   
       /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#ensureImplementationClass(java.lang.Class, java.lang.Class, boolean)
  +     */
  +    public synchronized void ensureImplementationClass(Class type, Class implClass, boolean isSingleton)
  +    {
  +        if (!hasImplementationClass(type))
  +        {
  +            setImplementationClass(type, implClass, isSingleton);
  +        }
  +    }
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#ensureImplementationClass(java.lang.Class, java.lang.Class)
  +     */
  +    public synchronized void ensureImplementationClass(Class type, Class implClass)
  +    {
  +        if (!hasImplementationClass(type))
  +        {
  +            setImplementationClass(type, implClass);
  +        }
  +    }
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setSingletonInstance(java.lang.Object)
  +     */
  +    public synchronized void setSingletonInstance(Object obj)
  +    {
  +        ArrayList baseTypes = getAllTypes(obj);
  +
  +        for (Iterator it = baseTypes.iterator(); it.hasNext();)
  +        {
  +            Class baseType = (Class)it.next();
  +
  +            if (!Object.class.getName().equals(baseType.getName()) &&
  +                !Cloneable.class.getName().equals(baseType.getName()) &&
  +                !Serializable.class.getName().equals(baseType.getName()))
  +            {
  +                setSingletonInstance(baseType, obj);
  +            }
  +        }
  +    }
  +
  +    /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#getSingletonInstance(java.lang.Class)
        */
       public Object getSingletonInstance(Class type) throws ObjectCreationException, ObjectConfigurationException
  @@ -91,7 +127,33 @@
           }
           return obj;
       }
  -    
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#getProperty(java.lang.String)
  +     */
  +    public Object getProperty(String qualifiedName)
  +    {
  +        int dotPos = qualifiedName.lastIndexOf('.');
  +
  +        if (dotPos <= 0)
  +        {
  +            throw new IllegalArgumentException("Illegal unqualified property "+qualifiedName);
  +        }
  +
  +        Class type = null;
  +
  +        try
  +        {
  +            type = getClassByName(qualifiedName.substring(0, dotPos));
  +        }
  +        catch (ClassNotFoundException ex)
  +        {
  +            throw new IllegalArgumentException("Property "+qualifiedName+" specifies unknown class "+qualifiedName.substring(0, dotPos));
  +        }
  +
  +        return getProperty(type, qualifiedName.substring(dotPos + 1));
  +    }
  +
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#getProperty(java.lang.Class, java.lang.String)
        */
  @@ -120,7 +182,14 @@
       {
           HashMap props = getProperties(type);
   
  -        return props == null ? null : props.get(name);
  +        if ((props != null) && props.containsKey(name))
  +        {
  +            return props.get(name);
  +        }
  +        else
  +        {
  +            return getParentContainer() != null ? getParentContainer().getProperty(type, name) : null;
  +        }
       }
   
       /* (non-Javadoc)
  @@ -132,13 +201,63 @@
           {
               throw new NullPointerException("No class specified");
           }
  -        return (HashMap)_propsPerClass.get(type);
  +
  +        Class   implClass   = getImplementationClass(type);
  +        HashMap props       = (HashMap)_propsPerClass.get(type);
  +        HashMap parentProps = null;
  +
  +        if (implClass != null)
  +        {
  +            if (props == null)
  +            {
  +                props = new HashMap();
  +            }
  +            props.put("class", implClass.getName());
  +        }
  +        if (getParentContainer() != null)
  +        {
  +            parentProps = getParentContainer().getProperties(type);
  +        }
  +        if ((props != null) && (parentProps != null))
  +        {
  +            parentProps.putAll(props);
  +            return parentProps;
  +        }
  +        else
  +        {
  +            return props != null ? props : parentProps;
  +        }
  +    }
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setProperty(java.lang.String, java.lang.Object, boolean)
  +     */
  +    public synchronized void setProperty(String qualifiedName, Object value, boolean force)
  +    {
  +        int dotPos = qualifiedName.lastIndexOf('.');
  +
  +        if (dotPos <= 0)
  +        {
  +            throw new IllegalArgumentException("Illegal unqualified property "+qualifiedName);
  +        }
  +
  +        try
  +        {
  +            setProperty(getClassByName(qualifiedName.substring(0, dotPos)),
  +                        qualifiedName.substring(dotPos + 1),
  +                        value,
  +                        force);
  +        }
  +        catch (ClassNotFoundException ex)
  +        {
  +            throw new IllegalArgumentException("Property "+qualifiedName+" specifies unknown class "+qualifiedName.substring(0, dotPos));
  +        }
       }
   
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setProperty(java.lang.Class, java.lang.String, java.lang.Object, boolean)
        */
  -    public void setProperty(Class type, String name, Object value, boolean force)
  +    public synchronized void setProperty(Class type, String name, Object value, boolean force)
       {
           // "class" is a special property that corresponds to registerImplementation
           if ("class".equals(name))
  @@ -180,7 +299,7 @@
        */
       protected void setBeanProperty(Class type, String name, Object value, boolean force)
       {
  -        HashMap props = getProperties(type);
  +        HashMap props = (HashMap)_propsPerClass.get(type);
   
           if (props == null)
           {
  @@ -203,29 +322,19 @@
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#setProperties(java.util.Properties, boolean)
        */
  -    public void setProperties(Properties props, boolean force) throws ContainerInitializationException
  +    public synchronized void setProperties(Properties props, boolean force) throws ContainerInitializationException
       {
           for (Iterator entryIt = props.entrySet().iterator(); entryIt.hasNext();)
           {
  -            Entry  entry  = (Entry)entryIt.next();
  -            String name   = (String)entry.getKey();
  -            int    dotPos = name.lastIndexOf('.');
  -
  -            if (dotPos <= 0)
  -            {
  -                throw new ContainerInitializationException("Illegal unqualified property "+name);
  -            }
  +            Entry entry = (Entry)entryIt.next();
   
               try
               {
  -                setProperty(getClassByName(name.substring(0, dotPos)),
  -                            name.substring(dotPos + 1),
  -                            entry.getValue(),
  -                            force);
  +                setProperty((String)entry.getKey(), entry.getValue(), force);
               }
  -            catch (Exception ex)
  +            catch (IllegalArgumentException ex)
               {
  -                throw new ContainerInitializationException(ex);
  +                throw new ContainerInitializationException(ex.getMessage());
               }
           }
       }
  @@ -233,26 +342,23 @@
       /* (non-Javadoc)
        * @see org.apache.ojb.broker.core.configuration.ComponentContainer#configure(java.lang.Object)
        */
  -    public void configure(Object obj) throws ObjectConfigurationException
  +    public synchronized void configure(Object obj) throws ObjectConfigurationException
       {
  -        ArrayList containers = flattenContainerHierarchy();
  -        
           try
           {
               for (Iterator typeIt = getAllTypes(obj).iterator(); typeIt.hasNext();)
               {
  -                Class clazz = (Class)typeIt.next();
  -
  -                for (Iterator containerIt = containers.iterator(); containerIt.hasNext();)
  +                Class   clazz = (Class)typeIt.next();
  +                HashMap props = getProperties(clazz);
  +                
  +                if (props != null)
                   {
  -                    HashMap props = ((ComponentContainer)containerIt.next()).getProperties(clazz);
  -                    
  -                    if (props != null)
  +                    for (Iterator propIt = props.entrySet().iterator(); propIt.hasNext();)
                       {
  -                        for (Iterator propIt = props.entrySet().iterator(); propIt.hasNext();)
  +                        Map.Entry entry = (Map.Entry)propIt.next();
  +
  +                        if (!"class".equals(entry.getKey()))
                           {
  -                            Map.Entry entry = (Map.Entry)propIt.next();
  -        
                               BeanUtils.setProperty(obj, (String)entry.getKey(), entry.getValue());
                           }
                       }
  @@ -274,33 +380,12 @@
        */
       protected Class getClassByName(String name) throws ClassNotFoundException
       {
  -        // TODO: Use OJB's ClassHelper once this is part of OJB
  -        return Class.forName(name);
  -    }
  -    
  -    /**
  -     * Returns a list of this and all its parent factories, starting with the most base
  -     * factory.
  -     * 
  -     * @return The list of factories
  -     */
  -    protected ArrayList flattenContainerHierarchy()
  -    {
  -        ArrayList          containers = new ArrayList();
  -        ComponentContainer parent     = _parentContainer;
  -
  -        containers.add(this);
  -        while (parent != null)
  -        {
  -            containers.add(0, parent);
  -            parent = parent.getParentContainer();
  -        }
  -        return containers;
  +        return ClassHelper.getClass(name);
       }
   
       /**
  -     * Returns all (base) types of the given object. If the object is a class, then
  -     * itself and all its super types are used, otherwise the types of the object.
  +     * Returns all (base) types of the given object i.e. the base classes
  +     * (if possible) and all base interfaces.
        * 
        * @param obj The object or class
        * @return A list of all types of the object/class
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/broker/core/configuration/HierarchyAwarePicoContainer.java
  
  Index: HierarchyAwarePicoContainer.java
  ===================================================================
  package org.apache.ojb.broker.core.configuration;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  
  import org.picocontainer.ComponentAdapter;
  import org.picocontainer.MutablePicoContainer;
  import org.picocontainer.Parameter;
  import org.picocontainer.PicoContainer;
  import org.picocontainer.PicoException;
  import org.picocontainer.PicoRegistrationException;
  import org.picocontainer.PicoVerificationException;
  import org.picocontainer.PicoVisitor;
  import org.picocontainer.alternatives.ImmutablePicoContainer;
  import org.picocontainer.defaults.AmbiguousComponentResolutionException;
  import org.picocontainer.defaults.CachingComponentAdapter;
  import org.picocontainer.defaults.CachingComponentAdapterFactory;
  import org.picocontainer.defaults.ComponentAdapterFactory;
  import org.picocontainer.defaults.DefaultComponentAdapterFactory;
  import org.picocontainer.defaults.DefaultPicoContainer;
  import org.picocontainer.defaults.DuplicateComponentKeyRegistrationException;
  import org.picocontainer.defaults.InstanceComponentAdapter;
  import org.picocontainer.defaults.LifecycleVisitor;
  import org.picocontainer.defaults.VerifyingVisitor;
  
  /**
   * A nearly identical copy of the <code>DefaultPicoContainer</code> but it creates
   * instances where the adapter comes from a parent container, in its own context, not
   * in the one of the parent container. This class does not inherit from
   * <code>DefaultPicoContainer</code> because it is not inheritance-friendly (no direct
   * access to the list of adapters).
   */
  public class HierarchyAwarePicoContainer implements MutablePicoContainer, Serializable
  {
      private Map componentKeyToAdapterCache = new HashMap();
      private ComponentAdapterFactory componentAdapterFactory;
      private PicoContainer parent;
      private List componentAdapters = new ArrayList();
  
      // Keeps track of instantiation order.
      private List orderedComponentAdapters = new ArrayList();
  
      private boolean started = false;
      private boolean disposed = false;
      private HashSet children = new HashSet();
  
      /**
       * Creates a new container with a custom ComponentAdapterFactory and a parent container.
       * <p/>
       * <em>
       * Important note about caching: If you intend the components to be cached, you should pass
       * in a factory that creates {@link CachingComponentAdapter} instances, such as for example
       * {@link CachingComponentAdapterFactory}. CachingComponentAdapterFactory can delegate to
       * other ComponentAdapterFactories.
       * </em>
       *
       * @param componentAdapterFactory the factory to use for creation of ComponentAdapters.
       * @param parent                  the parent container (used for component dependency lookups).
       */
      public HierarchyAwarePicoContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent)
      {
          if(componentAdapterFactory == null) throw new NullPointerException("componentAdapterFactory");
          this.componentAdapterFactory = componentAdapterFactory;
          this.parent = parent == null ? null : new ImmutablePicoContainer(parent);
      }
  
      /**
       * Creates a new container with a (caching) {@link DefaultComponentAdapterFactory}
       * and a parent container.
       */
      public HierarchyAwarePicoContainer(PicoContainer parent)
      {
          this(new DefaultComponentAdapterFactory(), parent);
      }
  
      /**
       * Creates a new container with a custom ComponentAdapterFactory and no parent container.
       *
       * @param componentAdapterFactory the ComponentAdapterFactory to use.
       */
      public HierarchyAwarePicoContainer(ComponentAdapterFactory componentAdapterFactory)
      {
          this(componentAdapterFactory, null);
      }
  
      /**
       * Creates a new container with a (caching) {@link DefaultComponentAdapterFactory} and no parent container.
       */
      public HierarchyAwarePicoContainer()
      {
          this(new DefaultComponentAdapterFactory(), null);
      }
  
      public Collection getComponentAdapters()
      {
          return Collections.unmodifiableList(componentAdapters);
      }
  
      public final ComponentAdapter getComponentAdapter(Object componentKey) throws AmbiguousComponentResolutionException
      {
          ComponentAdapter adapter = (ComponentAdapter)componentKeyToAdapterCache.get(componentKey);
  
          if ((adapter == null) && (parent != null))
          {
              adapter = parent.getComponentAdapter(componentKey);
          }
          return adapter;
      }
  
      public ComponentAdapter getComponentAdapterOfType(Class componentType)
      {
          // See http://jira.codehaus.org/secure/ViewIssue.jspa?key=PICO-115
          ComponentAdapter adapterByKey = getComponentAdapter(componentType);
  
          if (adapterByKey != null)
          {
              return adapterByKey;
          }
  
          List found = getComponentAdaptersOfType(componentType);
  
          if (found.size() == 1)
          {
              return (ComponentAdapter)found.get(0);
          }
          else if (found.size() == 0)
          {
              if (parent != null)
              {
                  return parent.getComponentAdapterOfType(componentType);
              }
              else
              {
                  return null;
              }
          }
          else
          {
              Class[] foundClasses = new Class[found.size()];
  
              for (int idx = 0; idx < foundClasses.length; idx++)
              {
                  foundClasses[idx] = ((ComponentAdapter)found.get(idx)).getComponentImplementation();
              }
              throw new AmbiguousComponentResolutionException(componentType, foundClasses);
          }
      }
  
      public List getComponentAdaptersOfType(Class componentType)
      {
          if (componentType == null)
          {
              return Collections.EMPTY_LIST;
          }
  
          List found = new ArrayList();
  
          for (Iterator iterator = getComponentAdapters().iterator(); iterator.hasNext();)
          {
              ComponentAdapter componentAdapter = (ComponentAdapter)iterator.next();
  
              if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation()))
              {
                  found.add(componentAdapter);
              }
          }
          return found;
      }
  
      /**
       * {@inheritDoc}
       * This method can be used to override the ComponentAdapter created by the {@link ComponentAdapterFactory}
       * passed to the constructor of this container.
       */
      public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) throws DuplicateComponentKeyRegistrationException
      {
          Object componentKey = componentAdapter.getComponentKey();
  
          if (componentKeyToAdapterCache.containsKey(componentKey))
          {
              throw new DuplicateComponentKeyRegistrationException(componentKey);
          }
          componentAdapters.add(componentAdapter);
          componentKeyToAdapterCache.put(componentKey, componentAdapter);
          return componentAdapter;
      }
  
      public ComponentAdapter unregisterComponent(Object componentKey)
      {
          ComponentAdapter adapter = (ComponentAdapter) componentKeyToAdapterCache.remove(componentKey);
  
          componentAdapters.remove(adapter);
          orderedComponentAdapters.remove(adapter);
          return adapter;
      }
  
      /**
       * {@inheritDoc}
       * The returned ComponentAdapter will be an {@link InstanceComponentAdapter}.
       */
      public ComponentAdapter registerComponentInstance(Object component) throws PicoRegistrationException
      {
          return registerComponentInstance(component.getClass(), component);
      }
  
      /**
       * {@inheritDoc}
       * The returned ComponentAdapter will be an {@link InstanceComponentAdapter}.
       */
      public ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance) throws PicoRegistrationException
      {
          if (componentInstance instanceof MutablePicoContainer)
          {
              MutablePicoContainer pc            = (MutablePicoContainer)componentInstance;
              Object               contrivedKey  = new Object();
              String               contrivedComp = "";
  
              pc.registerComponentInstance(contrivedKey, contrivedComp);
              try
              {
                  if (getComponentInstance(contrivedKey) != null)
                  {
                      throw new PicoRegistrationException("Cannot register a container to itself. The container is already implicitly registered.");
                  }
              }
              finally
              {
                  pc.unregisterComponent(contrivedKey);
              }
  
          }
  
          ComponentAdapter componentAdapter = new InstanceComponentAdapter(componentKey, componentInstance);
  
          registerComponent(componentAdapter);
          return componentAdapter;
      }
  
      /**
       * {@inheritDoc}
       * The returned ComponentAdapter will be instantiated by the {@link ComponentAdapterFactory}
       * passed to the container's constructor.
       */
      public ComponentAdapter registerComponentImplementation(Class componentImplementation) throws PicoRegistrationException
      {
          return registerComponentImplementation(componentImplementation, componentImplementation);
      }
  
      /**
       * {@inheritDoc}
       * The returned ComponentAdapter will be instantiated by the {@link ComponentAdapterFactory}
       * passed to the container's constructor.
       */
      public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation) throws PicoRegistrationException
      {
          return registerComponentImplementation(componentKey, componentImplementation, (Parameter[]) null);
      }
  
      /**
       * {@inheritDoc}
       * The returned ComponentAdapter will be instantiated by the {@link ComponentAdapterFactory}
       * passed to the container's constructor.
       */
      public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoRegistrationException
      {
          ComponentAdapter componentAdapter = componentAdapterFactory.createComponentAdapter(componentKey, componentImplementation, parameters);
  
          registerComponent(componentAdapter);
          return componentAdapter;
      }
  
      /**
       * Same as {@link #registerComponentImplementation(java.lang.Object, java.lang.Class, org.picocontainer.Parameter[])}
       * but with parameters as a {@link List}. Makes it possible to use with Groovy arrays (which are actually Lists).
       */
      public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, List parameters) throws PicoRegistrationException
      {
          Parameter[] parametersAsArray = (Parameter[])parameters.toArray(new Parameter[parameters.size()]);
  
          return registerComponentImplementation(componentKey, componentImplementation, parametersAsArray);
      }
  
      private void addOrderedComponentAdapter(ComponentAdapter componentAdapter)
      {
          if (!orderedComponentAdapters.contains(componentAdapter))
          {
              orderedComponentAdapters.add(componentAdapter);
          }
      }
  
      public List getComponentInstances() throws PicoException
      {
          return getComponentInstancesOfType(Object.class);
      }
  
      public List getComponentInstancesOfType(Class componentType) throws PicoException
      {
          if (componentType == null)
          {
              return Collections.EMPTY_LIST;
          }
  
          Map adapterToInstanceMap = new HashMap();
  
          for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();)
          {
              ComponentAdapter componentAdapter = (ComponentAdapter)iterator.next();
  
              if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation()))
              {
                  adapterToInstanceMap.put(componentAdapter, getInstance(componentAdapter));
  
                  // This is to ensure all are added. (Indirect dependencies will be added
                  // from InstantiatingComponentAdapter).
                  addOrderedComponentAdapter(componentAdapter);
              }
          }
  
          List result = new ArrayList();
  
          for (Iterator iterator = orderedComponentAdapters.iterator(); iterator.hasNext();)
          {
              Object componentAdapter = iterator.next();
  
              final Object componentInstance = adapterToInstanceMap.get(componentAdapter);
  
              if (componentInstance != null)
              {
                  // may be null in the case of the "implicit" adapter
                  // representing "this".
                  result.add(componentInstance);
              }
          }
          return result;
      }
  
      public Object getComponentInstance(Object componentKey) throws PicoException
      {
          ComponentAdapter componentAdapter = getComponentAdapter(componentKey);
  
          if (componentAdapter != null)
          {
              return getInstance(componentAdapter);
          }
          else
          {
              return null;
          }
      }
  
      public Object getComponentInstanceOfType(Class componentType)
      {
          final ComponentAdapter componentAdapter = getComponentAdapterOfType(componentType);
  
          return componentAdapter == null ? null : getInstance(componentAdapter);
      }
  
      private Object getInstance(ComponentAdapter componentAdapter)
      {
          return componentAdapter.getComponentInstance(this);
      }
  
  
      public PicoContainer getParent()
      {
          return parent;
      }
  
      public ComponentAdapter unregisterComponentByInstance(Object componentInstance)
      {
          Collection componentAdapters = getComponentAdapters();
  
          for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();)
          {
              ComponentAdapter componentAdapter = (ComponentAdapter)iterator.next();
  
              if (getInstance(componentAdapter).equals(componentInstance))
              {
                  return unregisterComponent(componentAdapter.getComponentKey());
              }
          }
          return null;
      }
  
      /**
       * @deprecated since 1.1 - Use new VerifyingVisitor().traverse(this)
      */
      public void verify() throws PicoVerificationException
      {
          new VerifyingVisitor().traverse(this);
      }
  
      /**
       * Start the components of this PicoContainer and all its logical child containers.
       * Any component implementing the lifecycle interface {@link org.picocontainer.Startable} will be started.
       * @see #makeChildContainer()
       * @see #addChildContainer(PicoContainer)
       * @see #removeChildContainer(PicoContainer)
       */
      public void start()
      {
          if (disposed)
          {
              throw new IllegalStateException("Already disposed");
          }
          if (started)
          {
              throw new IllegalStateException("Already started");
          }
  
          LifecycleVisitor.start(this);
  
          started = true;
      }
  
      /**
       * Stop the components of this PicoContainer and all its logical child containers.
       * Any component implementing the lifecycle interface {@link org.picocontainer.Startable} will be stopped.
       * @see #makeChildContainer()
       * @see #addChildContainer(PicoContainer)
       * @see #removeChildContainer(PicoContainer)
       */
      public void stop()
      {
          if (disposed)
          {
              throw new IllegalStateException("Already disposed");
          }
          if (!started)
          {
              throw new IllegalStateException("Not started");
          }
  
          LifecycleVisitor.stop(this);
  
          started = false;
      }
  
      /**
       * Dispose the components of this PicoContainer and all its logical child containers.
       * Any component implementing the lifecycle interface {@link org.picocontainer.Disposable} will be disposed.
       * @see #makeChildContainer()
       * @see #addChildContainer(PicoContainer)
       * @see #removeChildContainer(PicoContainer)
       */
      public void dispose()
      {
          if (disposed)
          {
              throw new IllegalStateException("Already disposed");
          }
  
          LifecycleVisitor.dispose(this);
  
          disposed = true;
      }
  
      public MutablePicoContainer makeChildContainer()
      {
          DefaultPicoContainer pc = new DefaultPicoContainer(componentAdapterFactory, this);
  
          addChildContainer(pc);
          return pc;
      }
  
      public boolean addChildContainer(PicoContainer child)
      {
          return children.add(child);
      }
  
      public boolean removeChildContainer(PicoContainer child)
      {
          return children.remove(child);
      }
  
      public void accept(PicoVisitor visitor)
      {
          visitor.visitContainer(this);
  
          final List componentAdapters = new ArrayList(getComponentAdapters());
  
          for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();)
          {
              ComponentAdapter componentAdapter = (ComponentAdapter)iterator.next();
  
              componentAdapter.accept(visitor);
          }
  
          final List allChildren = new ArrayList(children);
  
          for (Iterator iterator = allChildren.iterator(); iterator.hasNext();)
          {
              PicoContainer child = (PicoContainer)iterator.next();
  
              child.accept(visitor);
          }
      }
  }
  
  
  

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