mcconnell 2002/11/18 02:57:21 Added: assembly/src/java/org/apache/excalibur/assembly/type UnknownTypeException.java TypeRuntimeException.java TypeManager.java TypeException.java package.html DefaultTypeManager.java Log: Addition of the first cut of the refactoring of the type management system. This includes a clean seperation of a type repository from the classloader through the defintion of a TypeManager and default implemetation. Revision Changes Path 1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/assembly/type/UnknownTypeException.java Index: UnknownTypeException.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.excalibur.assembly.type; /** * Exception to indicate that a type is unknown within the scope of a type manager. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a> * @version $Revision: 1.1 $ $Date: 2002/11/18 10:57:20 $ */ public final class UnknownTypeException extends TypeException { /** * Construct a new <code>UnknownTypeException</code> instance. * * @param message The detail message for this exception. */ public UnknownTypeException( final String message ) { this( message, null ); } /** * Construct a new <code>UnknownTypeException</code> instance. * * @param message The detail message for this exception. * @param throwable the root cause of the exception */ public UnknownTypeException( final String message, final Throwable throwable ) { super( message, throwable ); } } 1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/assembly/type/TypeRuntimeException.java Index: TypeRuntimeException.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.excalibur.assembly.type; import org.apache.avalon.framework.CascadingRuntimeException; /** * Exception to indicate that there was a type related runtime error. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a> * @version $Revision: 1.1 $ $Date: 2002/11/18 10:57:20 $ */ public final class TypeRuntimeException extends CascadingRuntimeException { /** * Construct a new <code>TypeRuntimeException</code> instance. * * @param message The detail message for this exception. */ public TypeRuntimeException( final String message ) { this( message, null ); } /** * Construct a new <code>TypeRuntimeException</code> instance. * * @param message The detail message for this exception. * @param throwable the root cause of the exception */ public TypeRuntimeException( final String message, final Throwable throwable ) { super( message, throwable ); } } 1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/assembly/type/TypeManager.java Index: TypeManager.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.excalibur.assembly.type; import org.apache.avalon.framework.configuration.Configuration; import org.apache.excalibur.meta.info.Type; import org.apache.excalibur.meta.info.builder.TypeCreator; import org.apache.excalibur.meta.info.DependencyDescriptor; import org.apache.excalibur.meta.info.StageDescriptor; /** * A type manager implemetation provides support for the creation, * storage and retrival of component types. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a> * @version $Revision: 1.1 $ $Date: 2002/11/18 10:57:21 $ */ public interface TypeManager { /** * Register a type. The implementation will create and verirfy * a component type instance for the entry if not already known and * return the existing or new instance to the invoking client. * * @param path the component class name * @return the component type * @exception Exception if a registration failure occurs */ Type register( String path ) throws TypeException; /** * Locate a [EMAIL PROTECTED] Type} instances associated with the * supplied implementation classname. * @return the type matching the supplied implementation classname. * @exception UnknownTypeException if a matching type cannot be found */ Type locate( String classname ) throws UnknownTypeException; /** * Locate the set of component types capable of services the supplied * dependency. * @param a service depedency descriptor * @return a set of types capable of servicing the supplied dependency */ Type[] match( DependencyDescriptor dependency ); /** * Locate the set of component types that provide the supplied extension. * @param service a service descriptor * @return a set of types that provide the supplied service */ Type[] match( StageDescriptor stage ); } 1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/assembly/type/TypeException.java Index: TypeException.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.excalibur.assembly.type; import org.apache.avalon.framework.CascadingException; /** * Exception to indicate that there was a type related error. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a> * @version $Revision: 1.1 $ $Date: 2002/11/18 10:57:21 $ */ public class TypeException extends CascadingException { /** * Construct a new <code>TypeException</code> instance. * * @param message The detail message for this exception. */ public TypeException( final String message ) { this( message, null ); } /** * Construct a new <code>TypeException</code> instance. * * @param message The detail message for this exception. * @param throwable the root cause of the exception */ public TypeException( final String message, final Throwable throwable ) { super( message, throwable ); } } 1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/assembly/type/package.html Index: package.html =================================================================== <body> <p> The <code>type</code> package contains classes and interfaces for the [EMAIL PROTECTED] org.apache.excalibur.assembly.type.TypeManager} and related default implementations supporting the management of a repository of component types. </p> </body> 1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/assembly/type/DefaultTypeManager.java Index: DefaultTypeManager.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.excalibur.assembly.type; import java.util.Map; import java.util.Hashtable; import java.util.Iterator; import java.util.ArrayList; import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.configuration.Configuration; import org.apache.excalibur.meta.info.Type; import org.apache.excalibur.meta.info.builder.TypeBuilder; import org.apache.excalibur.meta.info.builder.TypeCreator; import org.apache.excalibur.meta.info.ReferenceDescriptor; import org.apache.excalibur.meta.info.DependencyDescriptor; import org.apache.excalibur.meta.info.ServiceDescriptor; import org.apache.excalibur.meta.info.StageDescriptor; import org.apache.excalibur.meta.verifier.ComponentVerifier; /** * A type manager implemetation provides support for the creation, * storage and retrival of component types. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a> * @version $Revision: 1.1 $ $Date: 2002/11/18 10:57:21 $ */ public class DefaultTypeManager extends AbstractLogEnabled implements TypeManager { //============================================================== // state //============================================================== /** * The classloader supplied to the manager. */ private final ClassLoader m_classloader; /** * The parent type manager (may be null) */ private final TypeManager m_parent; /** * The type builder. */ private final TypeBuilder m_builder = new TypeBuilder(); /** * Table of component types keyed by implementation classname. */ private Hashtable m_types = new Hashtable(); //============================================================== // constructor //============================================================== /** * Creation of a new [EMAIL PROTECTED] TypeManager} based on a supplied parent * and classloader. * @param parent the parent type manager (may be null) * @param classloader the classloader */ public DefaultTypeManager( TypeManager parent, ClassLoader classloader ) { if( classloader == null ) { throw new NullPointerException("classloader"); } m_parent = parent; m_classloader = classloader; } //============================================================== // LogEnabled //============================================================== /** * Setup logging for all subcomponents * @param logger the logging channel */ public void enableLogging( final Logger logger ) { super.enableLogging( logger ); m_builder.enableLogging( logger.getChildLogger( "builder" ) ); } //============================================================== // TypeManager //============================================================== /** * Register a type. The implementation will create and verirfy * a component type instance for the entry if not already known and * return the existing or new instance to the invoking client. * * @param path the component class name * @return the component type */ public Type register( String path ) throws TypeException { final String classname = path.replace( '/', '.' ); Type type; try { type = locate( classname ); } catch( UnknownTypeException ute ) { try { type = m_builder.build( classname, m_classloader ); } catch( Throwable e ) { final String error = "Could not register a type relative to the path: " + path + " due to a type build error."; throw new TypeException( error, e ); } try { verify( type ); } catch( Throwable e ) { final String error = "Could not register a type relative to the path: " + path + " due to a type verification failure."; throw new TypeException( error, e ); } if( getLogger().isDebugEnabled() ) { getLogger().debug("registering type: " + classname ); } m_types.put( classname, type ); } return type; } /** * Locate a [EMAIL PROTECTED] Type} instances associated with the * supplied implementation classname. * @return the type matching the supplied implementation classname. * @exception UnknownTypeException if a matching type cannot be found */ public Type locate( String classname ) throws UnknownTypeException { Type type = (Type) m_types.get( classname ); if( type == null ) { throw new UnknownTypeException( classname ); } return type; } /** * Locate the set of component types capable of services the supplied * dependency. * @param a service depedency descriptor * @return a set of types capable of servicing the supplied dependency */ public Type[] match( DependencyDescriptor dependency ) { ArrayList list = new ArrayList(); if( m_parent != null ) { Type[] types = m_parent.match( dependency ); for( int i=0; i<types.length; i++ ) { list.add( types[i] ); } } ReferenceDescriptor reference = dependency.getReference(); Iterator iterator = m_types.entrySet().iterator(); while( iterator.hasNext() ) { Type type = (Type) iterator.next(); Object service = type.getService( reference ); if( service != null ) { list.add( type ); } } return (Type[]) list.toArray( new Type[0] ); } /** * Locate the set of component types that provide the supplied extension. * @param service a service descriptor * @return a set of types that provide the supplied service */ public Type[] match( StageDescriptor stage ) { ArrayList list = new ArrayList(); if( m_parent != null ) { Type[] types = m_parent.match( stage ); for( int i=0; i<types.length; i++ ) { list.add( types[i] ); } } Iterator iterator = m_types.entrySet().iterator(); while( iterator.hasNext() ) { Type type = (Type) iterator.next(); if( type.getExtension( stage ) != null ) { list.add( type ); } } return (Type[]) list.toArray( new Type[0] ); } private void verify( Type type ) throws Exception { String name = type.getInfo().getName(); Class clazz = getComponentClass( type ); Class[] classes = getServiceClasses( type ); ComponentVerifier verifier = new ComponentVerifier(); verifier.enableLogging( getLogger().getChildLogger( "verifier" ) ); verifier.verifyComponent( name, clazz, classes ); } /** * Return the set of interface classes for a given type that are declared * or default to the "native" service access protocol and where the * service access model is undefined (i.e. native implementation). * access mode. * * @param type the component type * @return an array of classes represnting the type's service interfaces */ private Class[] getServiceClasses( Type type ) { ArrayList list = new ArrayList(); ServiceDescriptor[] services = type.getServices(); for( int i = 0; i < services.length; i++ ) { ServiceDescriptor service = services[ i ]; if( ( service.getAttribute( "avalon:service.protocol", "native" ).equals( "native" ) ) && ( service.getAttribute( "avalon:service.accessor", null ) == null ) ) { list.add( getServiceClass( services[ i ] ) ); } } return ( Class[]) list.toArray( new Class[0] ); } /** * Returns the component type implementation class. * @param type the component type descriptor * @return the class implementing the component type * @exception TypeException if a classloader error occurs */ private Class getComponentClass( Type type ) throws TypeException { if( null == type ) { throw new NullPointerException( "type" ); } final String classname = type.getInfo().getImplementationKey(); try { return m_classloader.loadClass( classname ); } catch( Throwable e ) { final String error = "Could not load implementation class for component type: " + classname; throw new TypeException( error, e ); } } /** * Returns the service type implementation class. * @param service the service type descriptor * @return the class implementing the service type * @exception TypeRuntimeException if a classloader error occurs */ private Class getServiceClass( ServiceDescriptor service ) throws TypeRuntimeException { final String classname = service.getReference().getClassname(); try { return m_classloader.loadClass( classname ); } catch( Throwable e ) { final String error = "Could not load implementation class for service type: " + classname; throw new TypeRuntimeException( error, e ); } } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>