donaldp 2002/06/17 20:41:49
Modified: containerkit/src/java/org/apache/excalibur/containerkit/kernel
KernelResourceAccessor.java
Added: containerkit/src/java/org/apache/excalibur/containerkit/kernel
Resources.properties
Log:
Update Accessor to be more fully implemented
Revision Changes Path
1.2 +250 -31
jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/kernel/KernelResourceAccessor.java
Index: KernelResourceAccessor.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/kernel/KernelResourceAccessor.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- KernelResourceAccessor.java 14 Jun 2002 08:00:47 -0000 1.1
+++ KernelResourceAccessor.java 18 Jun 2002 03:41:49 -0000 1.2
@@ -8,40 +8,129 @@
package org.apache.excalibur.containerkit.kernel;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
+import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
+import org.apache.avalon.framework.component.DefaultComponentManager;
+import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.excalibur.containerkit.lifecycle.ResourceAccessor;
import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
+import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
+import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ContextDescriptor;
import org.apache.excalibur.containerkit.metainfo.EntryDescriptor;
/**
+ * This is the bas object via which the kernel aquires
+ * resources for each component. This base implementation
+ * will aquire components and make sure that all required
+ * components are present. It will also make sure that the types
+ * of values returned from context are valid.
*
+ * <p>Note that this class assumes that the dependency graph
+ * has been validated (presumably via
+ * [EMAIL PROTECTED]
org.apache.excalibur.containerkit.verifier.AssemblyVerifier}</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @version $Revision$ $Date$
*/
public abstract class KernelResourceAccessor
+ extends AbstractLogEnabled
implements ResourceAccessor
{
private final static Resources REZ =
ResourceManager.getPackageResources( KernelResourceAccessor.class );
- private final AbstractServiceKernel m_kernel;
+ /**
+ * Utility method via which the [EMAIL PROTECTED] KernelResourceAccessor)
+ * aquires services to place in ServiceManager for a particular
+ * component.
+ *
+ * <p>Must be implemented in subclass.</p>
+ *
+ * @param name the name of service
+ * @param entry the entry for component aquiring service
+ * @return the service object for specified name
+ */
+ protected abstract Object getService( String name, Object entry );
+
+ /**
+ * Utility method via which the [EMAIL PROTECTED] KernelResourceAccessor)
+ * aquires a context value to place in Context for a particular
+ * component.
+ *
+ * <p>Must be implemented in subclass.</p>
+ *
+ * @param name the name of service
+ * @param entry the entry for component aquiring service
+ * @return the context value for specified name
+ */
+ protected abstract Object getContextValue( String name, Object entry );
- public KernelResourceAccessor( final AbstractServiceKernel kernel )
+ /**
+ * Create a Parameters object by Creating configuration object and
converting that.
+ *
+ * @param entry the entry
+ * @return a new Parameters object for component
+ * @throws Exception if unable to create resource
+ */
+ public Parameters createParameters( Object entry )
+ throws Exception
+ {
+ final Configuration configuration = createConfiguration( entry );
+ return Parameters.fromConfiguration( configuration );
+ }
+
+ /**
+ * Create a [EMAIL PROTECTED] Context} object that contains values
specified in map.
+ * The default implementation creates a basic Context object but
different
+ * containers may choose to overide this to provide their own subclass
of context.
+ *
+ * @param contextData the data to place in context
+ * @return the Context object
+ */
+ protected Context createContextImpl( final Map contextData )
+ {
+ final DefaultContext context = new DefaultContext( contextData );
+ context.makeReadOnly();
+ return context;
+ }
+
+ /**
+ * Return the [EMAIL PROTECTED] ComponentMetaData} for specified
component entry.
+ * This implementation assumes that entry is instance of [EMAIL
PROTECTED] ComponentMetaData}
+ * but subclasses should overide this method if this assumption does not
hold true.
+ *
+ * @param entry the component entry
+ * @return the ComponentMetaData
+ */
+ protected ComponentMetaData getMetaData( final Object entry )
{
- m_kernel = kernel;
+ return (ComponentMetaData)entry;
}
- public Context createContext( Object entry )
+ /**
+ * Create a context object for specified component.
+ *
+ * @param componentEntry the entry representing component
+ * @return the created Context
+ * @throws Exception if unable to create context or entrys in context
+ */
+ public final Context createContext( final Object componentEntry )
throws Exception
{
- final ComponentMetaData component = getMetaData( entry );
+ final ComponentMetaData component = getMetaData( componentEntry );
+ final String componentName = component.getName();
+
final ContextDescriptor descriptor =
component.getComponentInfo().getContextDescriptor();
@@ -50,49 +139,70 @@
final EntryDescriptor[] entrys = descriptor.getEntrys();
for( int i = 0; i < entrys.length; i++ )
{
- final String key = entrys[ i ].getKey();
- final String type = entrys[ i ].getType();
- final boolean optional = entrys[ i ].isOptional();
+ final EntryDescriptor entry = entrys[ i ];
+ final String key = entry.getKey();
+ final String type = entry.getType();
+ final boolean optional = entry.isOptional();
final Object value =
- m_kernel.getContextValue( key, entry );
-
+ getContextValue( key, componentEntry );
- if( null == value && !optional )
+ if( null == value )
{
+ final String message =
+ REZ.getString( "resource.missing-context-value.error",
+ optional ? "1" : "2",
+ key,
+ componentName );
if( !optional )
{
- final String message =
- REZ.getString(
"resource.missing-context-value.error",
- key,
- component.getName() );
throw new Exception( message );
}
else
{
+ getLogger().warn( message );
continue;
}
}
- final Class clazz = value.getClass();
- final Class typeClass = clazz.getClassLoader().loadClass( type );
- if( !typeClass.isAssignableFrom( clazz ) )
+ final boolean typeValid = objectImplementsType( value, type );
+ if( !typeValid )
{
final String message =
REZ.getString( "resource.bad-value-type.error",
+ optional ? "1" : "2",
key,
+ componentName,
type,
- clazz.getName(),
- component.getName() );
- throw new Exception( message );
+ value.getClass().getName() );
+ if( !optional )
+ {
+ throw new Exception( message );
+ }
+ else
+ {
+ getLogger().warn( message );
+ continue;
+ }
}
+
+ contextData.put( key, value );
}
- return null;
- }
+ final Context context = createContextImpl( contextData );
+ final String classname = descriptor.getClassname();
- protected ComponentMetaData getMetaData( final Object entry )
- {
- return (ComponentMetaData)entry;
+ final boolean validContextClass = objectImplementsType( context,
classname );
+ if( !validContextClass )
+ {
+ final String message =
+ REZ.getString( "resource.bad-context-type.error",
+ classname,
+ context.getClass().getName(),
+ componentName );
+ throw new Exception( message );
+ }
+
+ return context;
}
/**
@@ -102,10 +212,31 @@
* @return a new ComponentManager for component
* @throws Exception if unable to create resource
*/
- public ComponentManager createComponentManager( Object entry )
+ public final ComponentManager createComponentManager( final Object entry
)
throws Exception
{
- return null;
+ final Map services = createServiceMap( entry );
+
+ final DefaultComponentManager componentManager = new
DefaultComponentManager();
+
+ final Iterator keys = services.keySet().iterator();
+ while( keys.hasNext() )
+ {
+ final String key = (String)keys.next();
+ final Object service = services.get( key );
+ if( !Component.class.isInstance( service ) )
+ {
+ final String message =
+ REZ.getString( "resource.service-not-a-component.error",
+ key,
+ service.getClass().getName() );
+ throw new Exception( message );
+ }
+ componentManager.put( key, (Component)service );
+ }
+
+ componentManager.makeReadOnly();
+ return componentManager;
}
/**
@@ -115,9 +246,97 @@
* @return a new ServiceManager for component
* @throws Exception if unable to create resource
*/
- public ServiceManager createServiceManager( Object entry )
+ public final ServiceManager createServiceManager( final Object entry )
throws Exception
{
- return null;
+ final Map services = createServiceMap( entry );
+
+ final DefaultServiceManager serviceManager = new
DefaultServiceManager();
+
+ final Iterator keys = services.keySet().iterator();
+ while( keys.hasNext() )
+ {
+ final String key = (String)keys.next();
+ final Object service = services.get( key );
+ serviceManager.put( key, service );
+ }
+
+ serviceManager.makeReadOnly();
+ return serviceManager;
+ }
+
+ /**
+ * Create a Map of services for specified component.
+ * The map maps role name to service provider.
+ *
+ * @param componentEntry the component entry creating map for
+ * @return the map
+ * @throws Exception if error aquiring a service to place in map
+ */
+ private Map createServiceMap( final Object componentEntry )
+ throws Exception
+ {
+ final ComponentMetaData component = getMetaData( componentEntry );
+ final ComponentInfo info = component.getComponentInfo();
+ final DependencyMetaData[] dependencies =
component.getDependencies();
+
+ final HashMap services = new HashMap();
+
+ for( int i = 0; i < dependencies.length; i++ )
+ {
+ final DependencyMetaData dependency = dependencies[ i ];
+ final String role = dependency.getRole();
+ final String providerName = dependency.getProviderName();
+ final boolean optional = info.getDependency( role ).isOptional();
+
+ final Object service =
+ getService( providerName, componentEntry );
+ if( null == service )
+ {
+ final String message =
+ REZ.getString( "resource.missing-dependency.error",
+ optional ? "1" : "2",
+ role,
+ component.getName() );
+ if( !optional )
+ {
+ throw new Exception( message );
+ }
+ else
+ {
+ getLogger().warn( message );
+ continue;
+ }
+ }
+
+ services.put( role, service );
+ }
+
+ return services;
+ }
+
+ /**
+ * Check whether the specified value is compatible with specified type.
+ *
+ * @param value the value
+ * @param type the desired type
+ * @return true if value is compatible with type, false otherwise
+ */
+ private boolean objectImplementsType( final Object value, final String
type )
+ {
+ try
+ {
+ final Class clazz = value.getClass();
+ final ClassLoader classLoader = clazz.getClassLoader();
+ final Class typeClass = classLoader.loadClass( type );
+ if( typeClass.isAssignableFrom( clazz ) )
+ {
+ return true;
+ }
+ }
+ catch( final ClassNotFoundException cnfe )
+ {
+ }
+ return false;
}
}
1.1
jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/kernel/Resources.properties
Index: Resources.properties
===================================================================
resource.missing-context-value.error=Missing {0,choice,1#Optional|2#Required}
Context Entry with key "{1}" for component named "{2}".
resource.bad-value-type.error=Bad value retrieved for
{0,choice,1#Optional|2#Required} Context Entry with key "{1}" for component
named "{2}". Expected to be of type "{3}" but was of type "{4}".
resource.bad-context-type.error=The class of Contex object for component
named "{2}" was expected to be of type {0} but was of tpye {1}.
resource.service-not-a-component.error=The service with role "0" and
implemenation class "{1}" does not implement the Component interface but is
being exposed via ComponentManager.
resource.missing-dependency.error=Missing {0,choice,1#Optional|2#Required}
dependency with role "{1}" for component named {2}.
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>