You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2002/07/12 10:05:35 UTC
cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier AssemblyVerifier.java MetaDataVerifier.java Resources.properties package.html
mcconnell 2002/07/12 01:05:35
Added: assembly/src/java/org/apache/excalibur/merlin/meta/data
AbstractContainer.java Association.java
CategoryDescriptor.java ClasspathDescriptor.java
ComponentDescriptor.java ContainerDescriptor.java
DefaultProfile.java DirsetDescriptor.java
ExtensionsDescriptor.java FileTargetProvider.java
FilesetDescriptor.java IncludeDescriptor.java
KernelDescriptor.java LoggingDescriptor.java
Profile.java TargetDescriptor.java
TargetProvider.java package.html
assembly/src/java/org/apache/excalibur/merlin/meta/data/builder
ContainerCreator.java KernelCreator.java
ProfileBuilder.java ProfileCreator.java
Resources.properties TypeManager.java
XMLContainerCreator.java XMLKernelCreator.java
XMLProfileCreator.java package.html
assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle
LifecycleException.java LifecycleHelper.java
ResourceProvider.java Resources.properties
package.html
assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier
AssemblyVerifier.java MetaDataVerifier.java
Resources.properties package.html
Log:
population of a realistic meta-data model
Revision Changes Path
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/AbstractContainer.java
Index: AbstractContainer.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.meta.data;
/**
* Interface implemeted by objects capable of acting as a container.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public interface AbstractContainer
{
/**
* Return the container name.
*
* @return the name of the container
*/
String getName();
/**
* Return the logging descriptor.
*
* @return the {@link CategoryDescriptor} for the component loggers.
*/
CategoryDescriptor getCategoryDescriptor();
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/Association.java
Index: Association.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.meta.data;
/**
* The Association is the mapping of a component as a dependency
* of another component. Each component declares dependencies (via Type)
* and for each dependency there must be a coressponding Association which
* has a matching role. The name value in Association object must refer
* to another Component that implements a service as specified in DependencyInfo.
*
* <p>Note that it is invalid to have circular dependencies.</p>
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public final class Association
{
/**
* The name that the client component will use to access a dependency.
*/
private final String m_role;
/**
* the name of the component metadata instance that represents a component
* type that is capable of fullfilling the dependency.
*/
private final Profile m_provider;
/**
* Create Profile with specified name and role.
*
* @param role the name client uses to access component
* @param providerName the name of <code>ComponentProfile</code> instance
* that is associated as a service provider
*/
public Association( final String role,
final Profile provider )
{
m_role = role;
m_provider = provider;
}
/**
* Return the name that will be used by a component instance to access a
* dependent service.
*
* @return the name that the client component will use to access dependency.
* @see org.apache.avalon.framework.service.ServiceManager#lookup( String )
*/
public String getRole()
{
return m_role;
}
/**
* Return the name of a <code>ComponentProfile</code> instance that will used to
* fulfill the dependency.
*
* @return the name of the Component that will provide the dependency.
*/
public Profile getProvider()
{
return m_provider;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/CategoryDescriptor.java
Index: CategoryDescriptor.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.meta.data;
import java.util.Hashtable;
/**
* A logging category descriptor hierachy.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class CategoryDescriptor
{
public static final String DEBUG = "DEBUG";
public static final String INFO = "INFO";
public static final String WARN = "WARN";
public static final String ERROR = "ERROR";
public static final String DEFAULT_LOGGING_TARGET = "default";
public static final String DEFAULT_LOGGING_PRIORITY = INFO;
/**
* The logging category name.
*/
private String m_name;
/**
* The default logging priority.
*/
private final String m_priority;
/**
* The default logging target.
*/
private final String m_target;
/**
* The loggers descriptor parent.
*/
protected CategoryDescriptor m_parent;
/**
* Subsidiary categories.
*/
private final Hashtable m_categories = new Hashtable();
/**
*/
public CategoryDescriptor( CategoryDescriptor parent, final String name )
{
this( parent, name, null, null, new CategoryDescriptor[0] );
}
/**
*/
public CategoryDescriptor( final String name, final String priority, final String target )
{
this( null, name, priority, target, new CategoryDescriptor[0] );
}
/**
*/
public CategoryDescriptor(
final String name, final String priority, final String target,
final CategoryDescriptor[] categories )
{
this( null, name, priority, target, categories );
}
/**
*/
public CategoryDescriptor(
CategoryDescriptor parent, final String name, final String priority, final String target,
final CategoryDescriptor[] categories )
{
m_name = name;
m_target = target;
m_priority = priority;
m_parent = parent;
for( int i=0; i<categories.length; i++ )
{
CategoryDescriptor category = categories[i];
m_categories.put( category.getName(), category );
category.setParent( this );
}
}
/**
* Return the category name.
*
* @return the category name
*/
public String getName()
{
return m_name;
}
/**
* Return the default logging priority for the group of categories.
*
* @return the default logging priority
*/
public String getPriority( )
{
if( m_priority == null )
{
if( m_parent != null )
{
return m_parent.getPriority();
}
else
{
return DEFAULT_LOGGING_PRIORITY;
}
}
return m_priority;
}
/**
* Return the default log target for the group of categories.
*
* @return the default target name
*/
public String getTarget( )
{
if( m_target == null )
{
if( m_parent != null )
{
return m_parent.getTarget();
}
else
{
return DEFAULT_LOGGING_TARGET;
}
}
return m_target;
}
public void setParent( CategoryDescriptor parent )
{
m_parent = parent;
}
/**
* Return the category path.
*
* @return the category path
*/
public String getPath()
{
if( m_parent != null )
{
String path = m_parent.getPath();
if( path.equals("") )
{
return getName();
}
else
{
return path + "." + getName();
}
}
else
{
return getName();
}
}
/**
* Return the set of logging categories.
*
* @return the set of service provider assignments.
*/
public CategoryDescriptor[] getCategories()
{
return (CategoryDescriptor[]) m_categories.values().toArray( new CategoryDescriptor[0] );
}
/**
* Return a named category.
* @param name the category name
* @return the named category of null if unknown
*/
public CategoryDescriptor getCategory( String name )
{
CategoryDescriptor category = (CategoryDescriptor) m_categories.get( name );
if( category == null )
{
category = new CategoryDescriptor( this, name );
m_categories.put( name, category );
}
return category;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/ClasspathDescriptor.java
Index: ClasspathDescriptor.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.meta.data;
/**
* A classpath descriptor.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class ClasspathDescriptor
{
/**
* The base directory
*/
private final FilesetDescriptor[] m_filesets;
/**
* Create a ClasspathDescriptor instance.
*
* @param filesets the set of filesets to include in the classpath
*/
public ClasspathDescriptor( final FilesetDescriptor[] filesets )
{
m_filesets = filesets;
}
/**
* Return the filesets held within the classpath descriptor.
*
* @return the filesets
*/
public FilesetDescriptor[] getFilesetDescriptors()
{
return m_filesets;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/ComponentDescriptor.java
Index: ComponentDescriptor.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.meta.data;
import java.io.Serializable;
import java.util.Hashtable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.context.Context;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.merlin.meta.data.Profile;
import org.apache.excalibur.merlin.meta.data.Association;
import org.apache.excalibur.configuration.ConfigurationUtil;
/**
* A component profile description.
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class ComponentDescriptor extends DefaultProfile
{
/**
* Create a Profile instance.
*
* @param name the abstract name of component meta data instance
* @param dependencies the meta data for any dependencies
* @param type the component type
*/
public ComponentDescriptor( final String name,
final Parameters parameters,
final Configuration configuration,
final Context context,
final CategoryDescriptor loggers,
final Type type,
final int mode )
{
super( name, parameters, configuration, context, loggers, type, mode );
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/ContainerDescriptor.java
Index: ContainerDescriptor.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.meta.data;
import java.util.ArrayList;
/**
* A container profile.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class ContainerDescriptor implements AbstractContainer
{
/**
* The parent.
*/
private AbstractContainer m_parent;
/**
* The container name.
*/
private final String m_name;
/**
* The loggers defintion.
*/
private final CategoryDescriptor m_loggers;
/**
* The container classpath descriptor.
*/
private final ClasspathDescriptor m_classpath;
/**
* The component described within the scope of the container.
*/
//private final ArrayList m_components = new ArrayList();
private final ComponentDescriptor[] m_components;
/**
* The component described within the scope of the container.
*/
private final ContainerDescriptor[] m_containers;
/**
* Create a ContainerDescriptor instance.
*
*/
public ContainerDescriptor( final String name,
final CategoryDescriptor loggers,
final ClasspathDescriptor classpath,
final ComponentDescriptor[] components,
final ContainerDescriptor[] containers )
{
if( name == null )
throw new NullPointerException("name");
if( loggers == null )
throw new NullPointerException("loggers");
if( classpath == null )
throw new NullPointerException("classpath");
m_name = name;
m_loggers = loggers;
m_classpath = classpath;
m_components = components;
m_containers = containers;
for( int i=0; i<containers.length; i++ )
{
containers[i].getCategoryDescriptor().setParent( loggers );
}
for( int i=0; i<components.length; i++ )
{
components[i].getCategoryDescriptor().setParent( loggers );
}
}
/**
* Return the container name.
*
* @return the name of the container
*/
public String getName()
{
return m_name;
}
/**
* Return the logging descriptor.
*
* @return the {@link CategoryDescriptor} for the component loggers.
*/
public CategoryDescriptor getCategoryDescriptor()
{
return m_loggers;
}
/**
* Return the classpath descriptor.
*
* @return the {@link ClasspathDescriptor} for the container.
*/
public ClasspathDescriptor getClasspathDescriptor()
{
return m_classpath;
}
/**
* Add a container to this container.
*
* @parent the container to add
*/
//public void addComponent( ComponentDescriptor component )
//{
// m_components.add( component );
// component.getCategoryDescriptor().setParent( getCategoryDescriptor() );
//}
/**
* Return the set of component descriptors contained within this container.
*
* @return the target descriptors
*/
public ComponentDescriptor[] getComponentDescriptors()
{
//return (ComponentDescriptor[]) m_components.toArray( new ComponentDescriptor[0] );
return m_components;
}
/**
* Return the set of subsidiary containers contained within this container.
*
* @return the target descriptors
*/
public ContainerDescriptor[] getContainers()
{
return m_containers;
}
/**
* Set the parent container.
*
* @param the container containing this container.
* @exception IllegalStateException if the parent is already set
*/
public void setParent( AbstractContainer parent ) throws IllegalStateException
{
if( m_parent != null )
throw new IllegalStateException("parent");
m_parent = parent;
ContainerDescriptor[] containers = getContainers();
for( int i=0; i<containers.length; i++ )
{
containers[i].setParent( this );
}
}
/**
* Return the parent container.
*
* @return the container containing this container.
*/
public AbstractContainer getParent()
{
return m_parent;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/DefaultProfile.java
Index: DefaultProfile.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.meta.data;
import java.io.Serializable;
import java.util.Hashtable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.context.Context;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.merlin.meta.data.Profile;
import org.apache.excalibur.merlin.meta.data.Association;
import org.apache.excalibur.configuration.ConfigurationUtil;
/**
* Abstract defintion of a compoent profile.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class DefaultProfile
implements Profile, Serializable
{
/**
* The name of the component metadata instance. This is an
* abstract name used during assembly.
*/
private final String m_name;
/**
* The dependencies keyed by role name.
*/
private final Hashtable m_dependencies = new Hashtable();
/**
* The info object for component type.
*/
private final Type m_type;
/**
* The parameters for component (if any).
*/
private final Parameters m_parameters;
/**
* The configuration for component (if any).
*/
private final Configuration m_configuration;
/**
* The configuration for component (if any).
*/
private final Context m_context;
/**
* The logging descriptor.
*/
private final CategoryDescriptor m_loggers;
/**
* The creation mode.
*/
private final int m_mode;
/**
* Create a Profile instance.
*
* @param name the abstract name of component meta data instance
* @param dependencies the meta data for any dependencies
* @param type the component type
*/
public DefaultProfile( final String name,
final Parameters parameters,
final Configuration configuration,
final Context context,
final CategoryDescriptor loggers,
final Type type,
final int mode )
{
if( null == name )
{
m_name = "" + System.identityHashCode( this );
}
else
{
m_name = name;
}
if( null == type )
{
throw new NullPointerException( "type" );
}
m_parameters = parameters;
m_configuration = configuration;
m_type = type;
m_context = context;
m_loggers = loggers;
m_mode = mode;
}
/**
* Return the name of component metadata instance.
*
* @return the name of the component.
*/
public String getName()
{
return m_name;
}
/**
* Return the info for component.
*
* @return the info for component type.
*/
public Type getType()
{
return m_type;
}
/**
* Return the assigned service providers.
*
* @return the set of service provider assignments.
*/
public Association[] getAssociations()
{
return (Association[])m_dependencies.values().toArray( new Association[0] );
}
/**
* Return the Context for component (if any).
*
* @return the Context for component (if any).
*/
public Context getContext()
{
return m_context;
}
/**
* Return the Parameters for Component (if any).
*
* @return the Parameters for Component (if any).
*/
public Parameters getParameters()
{
return m_parameters;
}
/**
* Return the Configuration for Component (if any).
*
* @return the Configuration for Component (if any).
*/
public Configuration getConfiguration()
{
return m_configuration;
}
/**
* Return the logging descriptor.
*
* @return the {@link CategoryDescriptor} for the component loggers.
*/
public CategoryDescriptor getCategoryDescriptor()
{
return m_loggers;
}
/**
* Return the dependency metadata for component type with specified role.
*
* @return the dependency metadata for component with specified role.
*/
public Association getAssociation( final String role )
{
return (Association) m_dependencies.get( role );
}
/**
* Returns the creation mode for this profile.
* @return a value of EXPLICIT, PACKAGED or IMPLICIT
*/
public int getMode()
{
return m_mode;
}
/**
* Add a provider for a service dependecy role.
* @param provider the compenont provider profile
* @param role the dependent role
*/
public void addProvider( Profile provider, String role )
{
m_dependencies.put( role, new Association( role, provider ) );
}
public String toString()
{
return "Profile name: " + getName()
+ ", type: " + getType().getInfo().getName()
+ ", mode: " + modeToString( getMode() );
}
private String modeToString( int mode )
{
if( mode == IMPLICIT )
{
return "IMPLICIT";
}
else if( mode == PACKAGED )
{
return "PACKAGED";
}
else if( mode == EXPLICIT )
{
return "EXPLICIT";
}
else
{
return "?";
}
}
/**
* Provide a textual report on the profile.
* @return the formatted profile report
*/
public String list()
{
StringBuffer buffer = new StringBuffer();
buffer.append( "PROFILE REPORT\n" );
buffer.append( "\n name: " + getName() );
buffer.append( "\n base: " + getType().getInfo().getName() );
buffer.append( "\n key: " + getType().getInfo().getImplementationKey() );
buffer.append( "\n context: " + getContext( ) );
buffer.append( "\n configuration:" );
if( getConfiguration() != null )
{
buffer.append( ConfigurationUtil.list( getConfiguration() ) );
}
else
{
buffer.append( " null" );
}
buffer.append( "\n parameters: " + getParameters() );
buffer.append( "\n dependecies" );
Association[] dependencies = getAssociations();
if( dependencies.length == 0 )
{
buffer.append( " (none)\n\n" );
return buffer.toString();
}
for( int i=0; i<dependencies.length; i++ )
{
buffer.append( "\n dependency " + i );
buffer.append( "\n role: " + dependencies[i].getRole() );
buffer.append( "\n provider: " + dependencies[i].getProvider() );
}
buffer.append( "\n\n" );
return buffer.toString();
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/DirsetDescriptor.java
Index: DirsetDescriptor.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.meta.data;
/**
* A description of a directory set.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class DirsetDescriptor
{
/**
* The base directory
*/
private final String m_base;
/**
* The set of include directives.
*/
private final IncludeDescriptor[] m_includes;
/**
* Create a FilesetDescriptor instance.
*
* @param filesets the set of filesets to include in the classpath
*/
public DirsetDescriptor( final String base, final IncludeDescriptor[] includes )
{
m_base = base;
m_includes = includes;
}
/**
* Return the base directory.
*
* @return the directory
*/
public String getBaseDirectory()
{
return m_base;
}
/**
* Return the filesets held within the classpath descriptor.
*
* @return the filesets
*/
public IncludeDescriptor[] getIncludeDescriptors()
{
return m_includes;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/ExtensionsDescriptor.java
Index: ExtensionsDescriptor.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.meta.data;
/**
* An extensions descriptor.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class ExtensionsDescriptor
{
/**
* The base directory
*/
private final DirsetDescriptor[] m_dirs;
/**
* Create a ExtensionsDescriptor instance.
*
* @param filesets the set of filesets to include in the classpath
*/
public ExtensionsDescriptor( final DirsetDescriptor[] dirs )
{
m_dirs = dirs;
}
/**
* Return the dirset held within the extensions descriptor.
*
* @return the directory set
*/
public DirsetDescriptor[] getDirsetDescriptors()
{
return m_dirs;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/FileTargetProvider.java
Index: FileTargetProvider.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.meta.data;
/**
* File target provider type.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class FileTargetProvider extends TargetProvider
{
private final String m_location;
public FileTargetProvider( final String location )
{
m_location = location;
}
public String getLocation()
{
return m_location;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/FilesetDescriptor.java
Index: FilesetDescriptor.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.meta.data;
/**
* A fileset descriptor.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class FilesetDescriptor
{
/**
* The base directory
*/
private final String m_base;
/**
* The set of include directives.
*/
private final IncludeDescriptor[] m_includes;
/**
* Create a FilesetDescriptor instance.
*
* @param filesets the set of filesets to include in the classpath
*/
public FilesetDescriptor( final String base, final IncludeDescriptor[] includes )
{
m_base = base;
m_includes = includes;
}
/**
* Return the base directory.
*
* @return the directory
*/
public String getBaseDirectory()
{
return m_base;
}
/**
* Return the filesets held within the classpath descriptor.
*
* @return the filesets
*/
public IncludeDescriptor[] getIncludeDescriptors()
{
return m_includes;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/IncludeDescriptor.java
Index: IncludeDescriptor.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.meta.data;
/**
* An file include directive.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class IncludeDescriptor
{
/**
* The base directory
*/
private final String m_file;
/**
* Create a FilesetDescriptor instance.
*
* @param filesets the set of filesets to include in the classpath
*/
public IncludeDescriptor( final String file )
{
m_file = file;
}
/**
* Return the included filename.
*
* @return the file
*/
public String getFile()
{
return m_file;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/KernelDescriptor.java
Index: KernelDescriptor.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.meta.data;
/**
* Kernel creation profile.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public class KernelDescriptor implements AbstractContainer
{
/**
* The kernel name
*/
private final String m_name;
/**
* The logging defintion.
*/
private final LoggingDescriptor m_logging;
/**
* The extensions defintion.
*/
private final ExtensionsDescriptor m_extensions;
/**
* The root container.
*/
private ClasspathDescriptor m_classpath;
/**
* The root container.
*/
private ContainerDescriptor m_container;
/**
* Create a KernelDescriptor instance.
*
*/
public KernelDescriptor( final String name,
final LoggingDescriptor logging,
final ExtensionsDescriptor extensions,
final ContainerDescriptor container )
{
if( name == null )
throw new NullPointerException("name");
if( logging == null )
throw new NullPointerException("logging");
if( extensions == null )
throw new NullPointerException("extensions");
m_name = name;
m_logging = logging;
m_extensions = extensions;
m_container = container;
}
/**
* Return the container name.
*
* @return the name of the container
*/
public String getName()
{
return m_name;
}
/**
* Return the logging descriptor.
*
* @return the {@link LoggingDescriptor} for the component loggers.
*/
public LoggingDescriptor getLoggingDescriptor()
{
return m_logging;
}
/**
* Return the root logging descriptor.
*
* @return the {@link CategoryDescriptor} for the component loggers.
*/
public CategoryDescriptor getCategoryDescriptor()
{
return getLoggingDescriptor().getCategoryDescriptor();
}
/**
* Return the classpath descriptor.
*
* @return the {@link ClasspathDescriptor} for the container.
*/
public ExtensionsDescriptor getExtensionsDescriptor()
{
return m_extensions;
}
/**
* Return the classpath descriptor.
*
* @return the {@link ClasspathDescriptor} for the container.
*/
public ClasspathDescriptor getClasspathDescriptor()
{
return m_classpath;
}
/**
* Sets the root container for the kernel.
*
* @param root the root {@link ContainerDescriptor} of the container hierachy.
*/
//public void setContainerDescriptor( ContainerDescriptor container )
//{
// if( container == null )
// throw new NullPointerException("container");
// m_container = container;
// container.setParent( this );
//}
/**
* Return the root container.
*
* @return the root {@link ContainerDescriptor}.
*/
public ContainerDescriptor getContainerDescriptor()
{
return m_container;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/LoggingDescriptor.java
Index: LoggingDescriptor.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.meta.data;
/**
* Description of a top level logging environment.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public final class LoggingDescriptor
{
/**
* The root category hierachy.
*/
private CategoryDescriptor m_category;
/**
* The defaulr priority.
*/
private String m_priority;
/**
* The default target.
*/
private String m_target;
/**
* The dependencies keyed by role name.
*/
private final TargetDescriptor[] m_targets;
/**
* Create a LoggingDescriptor instance.
*/
public LoggingDescriptor( final String priority,
final String target,
final TargetDescriptor[] targets,
final CategoryDescriptor category )
{
m_targets = targets;
m_priority = priority;
m_target = target;
m_category = category;
}
/**
* Return the default logging priority for the group of categories.
*
* @return the default logging priority
*/
public String getPriority( )
{
return m_priority;
}
/**
* Return the default log target for the group of categories.
*
* @return the default target name
*/
public String getTarget( )
{
return m_target;
}
/**
* Return the set of logging target descriptors.
*
* @return the target descriptors
*/
public TargetDescriptor[] getTargetDescriptors()
{
return m_targets;
}
/**
* Return the root catagory descriptor.
*
* @return the target descriptors
*/
public CategoryDescriptor getCategoryDescriptor()
{
return m_category;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/Profile.java
Index: Profile.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.meta.data;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.context.Context;
import org.apache.excalibur.meta.info.Type;
/**
* Each component declared in the application is represented by
* a Profile. Note that this does not necessarily imply
* that there is only one instance of actual component. The
* ComponentProfile could represent a pool of components, a single
* component or a component prototype that is reused to create
* new components as needed.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public interface Profile
{
static final int IMPLICIT = 0;
static final int PACKAGED = 1;
static final int EXPLICIT = 2;
/**
* Return the name of component metadata instance.
*
* @return the name of the component.
*/
String getName();
/**
* Return the info for component.
*
* @return the info for component type.
*/
Type getType();
/**
* Return the Parameters for component (if any).
*
* @return the Parameters for Component (if any).
*/
Parameters getParameters();
/**
* Return the Configuration for component(if any).
*
* @return the Configuration for component
*/
Configuration getConfiguration();
/**
* Return the Context for component (if any).
*
* @return the Context for component
*/
Context getContext();
/**
* Return the logging descriptor.
*
* @return the {@link CategoryDescriptor} for the component loggers.
*/
public CategoryDescriptor getCategoryDescriptor();
/**
* Return the assigned service providers.
*
* @return the dependency metadata for component.
*/
Association[] getAssociations();
/**
* Return the Association for specified role.
*
* @return the Association for specified role.
*/
Association getAssociation( final String role );
/**
* Returns the creation mode for this profile.
* @return a value of EXPLICIT, PACKAGED or IMPLICIT
*/
int getMode();
/**
* Add a provider for a service dependency role.
* @param provider the compenont provider profile
* @param role the dependent role
*/
void addProvider( Profile provider, String role );
/**
* Provide a textual report on the profile.
* @return the formatted profile report
*/
String list();
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/TargetDescriptor.java
Index: TargetDescriptor.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.meta.data;
/**
* A logging target descriptor.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public final class TargetDescriptor
{
/**
* The target name.
*/
private final String m_name;
/**
* The target provider descriptor.
*/
private final TargetProvider m_provider;
/**
* Create a LoggingDescriptor instance.
*
* @param name the abstract name of component meta data instance
* @param dependencies the meta data for any dependencies
* @param type the component type
*/
public TargetDescriptor( final String name,
final TargetProvider provider )
{
m_name = name;
m_provider = provider;
}
/**
* Return the target name.
*
* @return the target name.
*/
public String getName()
{
return m_name;
}
/**
* Return the target provider descriptor
*
* @return the provider descriptor
*/
public TargetProvider getProvider()
{
return m_provider;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/TargetProvider.java
Index: TargetProvider.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.meta.data;
/**
* Abstract logging target provider type.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
*/
public abstract class TargetProvider
{
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/package.html
Index: package.html
===================================================================
<body>
<p>
Profile is the assembly of object instances that collectively defines a potential instantiation state for the type including information about the references to provider components capable of servicing declared dependecies, together with logging, configuration, parameterization, and contextualization state.
</p>
</body>
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/ContainerCreator.java
Index: ContainerCreator.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.meta.data.builder;
import org.apache.excalibur.merlin.meta.data.ContainerDescriptor;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.excalibur.merlin.meta.data.builder.TypeManager;
/**
* Simple interface used to create {@link ContainerDescriptor}
* from a Configuration sorce.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public interface ContainerCreator
{
/**
* Create a {@link Profile} from configuration
*
* @param config the confiugration source
* @return the newly created {@link ContainerDescriptor}
* @throws Exception
*/
ContainerDescriptor createContainerDescriptor( Configuration config, TypeManager manager )
throws Exception;
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/KernelCreator.java
Index: KernelCreator.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.meta.data.builder;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.excalibur.merlin.meta.data.KernelDescriptor;
import org.apache.excalibur.merlin.meta.data.builder.TypeManager;
/**
* Simple interface used to create {@link ContainerDescriptor}
* from a Configuration sorce.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public interface KernelCreator
{
/**
* Create a {@link KernelDescriptor} from configuration
*
* @param config the confiugration source
* @return the newly created {@link ContainerDescriptor}
* @throws Exception
*/
KernelDescriptor createKernelDescriptor( Configuration config, TypeManager manager )
throws Exception;
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/ProfileBuilder.java
Index: ProfileBuilder.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.meta.data.builder;
import java.io.InputStream;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.builder.TypeBuilder;
import org.apache.excalibur.merlin.meta.data.Profile;
/**
* A ProfileBuilder is responsible for building {@link Profile}
* objects from Configuration objects.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public final class ProfileBuilder
{
private static final Resources REZ =
ResourceManager.getPackageResources( TypeBuilder.class );
private final ProfileCreator m_xmlProfileCreator = createXMLProfileCreator();
/**
* Build Profile from the XML descriptor format.
*
* @param classname The classname of Component
* @param classLoader the ClassLoader to load info from
* @return the created Type
* @throws Exception if an error occurs
*/
public Profile[] build( Type type, final ClassLoader classLoader )
throws Exception
{
final String xprofile =
type.getInfo().getImplementationKey().replace( '.', '/' ) + ".xprofile";
final InputStream inputStream =
classLoader.getResourceAsStream( xprofile );
final ProfileCreator creator = getXMLProfileCreator( xprofile );
if( null == inputStream )
{
return creator.createProfiles( type, new DefaultConfiguration("profiles", null ) );
}
else
{
return creator.createProfiles( type, inputStream );
}
}
public Profile build( Type type, Configuration profile )
throws Exception
{
final ProfileCreator creator = getXMLProfileCreator( "implicit" );
return creator.createProfile( type, profile );
}
/**
* Utility to get xml info builder, else throw
* an exception if missing descriptor.
*
* @return the TypeCreator
*/
private ProfileCreator getXMLProfileCreator( final String classname )
throws Exception
{
if( null != m_xmlProfileCreator )
{
return m_xmlProfileCreator;
}
else
{
final String message =
REZ.getString( "builder.missing-xml-creator.error",
classname );
throw new Exception( message );
}
}
/**
* Utility to get XMLProfileCreator if XML files are on
* ClassPath.
*
* @return the XML {@link TypeCreator}
*/
private static ProfileCreator createXMLProfileCreator()
{
ProfileCreator xmlProfileCreator = null;
try
{
xmlProfileCreator = new XMLProfileCreator();
}
catch( final Exception e )
{
//Ignore it if ClassNot found due to no
//XML Classes on classpath
}
return xmlProfileCreator;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/ProfileCreator.java
Index: ProfileCreator.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.meta.data.builder;
import java.io.InputStream;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.merlin.meta.data.Profile;
/**
* Simple interface used to create {@link Profile}
* from stream or Configuration sorce.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public interface ProfileCreator
{
/**
* Create a {@link Profile} from stream
*
* @param key the name of component type that we are looking up
* @param inputStream the stream that the resource is loaded from
* @return the newly created {@link Type}
* @throws Exception
*/
Profile[] createProfiles( Type type, InputStream inputStream )
throws Exception;
/**
* Create a {@link Profile} from a configuration
*
* @param key the name of component type that we are looking up
* @param inputStream the stream that the resource is loaded from
* @return the newly created {@link Type}
* @throws Exception
*/
Profile[] createProfiles( Type type, Configuration config )
throws Exception;
Profile createProfile( Type type, Configuration config )
throws Exception;
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/Resources.properties
Index: Resources.properties
===================================================================
builder.redundent-role.notice=Warning: Type for class {0} redundently specifies role name "{1}" in dependency when it is identical to the name of service. It is recomended that the <role/> section be elided.
builder.creating-info.notice=Creating a Type for class "{0}".
builder.created-info.notice=Constructed Type object for class {0}. ComponentInfo contains {1} services, {2} dependencies, {3} context entrys and {4} loggers.
builder.bad-toplevel-element.error=Error the component implemented by "{0}" has an invalid element at top level of component info descriptor. Expected: "component-info". Actual: "{1}"
builder.missing-info.error=Unable to locate resource from which to load info for component implemented by class "{0}".
builder.missing-xml-creator.error=Unable to create XMLTypeCreator, usually due to not having XML classes on Classpath. Thus unable to lookup XML descriptor for component type "{0}".
builder.creating-profile.notice=Creating Profiles for class "{0}".
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/TypeManager.java
Index: TypeManager.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.meta.data.builder;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.ServiceDesignator;
import org.apache.excalibur.merlin.meta.data.ClasspathDescriptor;
/**
* Interface implemented by resources capable a resolving a Type form a classname.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public interface TypeManager
{
/**
* Add classes to the manager declared within a classpath structure.
* @param classpath the classpath descriptor
* @exception Exception if an exception occurs during class loading
*/
void addClasspath( ClasspathDescriptor classpath ) throws Exception;
/**
* Resolve a {@link Type} from a classname.
*
* @param classname the component type
* @return the component type
*/
Type lookup( String classname ) throws Exception;
/**
* Register a potential supplier component type. The implementation will
* create a component type instance for the entry if not already known and
* return the existing or new instance to the invoking client.
*
* @param classname the component class name
* @return the component type
*/
Type register( String classname ) throws Exception;
/**
* Returns the set of component types know to the registry.
* @return the set of component types registered with the registry
*/
Type[] getTypes();
/**
* Returns the set of component types know to the registry that are capable of
* supporting the supplied service.
* @return the set of candidate component types
*/
Type[] getTypes( ServiceDesignator service );
/**
* Returns a registered component type.
* @return the component type from the registry or null if the type is unknown
*/
Type getType( String classname );
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/XMLContainerCreator.java
Index: XMLContainerCreator.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.meta.data.builder;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.configuration.ContextFactory;
import org.apache.excalibur.merlin.meta.data.Profile;
import org.apache.excalibur.merlin.meta.data.DefaultProfile;
import org.apache.excalibur.merlin.meta.data.CategoryDescriptor;
import org.apache.excalibur.merlin.meta.data.IncludeDescriptor ;
import org.apache.excalibur.merlin.meta.data.FilesetDescriptor;
import org.apache.excalibur.merlin.meta.data.ClasspathDescriptor;
import org.apache.excalibur.merlin.meta.data.ContainerDescriptor;
import org.apache.excalibur.merlin.meta.data.ComponentDescriptor;
import org.apache.excalibur.merlin.meta.data.builder.TypeManager;
/**
* Handles internalization of an XML based description of a {@link Profile}
* from a Configuration object. The format for Configuration object
* is specified in the <a href="package-summary.html#external">package summary</a>.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public class XMLContainerCreator extends XMLProfileCreator
implements ContainerCreator
{
private static final Resources REZ =
ResourceManager.getPackageResources( XMLContainerCreator.class );
public ContainerDescriptor[] createContainerDescriptors( Configuration[] configs, TypeManager manager )
throws Exception
{
ArrayList list = new ArrayList();
for( int i=0; i<configs.length; i++ )
{
Configuration config = configs[i];
list.add( createContainerDescriptor( config, manager ) );
}
return (ContainerDescriptor[]) list.toArray( new ContainerDescriptor[0] );
}
/**
* Create a {@link ContainerDescriptor} from configuration
*
* @param config the confiugration source
* @return the newly created {@link ContainerDescriptor}
* @throws Exception
*/
public ContainerDescriptor createContainerDescriptor( Configuration config, TypeManager manager )
throws Exception
{
final String name = config.getAttribute("name");
CategoryDescriptor loggers = createCategoryDescriptor( config.getChild("loggers"), name );
ClasspathDescriptor classpath = createClasspathDescriptor( config.getChild("classpath") );
manager.addClasspath( classpath );
ComponentDescriptor[] components = createComponentDescriptors(
manager, config.getChildren("component") );
ContainerDescriptor[] containers = createContainerDescriptors(
config.getChildren("container"), manager );
return new ContainerDescriptor( name, loggers, classpath, components, containers );
}
public ComponentDescriptor[] createComponentDescriptors( TypeManager manager, Configuration[] configs )
throws Exception
{
ArrayList list = new ArrayList();
for( int i=0; i<configs.length; i++ )
{
Configuration config = configs[i];
Type type = manager.lookup( config.getAttribute("class") );
list.add( super.createProfile( type, config ) );
}
return (ComponentDescriptor[]) list.toArray( new ComponentDescriptor[0] );
}
public ClasspathDescriptor createClasspathDescriptor( Configuration config )
throws ConfigurationException
{
ArrayList list = new ArrayList();
Configuration[] configs = config.getChildren("fileset");
for( int i=0; i<configs.length; i++ )
{
Configuration c = configs[i];
list.add( createFilesetDescriptor( c ) );
}
FilesetDescriptor[] filesets = (FilesetDescriptor[]) list.toArray( new FilesetDescriptor[0] );
return new ClasspathDescriptor( filesets );
}
public FilesetDescriptor createFilesetDescriptor( Configuration config )
throws ConfigurationException
{
String base = config.getAttribute("dir");
ArrayList list = new ArrayList();
Configuration[] includeConfigs = config.getChildren("include");
for( int i=0; i<includeConfigs.length; i++ )
{
Configuration includeConfig = includeConfigs[i];
list.add( createIncludeDescriptor( includeConfig ) );
}
IncludeDescriptor[] includes = (IncludeDescriptor[]) list.toArray( new IncludeDescriptor[0] );
return new FilesetDescriptor( base, includes );
}
public IncludeDescriptor createIncludeDescriptor( Configuration config )
throws ConfigurationException
{
String filename = config.getAttribute("name");
return new IncludeDescriptor( filename );
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/XMLKernelCreator.java
Index: XMLKernelCreator.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.meta.data.builder;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.merlin.meta.data.Profile;
import org.apache.excalibur.merlin.meta.data.DefaultProfile;
import org.apache.excalibur.merlin.meta.data.CategoryDescriptor;
import org.apache.excalibur.merlin.meta.data.IncludeDescriptor ;
import org.apache.excalibur.merlin.meta.data.FilesetDescriptor;
import org.apache.excalibur.merlin.meta.data.ClasspathDescriptor;
import org.apache.excalibur.merlin.meta.data.ContainerDescriptor;
import org.apache.excalibur.merlin.meta.data.ComponentDescriptor;
import org.apache.excalibur.merlin.meta.data.DirsetDescriptor;
import org.apache.excalibur.merlin.meta.data.ExtensionsDescriptor;
import org.apache.excalibur.merlin.meta.data.KernelDescriptor;
import org.apache.excalibur.merlin.meta.data.TargetDescriptor;
import org.apache.excalibur.merlin.meta.data.FileTargetProvider;
import org.apache.excalibur.merlin.meta.data.TargetProvider;
import org.apache.excalibur.merlin.meta.data.LoggingDescriptor;
import org.apache.excalibur.merlin.meta.data.builder.TypeManager;
/**
* Handles internalization of an XML based description of a {@link Profile}
* from a Configuration object. The format for Configuration object
* is specified in the <a href="package-summary.html#external">package summary</a>.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public final class XMLKernelCreator extends XMLContainerCreator
implements KernelCreator
{
private static final Resources REZ =
ResourceManager.getPackageResources( XMLKernelCreator.class );
/**
* Create a {@link KernelDescriptor} from configuration
*
* @param config the confiugration source
* @return the newly created {@link ContainerDescriptor}
* @throws Exception
*/
public KernelDescriptor createKernelDescriptor( Configuration config, TypeManager manager )
throws Exception
{
final String name = config.getName();
LoggingDescriptor logging = createLoggingDescriptor( config.getChild("logging"), name );
ExtensionsDescriptor extensions = createExtensionsDescriptor( config.getChild("extensions") );
ClasspathDescriptor classpath = createClasspathDescriptor( config.getChild("classpath") );
ContainerDescriptor container = createContainerDescriptor( config.getChild("container"), manager );
return new KernelDescriptor( name, logging, extensions, container );
}
public LoggingDescriptor createLoggingDescriptor( Configuration config, String name )
throws ConfigurationException
{
final String target = config.getAttribute(
"target", CategoryDescriptor.DEFAULT_LOGGING_TARGET );
final String priority = config.getAttribute( "priority", null );
ArrayList list = new ArrayList();
Configuration[] configs = config.getChildren("target");
for( int i=0; i<configs.length; i++ )
{
Configuration c = configs[i];
list.add( createTargetDescriptor( c ) );
}
TargetDescriptor[] targets = (TargetDescriptor[]) list.toArray( new TargetDescriptor[0] );
CategoryDescriptor loggers = super.createCategoryDescriptor( config.getChild("loggers"), name );
return new LoggingDescriptor( priority, target, targets, loggers );
}
public TargetDescriptor createTargetDescriptor( Configuration config )
throws ConfigurationException
{
final String name = config.getAttribute("name");
if( config.getChildren().length == 0 )
throw new ConfigurationException(
"missing target provider elememt in '" + config.getName() + "'.");
final Configuration c = config.getChildren()[0];
TargetProvider provider = null;
if( c.getName().equals("file") )
{
provider = createFileTargetProvider( c );
}
else
{
throw new ConfigurationException(
"Unrecognized provider: " + c.getName() + " in " + config.getName() );
}
return new TargetDescriptor( name, provider );
}
public FileTargetProvider createFileTargetProvider( Configuration config )
throws ConfigurationException
{
String file = config.getAttribute("location");
return new FileTargetProvider( file );
}
public ExtensionsDescriptor createExtensionsDescriptor( Configuration config )
throws ConfigurationException
{
ArrayList list = new ArrayList();
Configuration[] configs = config.getChildren("dirset");
for( int i=0; i<configs.length; i++ )
{
Configuration c = configs[i];
list.add( createDirsetDescriptor( c ) );
}
DirsetDescriptor[] dirs = (DirsetDescriptor[]) list.toArray( new DirsetDescriptor[0] );
return new ExtensionsDescriptor( dirs );
}
public DirsetDescriptor createDirsetDescriptor( Configuration config )
throws ConfigurationException
{
String base = config.getAttribute("dir");
ArrayList list = new ArrayList();
Configuration[] includeConfigs = config.getChildren("include");
for( int i=0; i<includeConfigs.length; i++ )
{
Configuration includeConfig = includeConfigs[i];
list.add( createIncludeDescriptor( includeConfig ) );
}
IncludeDescriptor[] includes = (IncludeDescriptor[]) list.toArray( new IncludeDescriptor[0] );
return new DirsetDescriptor( base, includes );
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/XMLProfileCreator.java
Index: XMLProfileCreator.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.meta.data.builder;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.builder.XMLTypeCreator;
import org.apache.excalibur.meta.ConfigurationBuilder;
import org.apache.excalibur.merlin.meta.data.Profile;
import org.apache.excalibur.merlin.meta.data.DefaultProfile;
import org.apache.excalibur.merlin.meta.data.CategoryDescriptor;
import org.apache.excalibur.merlin.meta.data.ComponentDescriptor;
import org.apache.excalibur.configuration.ContextFactory;
import org.xml.sax.InputSource;
/**
* Handles internalization of an XML based description of a {@link Profile}
* from a Configuration object. The format for Configuration object
* is specified in the <a href="package-summary.html#external">package summary</a>.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public class XMLProfileCreator
implements ProfileCreator
{
private static final Resources REZ =
ResourceManager.getPackageResources( XMLTypeCreator.class );
/**
* Create a {@link Type} object for specified
* classname, loaded from specified {@link InputStream}.
*
* @param implementationKey The classname of Component
* @param inputStream the InputStream to load Type from
* @return the created Type
* @throws ConfigurationException if an error occurs
*/
public Profile[] createProfiles( Type type, InputStream inputStream )
throws Exception
{
final InputSource input = new InputSource( inputStream );
final Configuration configuration = ConfigurationBuilder.build( input );
return createProfiles( type, configuration );
}
/**
* Create a {@link Profile} object for specified classname from
* specified configuration data associated with a single type.
*
* @param classname The classname of Component
* @param info the Type configuration
* @return the created Type
* @throws ConfigurationException if an error occurs
*/
public Profile[] createProfiles( Type type, final Configuration info )
throws Exception
{
Vector vector = new Vector();
Configuration[] profiles = info.getChildren("component");
if( profiles.length == 0 )
{
//
// build a default profile
//
CategoryDescriptor loggers = new CategoryDescriptor(
type.getInfo().getName(), null, null );
return new Profile[]{
new ComponentDescriptor( null, null, null, null, loggers, type, Profile.IMPLICIT ) };
}
for( int i=0; i<profiles.length; i++ )
{
vector.add( buildProfile( type, profiles[i], Profile.PACKAGED ) );
}
return (Profile[]) vector.toArray( new Profile[0] );
}
public Profile createProfile( Type type, Configuration config )
throws Exception
{
return buildProfile( type, config, Profile.EXPLICIT );
}
private Profile buildProfile( Type type, Configuration profile, int mode ) throws Exception
{
String name = null;
if( mode == Profile.EXPLICIT )
{
name = profile.getAttribute("name");
}
Parameters params = Parameters.fromConfiguration( profile.getChild("parameters") );
Configuration config = profile.getChild("configuration");
Configuration loggersConfig = profile.getChild("loggers");
CategoryDescriptor loggers = createCategoryDescriptor( loggersConfig, name );
Context context = ContextFactory.createContextFromConfiguration(
null, profile.getChild("context") );
return new ComponentDescriptor( name, params, config, context, loggers, type, mode );
}
public CategoryDescriptor createCategoryDescriptor( Configuration config, String fallback )
throws ConfigurationException
{
final String name = config.getAttribute( "name", fallback );
final String priority = config.getAttribute( "priority", null );
final String target = config.getAttribute( "target", null );
CategoryDescriptor[] categories = createCategoryDescriptors( config );
return new CategoryDescriptor( name, priority, target, categories );
}
private CategoryDescriptor[] createCategoryDescriptors( Configuration config )
throws ConfigurationException
{
ArrayList list = new ArrayList();
Configuration[] categories = config.getChildren( "category" );
for( int i=0; i<categories.length; i++ )
{
CategoryDescriptor category = createCategoryDescriptor( categories[i], null );
list.add( category );
}
return (CategoryDescriptor[]) list.toArray( new CategoryDescriptor[0] );
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/package.html
Index: package.html
===================================================================
<html><body>
<p>Component meta data information builders that handle internalization of an component profile descriptions supplied as a configuration instance.</P>
</body></html>
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/LifecycleException.java
Index: LifecycleException.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.meta.data.lifecycle;
import org.apache.avalon.framework.CascadingException;
import org.apache.excalibur.meta.verifier.VerifyException;
/**
* Exception to indicate error processing a component through its lifecycle.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public final class LifecycleException
extends CascadingException
{
/**
* Construct a new <code>VerifyException</code> instance.
*
* @param message The detail message for this exception.
*/
public LifecycleException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>VerifyException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public LifecycleException( final String message, final Throwable throwable )
{
super( message, throwable );
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/LifecycleHelper.java
Index: LifecycleHelper.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.meta.data.lifecycle;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.parameters.Parameterizable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.excalibur.merlin.meta.data.Profile;
/**
* This is a class to help an Application manage the lifecycle of a component.
* The implementation provides support for the processing of a component through
* each lifecycle stage, and manage errors in a consistent way.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
*/
public class LifecycleHelper
extends AbstractLogEnabled
{
private static final Resources REZ =
ResourceManager.getPackageResources( LifecycleHelper.class );
//Constants to designate stages
private static final int STAGE_CREATE = 0;
private static final int STAGE_LOGGER = 1;
private static final int STAGE_CONTEXT = 2;
private static final int STAGE_COMPOSE = 3;
private static final int STAGE_CONFIG = 4;
private static final int STAGE_PARAMETER = 5;
private static final int STAGE_INIT = 6;
private static final int STAGE_START = 7;
private static final int STAGE_STOP = 8;
private static final int STAGE_DISPOSE = 9;
private static final int STAGE_DESTROY = 10;
/**
* Method to run a component through it's startup phase.
* Errors that occur during startup will be logged appropriately and
* cause exceptions with useful messages to be raised.
*
* @param name the name of the component
* @param profile representing the instance criteria
* @param provider the resource provider
* @throws LifecycleException if an error occurs when the component passes
* through a specific lifecycle stage
*/
public Object startup( final String name,
final Profile profile,
final ResourceProvider provider )
throws LifecycleException
{
int stage = 0;
try
{
//Creation stage
stage = STAGE_CREATE;
notice( name, stage );
final Object object = provider.createObject( profile );
//LogEnabled stage
stage = STAGE_LOGGER;
if( object instanceof LogEnabled )
{
notice( name, stage );
final Logger logger = provider.createLogger( profile );
ContainerUtil.enableLogging( object, logger );
}
//Contextualize stage
stage = STAGE_CONTEXT;
if( object instanceof Contextualizable )
{
notice( name, stage );
final Context context = provider.createContext( profile );
ContainerUtil.contextualize( object, context );
}
//Composition stage
stage = STAGE_COMPOSE;
if( object instanceof Serviceable )
{
notice( name, stage );
final ServiceManager manager =
provider.createServiceManager( profile);
ContainerUtil.service( object, manager );
}
else if( object instanceof Composable )
{
notice( name, stage );
final ComponentManager componentManager =
provider.createComponentManager( profile );
ContainerUtil.compose( object, componentManager );
}
//Configuring stage
stage = STAGE_CONFIG;
if( object instanceof Configurable )
{
notice( name, stage );
final Configuration configuration =
provider.createConfiguration( profile );
ContainerUtil.configure( object, configuration );
}
//Parameterizing stage
stage = STAGE_PARAMETER;
if( object instanceof Parameterizable )
{
notice( name, stage );
final Parameters parameters =
provider.createParameters( profile );
ContainerUtil.parameterize( object, parameters );
}
//Initialize stage
stage = STAGE_INIT;
if( object instanceof Initializable )
{
notice( name, stage );
ContainerUtil.initialize( object );
}
//Start stage
stage = STAGE_START;
if( object instanceof Startable )
{
notice( name, stage );
ContainerUtil.start( object );
}
return object;
}
catch( final Throwable t )
{
fail( name, stage, t );
//fail() throws an exception so next
//line will never be executed
return null;
}
}
/**
* Method to run a component through it's shutdown phase.
* Errors that occur during shutdown will be logged appropraitely.
*
* @param name the name of the component
* @param object the component to shutdown
*/
public void shutdown( final String name,
final Object object )
throws LifecycleException
{
//Stage at which failure occured
int stage = 0;
//Failure exception
Throwable failure = null;
//Stoppable stage
if( object instanceof Startable )
{
notice( name, STAGE_STOP );
try
{
ContainerUtil.stop( object );
}
catch( final Throwable t )
{
safeFail( name, STAGE_STOP, t );
failure = t;
stage = STAGE_STOP;
}
}
//Disposable stage
if( object instanceof Disposable )
{
notice( name, STAGE_DISPOSE );
try
{
ContainerUtil.dispose( object );
}
catch( final Throwable t )
{
safeFail( name, STAGE_DISPOSE, t );
failure = t;
stage = STAGE_DISPOSE;
}
}
notice( name, STAGE_DESTROY );
if( null != failure )
{
fail( name, stage, failure );
}
}
/**
* Utility method to report that a lifecycle stage is about to be processed.
*
* @param name the name of component that is the subject of the notice
* @param stage the lifecycle processing stage
*/
private void notice( final String name, final int stage )
{
if( getLogger().isDebugEnabled() )
{
final String message =
REZ.getString( "lifecycle.stage.notice",
name,
new Integer( stage ) );
getLogger().debug( message );
}
}
/**
* Utility method to report that there was an error processing
* specified lifecycle stage.
*
* @param name the name of component that caused failure
* @param stage the lefecycle stage
* @param t the exception thrown
*/
private void safeFail( final String name,
final int stage,
final Throwable t )
{
//final String reason = t.getMessage();
final String reason = t.toString();
final String message =
REZ.getString( "lifecycle.fail.error",
name,
new Integer( stage ),
reason );
getLogger().error( message );
}
/**
* Utility method to report that there was an error processing
* specified lifecycle stage. It will also re-throw an exception
* with a better error message.
*
* @param name the name of block that caused failure
* @param stage the stage
* @param t the exception thrown
* @throws LifecycleException containing error
*/
private void fail( final String name,
final int stage,
final Throwable t )
throws LifecycleException
{
//final String reason = t.getMessage();
final String reason = t.toString();
final String message =
REZ.getString( "lifecycle.fail.error",
name,
new Integer( stage ), reason );
getLogger().error( message );
throw new LifecycleException( message, t );
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/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.meta.data.lifecycle;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.excalibur.merlin.meta.data.Profile;
/**
* The interface via which resources required for a component
* are aquired based on a supplied {@link Profile}.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public interface ResourceProvider
{
/**
* Create an object specified by profile.
*
* @param profile the profile
* @return the new object
* @throws Exception if unable to create resource
*/
Object createObject( Profile profile )
throws Exception;
/**
* Create a new Logger for component.
*
* @param profile the profile
* @return a new Logger for component
* @throws Exception if unable to create resource
*/
Logger createLogger( Profile profile )
throws Exception;
/**
* Create a new Context for component.
*
* @param profile the profile
* @return a new Context for component
* @throws Exception if unable to create resource
*/
Context createContext( Profile profile )
throws Exception;
/**
* Create a new ComponentManager for component.
*
* @param profile the profile
* @return a new ComponentManager for component
* @throws Exception if unable to create resource
*/
ComponentManager createComponentManager( Profile profile )
throws Exception;
/**
* Create a new ServiceManager for component.
*
* @param profile the profile
* @return a new ServiceManager for component
* @throws Exception if unable to create resource
*/
ServiceManager createServiceManager( Profile profile )
throws Exception;
/**
* Create a new Configuration object for component.
*
* @param profile the profile
* @return a new Configuration object for component
* @throws Exception if unable to create resource
*/
Configuration createConfiguration( Profile profile )
throws Exception;
/**
* Create a new Parameters object for component.
*
* @param profile the profile
* @return a new Parameters object for component
* @throws Exception if unable to create resource
*/
Parameters createParameters( Profile profile )
throws Exception;
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/Resources.properties
Index: Resources.properties
===================================================================
lifecycle.stage.notice=Component named "{0}" is passing through the {1,choice,0#Creation|1#Logger initialization|2#Contextualization|3#Composing|4#Configuration|5#Parameterizing|6#Initialization|7#Starting|8#Stopping|9#Disposing|10#Destruction} stage.
lifecycle.fail.error=Component named "{0}" failed to pass through the {1,choice,0#Creation|1#Logger initialization|2#Contextualization|3#Composing|4#Configuration|5#Parameterizing|6#Initialization|7#Starting|8#Stopping|9#Disposing|10#Destruction} stage. (Reason: {2}).
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/package.html
Index: package.html
===================================================================
<body>
Helpers classes and interfaces supporting the declaration of a resource provider to a component during lifecycle processing.
<h3>Package Structure (UML)</h3>
<p><img src=doc-files/lifecycle.gif border=0></p>
</body>
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier/AssemblyVerifier.java
Index: AssemblyVerifier.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.meta.data.verifier;
import java.util.ArrayList;
import java.util.Stack;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.verifier.VerifyException;
import org.apache.excalibur.meta.info.DependencyDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.ServiceDesignator;
import org.apache.excalibur.merlin.meta.data.Profile;
import org.apache.excalibur.merlin.meta.data.Association;
/**
* This Class verifies that a set of profiles are valid. It performs a number
* of checks to make sure that the profile set represents a valid
* application and excluding runtime errors will start up normally.
* Some of the checks performed include;
*
* <ul>
* <li>Verify names of Components contain only
* letters, digits or the '_' character.</li>
* <li>Verify that the names of the Components are unique to the
* Assembly.</li>
* <li>Verify that the specified dependeny mapping correspond to
* dependencies specified in Type files.</li>
* <li>Verify that the inter-Component dependendencies are valid.
* This essentially means that if Component A requires Service S
* from Component B then Component B must provide Service S.</li>
* <li>Verify that there are no circular dependendencies between
* components.</li>
* <li>Verify that the Class objects for Component implement the
* service interfaces.</li>
* <li>Verify that the Class is a valid Avalon Component as per the
* rules in {@link ComponentVerifier} object.</li>
* </ul>
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public class AssemblyVerifier
extends AbstractLogEnabled
{
private static final Resources REZ =
ResourceManager.getPackageResources( AssemblyVerifier.class );
/**
* Validate and Verify the specified assembly (ie organization
* of components). See the Class Javadocs for the rules and
* regulations of assembly.
*
* @param components the Components that make up assembly
* @throws VerifyException if an error occurs
*/
public void verifyAssembly( final Profile[] components )
throws VerifyException
{
String message = null;
message = REZ.getString( "assembly.valid-names.notice" );
getLogger().debug( message );
verifyValidNames( components );
message = REZ.getString( "assembly.unique-names.notice" );
getLogger().debug( message );
checkNamesUnique( components );
message = REZ.getString( "assembly.dependencies-mapping.notice" );
getLogger().debug( message );
verifyValidDependencies( components );
message = REZ.getString( "assembly.dependency-references.notice" );
getLogger().debug( message );
verifyDependencyReferences( components );
message = REZ.getString( "assembly.nocircular-dependencies.notice" );
getLogger().debug( message );
verifyNoCircularDependencies( components );
}
/**
* Verfiy that all Components have the needed dependencies specified correctly.
*
* @param components the Profile objects for the components
* @throws VerifyException if an error occurs
*/
public void verifyValidDependencies( final Profile[] components )
throws VerifyException
{
for( int i = 0; i < components.length; i++ )
{
verifyDependenciesMap( components[ i ] );
}
}
/**
* Verfiy that there are no circular references between Components.
*
* @param components the Profile objects for the components
* @throws VerifyException if an circular dependency error occurs
*/
protected void verifyNoCircularDependencies( final Profile[] components )
throws VerifyException
{
for( int i = 0; i < components.length; i++ )
{
final Profile component = components[ i ];
final Stack stack = new Stack();
stack.push( component );
verifyNoCircularDependencies( component, components, stack );
stack.pop();
}
}
/**
* Verfiy that there are no circular references between Components.
*
* @param component ???
* @param components the Profile objects for the components
* @param stack the ???
* @throws VerifyException if an error occurs
*/
protected void verifyNoCircularDependencies( final Profile component,
final Profile[] components,
final Stack stack )
throws VerifyException
{
final Profile[] dependencies = getDependencies( component, components );
for( int i = 0; i < dependencies.length; i++ )
{
final Profile dependency = dependencies[ i ];
if( stack.contains( dependency ) )
{
final String trace = getDependencyTrace( dependency, stack );
final String message =
REZ.getString( "assembly.circular-dependency.error",
component.getName(),
trace );
throw new VerifyException( message );
}
stack.push( dependency );
verifyNoCircularDependencies( dependency, components, stack );
stack.pop();
}
}
/**
* Get a string defining path from top of stack till
* it reaches specified component.
*
* @param component the component
* @param stack the Stack
* @return the path of dependency
*/
protected String getDependencyTrace( final Profile component,
final Stack stack )
{
final StringBuffer sb = new StringBuffer();
sb.append( "[ " );
final String name = component.getName();
final int size = stack.size();
final int top = size - 1;
for( int i = top; i >= 0; i-- )
{
final Profile other = (Profile)stack.get( i );
if( top != i )
{
sb.append( ", " );
}
sb.append( other.getName() );
if( other.getName().equals( name ) )
{
break;
}
}
sb.append( ", " );
sb.append( name );
sb.append( " ]" );
return sb.toString();
}
/**
* Get array of dependencies for specified Component from specified
* Component array.
*
* @param component the component to get dependencies of
* @param components the total set of components in application
* @return the dependencies of component
*/
protected Profile[] getDependencies( final Profile component,
final Profile[] components )
{
final ArrayList dependencies = new ArrayList();
final Association[] deps = component.getAssociations();
for( int i = 0; i < deps.length; i++ )
{
final String name = deps[ i ].getProvider().getName();
final Profile other = getProfile( name, components );
dependencies.add( other );
}
return (Profile[])dependencies.toArray( new Profile[ 0 ] );
}
/**
* Verfiy that the inter-Component dependencies are valid.
*
* @param components the Profile objects for the components
* @throws VerifyException if an error occurs
*/
protected void verifyDependencyReferences( final Profile[] components )
throws VerifyException
{
for( int i = 0; i < components.length; i++ )
{
verifyDependencyReferences( components[ i ], components );
}
}
/**
* Verfiy that the inter-Component dependencies are valid for specified Component.
*
* @param component the Profile object for the component
* @param others the Profile objects for the other components
* @throws VerifyException if an error occurs
*/
protected void verifyDependencyReferences( final Profile component,
final Profile[] others )
throws VerifyException
{
final Type info = component.getType();
final Association[] roles = component.getAssociations();
for( int i = 0; i < roles.length; i++ )
{
final String providerName = roles[ i ].getProvider().getName();
final String roleName = roles[ i ].getRole();
final ServiceDesignator service =
info.getDependency( roleName ).getService();
//Get the other component that is providing service
final Profile provider = getProfile( providerName, others );
if( null == provider )
{
final String message =
REZ.getString( "assembly.missing-dependency.error",
roleName,
providerName,
component.getName() );
throw new VerifyException( message );
}
//make sure that the component offers service
//that user expects it to be providing
final ServiceDescriptor[] services = provider.getType().getServices();
if( !hasMatchingService( service, services ) )
{
final String message =
REZ.getString( "assembly.dependency-missing-service.error",
component.getName(),
providerName,
roleName,
service );
throw new VerifyException( message );
}
}
}
/**
* Get component with specified name from specified Component array.
*
* @param name the name of component to get
* @param components the array of components to search
* @return the Component if found, else null
*/
protected Profile getProfile( final String name,
final Profile[] components )
{
for( int i = 0; i < components.length; i++ )
{
if( components[ i ].getName().equals( name ) )
{
return components[ i ];
}
}
return null;
}
/**
* Verify that the names of the specified Components are valid.
*
* @param components the Components metadata
* @throws VerifyException if an error occurs
*/
protected void verifyValidNames( final Profile[] components )
throws VerifyException
{
for( int i = 0; i < components.length; i++ )
{
final String name = components[ i ].getName();
if( !isValidName( name ) )
{
final String message =
REZ.getString( "assembly.bad-name.error", name );
throw new VerifyException( message );
}
}
}
/**
* Return true if specified name is valid.
* Valid names consist of letters, digits or the '_' character.
*
* @param name the name to check
* @return true if valid, false otherwise
*/
protected boolean isValidName( final String name )
{
final int size = name.length();
for( int i = 0; i < size; i++ )
{
final char ch = name.charAt( i );
if( !Character.isLetterOrDigit( ch ) && '-' != ch )
{
return false;
}
}
return true;
}
/**
* Verify that the names of the specified components and listeners are unique.
* It is not valid for the same name to be used in multiple components.
*
* @param components the Components
* @throws VerifyException if an error occurs
*/
protected void checkNamesUnique( final Profile[] components )
throws VerifyException
{
for( int i = 0; i < components.length; i++ )
{
final String name = components[ i ].getName();
verifyUniqueName( components, name, i );
}
}
/**
* Verfify that specified name is unique among the specified components.
*
* @param components the array of components to check
* @param name the name of component
* @param index the index of component in array (so we can skip it)
* @throws VerifyException if names are not unique
*/
private void verifyUniqueName( final Profile[] components,
final String name,
final int index )
throws VerifyException
{
for( int i = 0; i < components.length; i++ )
{
final String other = components[ i ].getName();
if( index != i && other.equals( name ) )
{
final String message =
REZ.getString( "assembly.duplicate-name.error", name );
throw new VerifyException( message );
}
}
}
/**
* Retrieve a list of Association objects for Profile
* and verify that there is a 1 to 1 map with dependencies specified
* in Type.
*
* @param component the Profile describing the component
* @throws VerifyException if an error occurs
*/
protected void verifyDependenciesMap( final Profile component )
throws VerifyException
{
//Make sure all role entries specified in config file are valid
final Association[] dependencySet = component.getAssociations();
for( int i = 0; i < dependencySet.length; i++ )
{
final String roleName = dependencySet[ i ].getRole();
final DependencyDescriptor descriptor = component.getType().getDependency( roleName );
//If there is no dependency descriptor in Type then
//user has specified an uneeded dependency.
if( null == descriptor )
{
final String message =
REZ.getString( "assembly.unknown-dependency.error",
roleName,
roleName,
component.getName() );
throw new VerifyException( message );
}
}
//Make sure all dependencies in Type file are satisfied
final DependencyDescriptor[] dependencies = component.getType().getDependencies();
for( int i = 0; i < dependencies.length; i++ )
{
final DependencyDescriptor dependency = dependencies[ i ];
final Association role = component.getAssociation( dependency.getRole() );
//If there is no Role then the user has failed
//to specify a needed dependency.
if( null == role && !dependency.isOptional() )
{
final String message =
REZ.getString( "assembly.unspecified-dependency.error",
dependency.getRole(),
component.getName() );
throw new VerifyException( message );
}
}
}
/**
* Return true if specified service reference matches any of the
* candidate services.
*
* @param service the service descriptor reference
* @param candidates an array of candidate services
* @return true if candidate services contains a service that matches
* specified service, false otherwise
*/
protected boolean hasMatchingService( final ServiceDesignator service,
final ServiceDescriptor[] candidates )
{
for( int i = 0; i < candidates.length; i++ )
{
final ServiceDesignator other = candidates[ i ].getService();
if( service.matches( other ) )
{
return true;
}
}
return false;
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier/MetaDataVerifier.java
Index: MetaDataVerifier.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.meta.data.verifier;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.excalibur.merlin.meta.data.Profile;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.ContextDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.ServiceDesignator;
import org.apache.excalibur.meta.verifier.VerifyException;
import org.apache.excalibur.meta.verifier.ComponentVerifier;
/**
* This Class verifies that an implementation is valid wrt the
* Profile. It performs a number of checks to make sure
* that the implementation class is consistent with MetaData.
* Some of the checks it performs include;
*
* <ul>
* <li>Verify that the Class objects for Component implement the
* service interfaces.</li>
* <li>Verify that the Class is a valid Avalon Component as per the
* rules in {@link ComponentVerifier} object.</li>
* <li>Verify that the Class is Composable/Serviceable if and only if
* dependencies are declared.</li>
* <li>Verify that the Class is Contextualizable if and context
* entrys are declared.</li>
* </ul>
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
*/
public class MetaDataVerifier
extends AbstractLogEnabled
{
private static final Resources REZ =
ResourceManager.getPackageResources( MetaDataVerifier.class );
/**
* The verifier for components in assembly.
*/
private final ComponentVerifier m_verifier;
/**
* Create an MetaDataVerifier using base Componert ComponentVerifier.
*/
public MetaDataVerifier()
{
this( new ComponentVerifier() );
}
/**
* Create an AssemblyVerifier using specified Component ComponentVerifier.
*/
public MetaDataVerifier( final ComponentVerifier verifier )
{
if( null == verifier )
{
throw new NullPointerException( "verifier" );
}
m_verifier = verifier;
}
public void enableLogging( final Logger logger )
{
super.enableLogging( logger );
setupLogger( m_verifier );
}
/**
* Verfiy that specified components designate classes that implement the
* advertised interfaces. And confrorm to expectations of MetaData.
*
* @param component the Profile object for the components
* @param classLoader the ClassLoader to load component from
* @throws VerifyException if an error occurs
*/
public void verifyType( final Profile component,
final ClassLoader classLoader )
throws VerifyException
{
final Class clazz = getClass( classLoader, component );
verifyType( component, clazz );
}
/**
* Verfiy that specified components designate classes that implement the
* advertised interfaces. And confrorm to expectations of MetaData.
*
* @param component the Profile object for the components
* @throws VerifyException if an error occurs
*/
public void verifyType( final Profile component,
final Class clazz )
throws VerifyException
{
final String name = component.getName();
final Class[] interfaces =
getServiceClasses( name,
component.getType().getServices(),
clazz.getClassLoader() );
m_verifier.verifyComponent( name, clazz, interfaces );
verifyDependencyPresence( component, clazz );
verifyContextPresence( component, clazz );
}
/**
* Verify that the if the component is not Contextualizable that it
* does not declare Context Entrys.
*
* @param component the component metadata
* @param clazz the class implementing component
* @throws VerifyException if fails verification check
*/
protected void verifyContextPresence( final Profile component,
final Class clazz )
throws VerifyException
{
final Type info = component.getType();
final ContextDescriptor context = info.getContextDescriptor();
final int count = context.getEntrys().length;
if( !Contextualizable.class.isAssignableFrom( clazz ) )
{
if( 0 != count )
{
final String message =
REZ.getString( "metadata.declare-uneeded-entrys.error",
component.getName(),
getClassname( component ) );
throw new VerifyException( message );
}
}
}
/**
* Verify the component assembly logic.
* The implications verifies that the component:
* <p>Is not Composable/Serviceable and does not declare dependencys</p>
* <p>or</p>
* <p>Is Composable/Serviceable and does declare dependencys</p>
*
* @param component the component metadata
* @param clazz the class implementing component
* @throws VerifyException if fails verification check
*/
protected void verifyDependencyPresence( final Profile component,
final Class clazz )
throws VerifyException
{
final int count = component.getAssociations().length;
final boolean aquiresServices =
Composable.class.isAssignableFrom( clazz ) ||
Serviceable.class.isAssignableFrom( clazz );
if( !aquiresServices )
{
if( 0 != count )
{
final String message =
REZ.getString( "metadata.declare-uneeded-deps.error",
component.getName(),
getClassname( component ) );
throw new VerifyException( message );
}
}
}
/**
* Retrieve an array of Classes for all the services that a Component
* offers. This method also makes sure all services offered are
* interfaces.
*
* @param name the name of component
* @param services the services the component offers
* @param classLoader the classLoader
* @return an array of Classes for all the services
* @throws VerifyException if an error occurs
*/
protected Class[] getServiceClasses( final String name,
final ServiceDescriptor[] services,
final ClassLoader classLoader )
throws VerifyException
{
final Class[] classes = new Class[ services.length ];
for( int i = 0; i < services.length; i++ )
{
final ServiceDesignator service = services[ i ].getService();
final String classname = service.getClassname();
try
{
classes[ i ] = classLoader.loadClass( classname );
}
catch( final Throwable t )
{
final String message =
REZ.getString( "metadata.bad-service-class.error",
name,
classname,
t.toString() );
throw new VerifyException( message, t );
}
}
return classes;
}
/**
* Load class object for specified Profile.
*
* @param classLoader the ClassLoader to use
* @param component the meta data associate with component
* @return the Class object
* @throws VerifyException if unable to aquire class object
*/
private Class getClass( final ClassLoader classLoader,
final Profile component )
throws VerifyException
{
Class clazz = null;
try
{
clazz = classLoader.loadClass( getClassname( component ) );
}
catch( final Exception e )
{
final String message =
REZ.getString( "assembly.bad-class.error",
component.getName(),
getClassname( component ),
e.toString() );
throw new VerifyException( message );
}
return clazz;
}
/**
* Utility method to aquire classname for component.
*
* @param component the component
* @return the classname for component
*/
private String getClassname( final Profile component )
{
return component.getType().getInfo().getImplementationKey();
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier/Resources.properties
Index: Resources.properties
===================================================================
#Assembly Verifier
assembly.valid-names.notice=Verifying that the names specified for Component are valid.
assembly.unique-names.notice=Verifying that the names specified for the Components are unique.
assembly.dependencies-mapping.notice=Verifying that the dependency mapping is valid according to ComponentInfos.
assembly.dependency-references.notice=Verifying that the dependency mapping for every Component is valid with respect to other components.
assembly.nocircular-dependencies.notice=Verifying that there are no circular dependencies between Components.
assembly.component-type.notice=Verifying that the specified Components have valid types.
assembly.circular-dependency.error=Component named "{0}" has a circular dependency via path: {1}.
assembly.missing-dependency.error=Component "{1}" that satisfies the dependency with role "{0}" of Component "{2}" does not exist.
assembly.dependency-missing-service.error=Profile {0}" is associated to profile "{1}" under the role "{2}" however, the provider does not supply the required service "{3}".
assembly.bad-class.error=Unable to load class "{1}" for Component named "{0}". (Reason: {2}).
assembly.bad-name.error=The Component name "{0}" is invalid. Valid names contain only letters, digits and the '-' character.
assembly.duplicate-name.error=The name "{0}" is used by multiple Components in assembly.
assembly.unknown-dependency.error=Unknown dependency named "{0}" with role "{1}" declared for Component {2}.
assembly.unspecified-dependency.error=Dependency for role "{0}" not specified for the Component named "{1}".
#MetaData Verifier
metadata.bad-service-class.error=Unable to load service class "{1}" for Component named "{0}". (Reason: {2}).
metadata.nodeclare-deps.error=Component named "{0}" of type "{1}" is Composable or Serviceable but does not declare any dependencies.
metadata.declare-uneeded-deps.error=Component named "{0}" of type "{1}" is not Composable or Serviceable but declares dependencies.
metadata.declare-uneeded-entrys.error=Component named "{0}" of type "{1}" is not Contextualizable but declares Context Entrys.
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier/package.html
Index: package.html
===================================================================
<body>
A set of classes supporting verification of components and component
assemblies using class and component meta-data information.
<h3>Overview</h3>
<p>This package includes a set of classes supporting the verification of the
integrity of a component class and the verification of the integrity of a
relationships and inter-dependecies based on supplied meta-data. The
{@link org.apache.excalibur.merlin.meta.data.verifier.ComponentVerifier} provides
support for the validation of a component class. It includes validation
functions that check for structural and best-practice integrity related to
the class, lifecycle patterns and service. The
{@link org.apache.excalibur.merlin.meta.data.verifier.AssemblyVerifier} performs
validation of the structural integrity of a set component assembly based on
assembly meta-data.
</body>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>