Return-Path: Delivered-To: apmail-jakarta-avalon-cvs-archive@apache.org Received: (qmail 35258 invoked from network); 12 Jul 2002 16:05:49 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 12 Jul 2002 16:05:49 -0000 Received: (qmail 22335 invoked by uid 97); 12 Jul 2002 16:05:56 -0000 Delivered-To: qmlist-jakarta-archive-avalon-cvs@jakarta.apache.org Received: (qmail 22289 invoked by uid 97); 12 Jul 2002 16:05:54 -0000 Mailing-List: contact avalon-cvs-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon CVS List" Reply-To: "Avalon Developers List" Delivered-To: mailing list avalon-cvs@jakarta.apache.org Received: (qmail 22209 invoked by uid 97); 12 Jul 2002 16:05:48 -0000 X-Antivirus: nagoya (v4198 created Apr 24 2002) Date: 12 Jul 2002 16:05:06 -0000 Message-ID: <20020712160506.53844.qmail@icarus.apache.org> From: mcconnell@apache.org To: jakarta-avalon-excalibur-cvs@apache.org Subject: cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container Selector.java ResourceProvider.java DependencyGraph.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N mcconnell 2002/07/12 09:05:06 Added: assembly/src/java/org/apache/excalibur/merlin/container Selector.java ResourceProvider.java DependencyGraph.java Log: package rationalization Revision Changes Path 1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/Selector.java Index: Selector.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.excalibur.merlin.container; import org.apache.excalibur.merlin.model.Profile; /** * Interface implemented by a service selection implementation mechanism. Classes * implementing the selector interface may be activated during the selection of * candidate service providers in an autom assembly process. A selector my be * declared via inclusion a implemetation class nameed <service-type>Selector. * Alternatively, a component author may declare a selection class explicitly via a * service dependecy attribute with the attribute name of avalon.service.selector. * * @author Stephen McConnell * @version $Revision: 1.1 $ $Date: 2002/07/12 16:05:05 $ */ public interface Selector { /** * Returns the preferred profile form an available selection of candidate provider profiles. * @param facilities the set of profiles of potential service providers available in the * container hierachy * @param profiles the set of profiles of potential service providers contained with the * local container * @return the preferred provider or null if no satisfactory provider can be established * from the supplied profiles. */ Profile select( Profile[] facilities, Profile[] profiles ); } 1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/ResourceProvider.java Index: ResourceProvider.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.excalibur.merlin.container; import java.io.InputStream; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.JarURLConnection; import java.net.URLClassLoader; import java.util.Map; import java.util.List; import java.util.LinkedList; import java.util.Hashtable; import java.util.Properties; import java.util.Vector; import java.util.Iterator; import java.util.jar.Attributes; import java.util.jar.Manifest; import java.security.Policy; import java.io.FileInputStream; import java.util.HashMap; import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; import org.apache.excalibur.configuration.ConfigurationUtil; import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.logger.AvalonFormatter; import org.apache.avalon.framework.logger.LogKitLogger; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Executable; import org.apache.avalon.framework.activity.Startable; import org.apache.avalon.framework.CascadingRuntimeException; import org.apache.avalon.framework.service.ServiceManager; 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.parameters.Parameters; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.DefaultConfiguration; import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.DefaultContext; import org.apache.avalon.framework.service.Serviceable; import org.apache.avalon.framework.service.ServiceManager; import org.apache.avalon.framework.service.DefaultServiceManager; import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.Version; import org.apache.avalon.framework.ExceptionUtil; import org.apache.avalon.excalibur.extension.PackageRepository; import org.apache.avalon.excalibur.extension.Extension; import org.apache.avalon.excalibur.extension.OptionalPackage; import org.apache.avalon.excalibur.extension.DefaultPackageRepository; import org.apache.excalibur.meta.verifier.VerifyException; import org.apache.excalibur.meta.info.Type; import org.apache.excalibur.meta.info.DefaultType; import org.apache.excalibur.meta.info.ServiceDescriptor; import org.apache.excalibur.meta.info.DependencyDescriptor; import org.apache.excalibur.meta.info.ServiceDesignator; import org.apache.excalibur.merlin.model.Profile; import org.apache.excalibur.merlin.model.Association; import org.apache.excalibur.merlin.model.CategoryDescriptor; import org.apache.excalibur.merlin.kernel.DefaultLoggerManager; import org.apache.log.Hierarchy; import org.apache.log.Priority; import org.apache.log.output.io.StreamTarget; /** * Internal class that handles the establishment of component instances based on a supplied * type profile. * * @author Stephen McConnell * @version $Revision: 1.1 $ $Date: 2002/07/12 16:05:06 $ */ class ResourceProvider extends AbstractLogEnabled { //======================================================================= // state //======================================================================= private final static Resources REZ = ResourceManager.getPackageResources( ResourceProvider.class ); //======================================================================= // state //======================================================================= /** * The classloader to use when servicing object creation requests. */ private ClassLoader m_classloader; /** * A hashtable of service implemenentation object references keyed by profile. */ private final Hashtable m_singletons = new Hashtable(); /** * The log manager. */ private DefaultLoggerManager m_logging; private Container m_locator; //======================================================================= // constructor //======================================================================= public ResourceProvider( ClassLoader loader, DefaultLoggerManager manager, Container locator ) { m_classloader = loader; m_logging = manager; m_locator = locator; } //======================================================================= // ResourceProvider //======================================================================= /** * Create an object specified by profile. * * @param profile the profile * @return the new object * @throws Exception if unable to resolve resource */ public Object createObject( Profile profile ) throws Exception { Object object = getSingletonInstance( profile ); if( object == null ) { Class clazz = null; String classname = null; try { classname = profile.getType().getInfo().getImplementationKey(); clazz = m_classloader.loadClass( classname ); } catch( Throwable e ) { final String error = "Unexpected exception while attempting to load class '" + classname + "' for the profile: " + profile; throw new ContainerException( error, e ); } try { object = clazz.newInstance(); putSingletonInstance( profile, object ); } catch( Throwable e ) { final String error = "Unexpected exception while attempting to instantiate an instance from profile: " + profile; throw new ContainerException( error, e ); } } return object; } /** * Create a new Logger for component. * * @param profile the profile * @return a new Logger for service * @throws Exception if unable to create the logger */ public Logger createLogger( Profile profile ) throws Exception { final String name = profile.getName(); CategoryDescriptor loggers = profile.getCategoryDescriptor(); m_logging.addCategories( loggers ); return m_logging.getLoggerForCategory( loggers ); } /** * Create a new Context for component. * * @param profile the profile * @return a new Context for service * @throws Exception if unable to create context */ public Context createContext( Profile profile ) throws Exception { return profile.getContext(); } /** * Create a new ComponentManager for component. * * @param profile the profile * @return a new ComponentManager for component * @throws Exception if unable to create the component manager */ public ComponentManager createComponentManager( Profile profile ) throws Exception { final Map services = getServices( profile ); 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; } /** * Create a new ServiceManager for component. * * @param entry the entry * @return a new ServiceManager for component * @throws Exception if unable to create resource */ public ServiceManager createServiceManager( Profile profile ) throws Exception { final Map services = getServices( profile ); 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 new Configuration object for component. * * @param entry the entry * @return a new Configuration object for component * @throws Exception if unable to create resource */ public Configuration createConfiguration( Profile profile ) throws Exception { Configuration config = profile.getConfiguration(); if( config == null ) config = new DefaultConfiguration("configuration", null ); return config; } /** * Create a new Parameters object for component. * * @param entry the entry * @return a new Parameters object for component * @throws Exception if unable to create resource */ public Parameters createParameters( Profile profile ) throws Exception { final Parameters parameters = profile.getParameters(); if( null == parameters ) { final String message = REZ.getString( "resource.missing-parameters.error", profile.getName() ); throw new Exception( message ); } parameters.makeReadOnly(); return parameters; } public Object getSingletonInstance( Profile profile ) { return m_singletons.get( profile ); } private void putSingletonInstance( Profile profile, Object object ) { m_singletons.put( profile, object ); } /** * Prepare a map of the dependent services keyed by role name. * @param profile the profile referencing a type declaring dependecies * @return a map of the services */ private Map getServices( Profile profile ) throws Exception { final Type type = profile.getType(); final DependencyDescriptor[] dependencies = type.getDependencies(); final HashMap services = new HashMap(); for( int i = 0; i < dependencies.length; i++ ) { DependencyDescriptor dependency = dependencies[i]; final String role = dependency.getRole(); final Association association = profile.getAssociation( role ); final Profile provider = association.getProvider(); final boolean required = type.getDependency( role ).isRequired(); final String classname = type.getDependency( role ).getService().getClassname(); final Object service = lookup( provider, classname ); if(( null == service ) && ( required )) { final String message = REZ.getString( "resource.missing-dependency.error", !required ? "1" : "2", role, profile.getName() ); throw new Exception( message ); } services.put( role, service ); } return services; } /** * Get a service instance for the supplied profile, and validate that the returned * service instance implements the supplied service classname. * @param provider the key to the provider instance * @param service the classname of the service requested */ private Object lookup( Profile provider, String service ) throws Exception { Object object = m_locator.lookup( provider ); if( objectImplementsType( object, service ) ) return object; final String error = "Unable to locate an instantiated service instance implementing the interface: " + service + ", from the provider: " + provider; throw new ContainerException( error ); } /** * 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 ) throws Exception { if( value == null ) return false; 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/assembly/src/java/org/apache/excalibur/merlin/container/DependencyGraph.java Index: DependencyGraph.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.excalibur.merlin.container; import java.util.ArrayList; import org.apache.excalibur.merlin.model.Profile; import org.apache.excalibur.merlin.model.Association; import org.apache.excalibur.meta.info.DependencyDescriptor; /** *

Utility class to help aquire a ordered graph of * consumers and providers for specific components.

*

UML

*

* * @author Peter Donald * @author Stephen McConnell * @version $Revision: 1.1 $ $Date: 2002/07/12 16:05:06 $ */ public class DependencyGraph { /** * Parent Map. Components in parent * Map are potential Providers for services * if no profile in current assembly satisfies dependency. */ private final DependencyGraph m_parent; /** * The set of components declared by the container as available., * Used when searching for providers/consumers. */ private final ArrayList m_components = new ArrayList(); /** * The child {@link DependencyGraph} objects. * Possible consumers of services in this assembly. */ private final ArrayList m_children = new ArrayList(); public DependencyGraph() { this( null ); } public DependencyGraph( final DependencyGraph parent ) { m_parent = parent; } /** * Add child dependency graph. * * @param child the child map */ public void addChild( final DependencyGraph child ) { m_children.add( child ); } /** * Remove child dependency graph. * * @param child the child map */ public void removeChild( final DependencyGraph child ) { m_children.remove( child ); } /** * Add a profile to current dependency graph. * * @param profile the profile */ public void add( final Profile profile ) { if( !m_components.contains( profile ) ) m_components.add( profile ); } /** * Get the serilized graph of {@link Profile} objects * required when starting up all the components. This makes sure * that all providers occur before their coresponding * consumers in graph. * * @return the ordered list of components */ public Profile[] getStartupGraph() { return walkGraph( true ); } /** * Get the serilized graph of {@link Profile} objects * required when shutting down all the components. This makes * sure that all consumers occur before their coresponding * providers in graph. * * @return the ordered list of components */ public Profile[] getShutdownGraph() { return walkGraph( false ); } /** * Get the serilized graph of {@link Profile} objects * that use services of specified profile. * * @param profile the profile * @return the ordered list of consumers */ public Profile[] getConsumerGraph( final Profile profile ) { return referencedProfiles( profile, getComponentGraph( profile, false )); } /** * Get the serilized graph of {@link Profile} objects * that provide specified profile with services. * * @param profile the profile * @return the ordered list of providers */ public Profile[] getProviderGraph( final Profile profile ) { return referencedProfiles( profile, getComponentGraph( profile, true )); } /** * Return a profile array that does not include the provided profile. */ private Profile[] referencedProfiles( final Profile profile, Profile[] profiles ) { ArrayList list = new ArrayList(); for( int i=0; i For additional commands, e-mail: