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