Author: cziegeler
Date: Thu Oct 21 12:25:56 2004
New Revision: 55250
Added:
cocoon/trunk/src/core/
cocoon/trunk/src/core/java/
cocoon/trunk/src/core/java/org/
cocoon/trunk/src/core/java/org/apache/
cocoon/trunk/src/core/java/org/apache/cocoon/
cocoon/trunk/src/core/java/org/apache/cocoon/components/
cocoon/trunk/src/core/java/org/apache/cocoon/core/
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java
cocoon/trunk/src/core/test/
cocoon/trunk/src/core/test/org/
cocoon/trunk/src/core/test/org/apache/
cocoon/trunk/src/core/test/org/apache/cocoon/
cocoon/trunk/src/core/test/org/apache/cocoon/core/
cocoon/trunk/src/core/test/org/apache/cocoon/core/container/
cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java
Removed:
cocoon/trunk/src/java/org/apache/cocoon/components/ExtendedComponentSelector.java
cocoon/trunk/src/java/org/apache/cocoon/components/container/CocoonComponentManager.java
cocoon/trunk/src/java/org/apache/cocoon/components/container/ComponentLocatorImpl.java
cocoon/trunk/src/java/org/apache/cocoon/components/container/ComponentManagerWrapper.java
Modified:
cocoon/trunk/src/blocks/portal/java/org/apache/cocoon/portlet/CocoonPortlet.java
cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java
cocoon/trunk/src/java/org/apache/cocoon/bean/BeanListener.java
cocoon/trunk/src/java/org/apache/cocoon/bean/CocoonBean.java
cocoon/trunk/src/java/org/apache/cocoon/bean/CocoonWrapper.java
cocoon/trunk/src/java/org/apache/cocoon/components/container/DefaultSitemapConfigurationHolder.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsSelector.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java
cocoon/trunk/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.java
cocoon/trunk/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.java
cocoon/trunk/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.java
cocoon/trunk/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.java
cocoon/trunk/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.java
Log:
Adding ECM++ - not working yet
Modified:
cocoon/trunk/src/blocks/portal/java/org/apache/cocoon/portlet/CocoonPortlet.java
==============================================================================
---
cocoon/trunk/src/blocks/portal/java/org/apache/cocoon/portlet/CocoonPortlet.java
(original)
+++
cocoon/trunk/src/blocks/portal/java/org/apache/cocoon/portlet/CocoonPortlet.java
Thu Oct 21 12:25:56 2004
@@ -1600,9 +1600,6 @@
if (parent != null) {
ContainerUtil.compose(c, parent);
}
- if (this.enableInstrumentation) {
- c.setInstrumentManager(getInstrumentManager());
- }
ContainerUtil.initialize(c);
this.creationTime = System.currentTimeMillis();
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.excalibur.pool.Poolable;
+import org.apache.avalon.framework.component.Composable;
+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.service.ServiceManager;
+import org.apache.avalon.framework.thread.SingleThreaded;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * This class acts like a Factory to instantiate the correct version
+ * of the component handler that you need.
+ *
+ * @version CVS $Id: AbstractComponentHandler.java 55144 2004-10-20 12:26:09Z
ugo $
+ */
+public abstract class AbstractComponentHandler {
+
+ private final Object referenceSemaphore = new Object();
+ private int references = 0;
+
+ protected final Logger logger;
+
+ /** This factory is used to created new objects */
+ protected final ComponentFactory factory;
+
+ /** State management boolean stating whether the Handler is disposed or
not */
+ protected boolean disposed = false;
+
+ /** State management boolean stating whether the Handler is initialized or
not */
+ protected boolean initialized = false;
+
+ /**
+ * Looks up and returns a component handler for a given component class.
+ *
+ * @param role The role name of the component. This must be
+ * a fully-qualified classname
+ * @param componentClass Class of the component for which the handle is
+ * being requested.
+ * @param configuration The configuration for this component.
+ * @param serviceManager The service manager which will be managing the
service.
+ * @param context The current context object.
+ * @param logger The current logger
+ * @param loggerManager The current LoggerManager.
+ *
+ * @throws Exception If there were any problems obtaining a
ComponentHandler
+ */
+ public static AbstractComponentHandler getComponentHandler( final String
role,
+ final Class
componentClass,
+ final Configuration
configuration,
+ final ServiceManager
serviceManager,
+ final Context context,
+ final Logger logger,
+ final LoggerManager
loggerManager,
+ final RoleManager
roleManager)
+ throws Exception {
+ int numInterfaces = 0;
+
+ if( SingleThreaded.class.isAssignableFrom( componentClass ) ) {
+ numInterfaces++;
+ }
+
+ if( ThreadSafe.class.isAssignableFrom( componentClass ) ) {
+ numInterfaces++;
+ }
+
+ if( Poolable.class.isAssignableFrom( componentClass ) ) {
+ numInterfaces++;
+ }
+
+ if( numInterfaces > 1 ) {
+ throw new Exception( "[CONFLICT] More than one lifecycle interface
in "
+ + componentClass.getName() + " May implement
no more than one of "
+ + "SingleThreaded, ThreadSafe, or Poolable" );
+ }
+
+ // Early check for Composable
+ if ( Composable.class.isAssignableFrom( componentClass ) ) {
+ throw new Exception("Interface Composable is not supported
anymore. Please change class "
+ + componentClass.getName() + " to use
Serviceable instead.");
+ }
+
+ // Create the factory to use to create the instances of the Component.
+ ComponentFactory factory = new ComponentFactory( role,
+ componentClass,
+ configuration,
+ serviceManager,
+ context,
+ logger,
+ loggerManager,
+ roleManager);
+
+ AbstractComponentHandler handler;
+
+ if( Poolable.class.isAssignableFrom( componentClass ) ) {
+ handler = new PoolableComponentHandler( logger, factory,
configuration );
+ } else if( ThreadSafe.class.isAssignableFrom( componentClass ) ) {
+ handler = new ThreadSafeComponentHandler( logger, factory );
+ } else {
+ // This is a SingleThreaded component
+ handler = new SingleThreadedComponentHandler( logger, factory );
+ }
+
+ return handler;
+ }
+
+ /**
+ * Creates a new ComponentHandler.
+ */
+ public AbstractComponentHandler(Logger logger, ComponentFactory factory) {
+ this.logger = logger;
+ this.factory = factory;
+ }
+
+ /**
+ * Get an instance of the type of component handled by this handler.
+ * <p>
+ * Subclasses should not extend this method but rather the doGet method
below otherwise
+ * reference counts will not be supported.
+ * <p>
+ *
+ * @return an instance
+ * @exception Exception if an error occurs
+ */
+ public final Object get() throws Exception {
+ if( !this.initialized ) {
+ throw new IllegalStateException(
+ "You cannot get a component from an uninitialized handler." );
+ }
+ if( this.disposed ) {
+ throw new IllegalStateException( "You cannot get a component from
a disposed handler." );
+ }
+
+ final Object component = this.doGet();
+
+ synchronized( this.referenceSemaphore ) {
+ this.references++;
+ }
+
+ return component;
+ }
+
+ /**
+ * Put back an instance of the type of component handled by this handler.
+ * <p>
+ * Subclasses should not extend this method but rather the doPut method
below otherwise
+ * reference counts will not be supported.
+ * <p>
+ *
+ * @param component a service
+ * @exception Exception if an error occurs
+ */
+ public final void put( Object component )
+ throws Exception {
+ if( !this.initialized ) {
+ throw new IllegalStateException(
+ "You cannot put a component to an uninitialized handler." );
+ }
+ // The reference count must be decremented before any calls to doPut.
+ // If there is another thread blocking, then this thread could stay
deep inside
+ // doPut for an undetermined amount of time until the thread
scheduler gives it
+ // some cycles again. (It happened). All ComponentHandler state
must therefor
+ // reflect the thread having left this method before the call to
doPut to avoid
+ // warning messages from the dispose() cycle if that takes place
before this
+ // thread has a chance to continue.
+ synchronized( this.referenceSemaphore ) {
+ this.references--;
+ }
+
+ try {
+ this.doPut( component );
+ } catch( Throwable t ) {
+ this.logger.error("Exception during putting back a component.", t);
+ }
+ }
+
+ /**
+ * Concrete implementation of getting a component.
+ *
+ * @return a service
+ * @exception Exception if an error occurs
+ */
+ protected abstract Object doGet() throws Exception;
+
+ /**
+ * Concrete implementation of putting back a component.
+ *
+ * @param component a <code>Component</code> value
+ * @exception Exception if an error occurs
+ */
+ protected abstract void doPut( Object component ) throws Exception;
+
+ /**
+ * Returns <code>true</code> if this component handler can safely be
+ * disposed (i.e. none of the components it is handling are still
+ * being used).
+ *
+ * @return <code>true</code> if this component handler can safely be
+ * disposed; <code>false</code> otherwise
+ */
+ public final boolean canBeDisposed() {
+ return ( this.references == 0 );
+ }
+
+ /**
+ * Dispose of the component handler and any associated Pools and Factories.
+ */
+ public void dispose() {
+ this.disposed = true;
+ }
+
+ /**
+ * Initialize this handler
+ */
+ public void initialize() throws Exception {
+ if( this.initialized ) {
+ return;
+ }
+ this.initialized = true;
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "ThreadSafeComponentHandler initialized for: "
+ this.factory.getCreatedClass().getName() );
+ }
+ }
+}
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+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.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * Base class for all service managers: ServiceManager and ServiceSelector
+ *
+ * @version CVS $Id: AbstractServiceManager.java 55144 2004-10-20 12:26:09Z
ugo $
+ */
+public abstract class AbstractServiceManager
+extends AbstractLogEnabled
+implements Contextualizable, ThreadSafe, Disposable, Initializable {
+
+ /** The classloader used for this system. */
+ protected final ClassLoader loader;
+
+ /** The application context for components */
+ protected Context context;
+
+ /** Static component mapping handlers. */
+ protected final Map componentMapping = Collections.synchronizedMap(new
HashMap());
+
+ /** Used to map roles to ComponentHandlers. */
+ protected final Map componentHandlers = Collections.synchronizedMap(new
HashMap());
+
+ /** Is the Manager disposed or not? */
+ protected boolean disposed;
+
+ /** Is the Manager initialized? */
+ protected boolean initialized;
+
+ /** RoleInfos. */
+ protected RoleManager roleManager;
+
+ /** LoggerManager. */
+ protected LoggerManager loggerManager;
+
+
+ /**
+ * Create the ServiceManager with a Classloader
+ */
+ public AbstractServiceManager( final ClassLoader loader ) {
+ if( null == loader ) {
+ this.loader = Thread.currentThread().getContextClassLoader();
+ } else {
+ this.loader = loader;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+ */
+ public void contextualize( final Context context ) {
+ this.context = context;
+ }
+
+ public void setRoleManager( final RoleManager roles ) {
+ this.roleManager = roles;
+ }
+
+ /**
+ * Configure the LoggerManager.
+ */
+ public void setLoggerManager( final LoggerManager manager ) {
+ this.loggerManager = manager;
+ }
+
+ /**
+ * Obtain a new ComponentHandler for the specified component.
+ *
+ * @param role The role
+ * @param componentClass Class of the component for which the handle is
+ * being requested.
+ * @param configuration The configuration for this component.
+ * @param serviceManager The service manager which will be managing the
Component.
+ *
+ * @throws Exception If there were any problems obtaining a
ComponentHandler
+ */
+ protected AbstractComponentHandler getComponentHandler( final String role,
+ final Class componentClass,
+ final Configuration
configuration,
+ final ServiceManager
serviceManager)
+ throws Exception {
+ return AbstractComponentHandler.getComponentHandler( role,
+ componentClass,
+ configuration,
+ serviceManager,
+ this.context,
+ this.getLogger(),
+ this.loggerManager,
+ this.roleManager);
+ }
+
+ protected void addComponent(String className,
+ Object role,
+ Configuration configuration)
+ throws ConfigurationException {
+ // check for old class names
+ // TODO We can remove this as soon as we changed cocoon.roles and
cocoon.xconf
+ if (
"org.apache.cocoon.components.ExtendedComponentSelector".equals(className)) {
+ className = CocoonServiceSelector.class.getName();
+ }
+
+ try {
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "Adding component (" + role + " = " +
className + ")" );
+ }
+
+ final Class clazz = this.loader.loadClass( className );
+ this.addComponent( role, clazz, configuration );
+ } catch( final ClassNotFoundException cnfe ) {
+ final String message = "Could not get class (" + className + ")
for role "
+ + role + " on configuration element " +
configuration.getName();
+
+ if( this.getLogger().isErrorEnabled() ) {
+ this.getLogger().error( message, cnfe );
+ }
+
+ throw new ConfigurationException( message, cnfe );
+ } catch( final ServiceException ce ) {
+ final String message = "Bad component "+ className + " for role "
+ role
+ + " on configuration element " +
configuration.getName();
+
+ if( this.getLogger().isErrorEnabled() ) {
+ this.getLogger().error( message, ce );
+ }
+
+ throw new ConfigurationException( message, ce );
+ } catch( final Exception e ) {
+ final String message = "Unexpected exception for role: " + role;
+ if( this.getLogger().isErrorEnabled() ) {
+ this.getLogger().error( "Unexpected exception for role: " +
role, e );
+ }
+ throw new ConfigurationException( message, e );
+ }
+ }
+
+ protected abstract void addComponent(Object role, Class clazz,
Configuration config)
+ throws ServiceException;
+
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ */
+ public void dispose() {
+ this.disposed = true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Initializable#initialize()
+ */
+ public void initialize() throws Exception {
+ this.initialized = true;
+ }
+}
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,485 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.SitemapConfigurable;
+import org.apache.cocoon.components.SitemapConfigurationHolder;
+import
org.apache.cocoon.components.container.DefaultSitemapConfigurationHolder;
+
+/**
+ * Default service manager for Cocoon's components.
+ *
+ * @version CVS $Revision: 1.6 $Id: CocoonServiceManager.java 55165 2004-10-20
16:51:50Z cziegeler $
+ */
+public class CocoonServiceManager
+extends AbstractServiceManager
+implements ServiceManager, Configurable {
+
+ /** The parent ServiceManager */
+ private final ServiceManager parentManager;
+
+ /** added component handlers before initialization to maintain
+ * the order of initialization
+ */
+ private final List newComponentHandlers = new ArrayList();
+
+ /** The [EMAIL PROTECTED] SitemapConfigurationHolder}s */
+ private Map sitemapConfigurationHolders = new HashMap(15);
+
+ /** Temporary list of parent-aware components. Will be null for most of
+ * our lifecycle. */
+ private ArrayList parentAwareComponents = new ArrayList();
+
+ /** Create the ServiceManager with a Classloader and parent ServiceManager
*/
+ public CocoonServiceManager( final ServiceManager parent,
+ final ClassLoader loader ) {
+ super(loader);
+ this.parentManager = parent;
+ // get role manager and logger manager
+ if ( parent instanceof CocoonServiceManager ) {
+ this.roleManager = ((CocoonServiceManager)parent).roleManager;
+ this.loggerManager = ((CocoonServiceManager)parent).loggerManager;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+ */
+ public Object lookup( final String role )
+ throws ServiceException {
+ if( !this.initialized ) {
+ if( this.getLogger().isWarnEnabled() ) {
+ this.getLogger().warn(
+ "Looking up component on an uninitialized
CocoonServiceManager [" + role + "]" );
+ }
+ }
+
+ if( this.disposed ) {
+ throw new IllegalStateException(
+ "You cannot lookup components on a disposed
CocoonServiceManager" );
+ }
+
+ if( role == null ) {
+ final String message =
+ "CocoonServiceManager attempted to retrieve service with null
role.";
+
+ if( this.getLogger().isErrorEnabled() ) {
+ this.getLogger().error( message );
+ }
+ throw new ServiceException( role, message );
+ }
+
+ AbstractComponentHandler handler =
(AbstractComponentHandler)this.componentHandlers.get( role );
+
+ // Retrieve the instance of the requested component
+ if ( handler == null ) {
+ if( this.parentManager != null ) {
+ try {
+ return this.parentManager.lookup( role );
+ } catch( Exception e ) {
+ if( this.getLogger().isWarnEnabled() ) {
+ final String message =
+ "ComponentLocator exception from parent SM during
lookup.";
+ this.getLogger().warn( message, e );
+ }
+ // ignore. If the exception is thrown, we try to
+ // create the component next
+ }
+ }
+
+ if( this.roleManager != null ) {
+ final String className =
this.roleManager.getDefaultClassNameForRole( role );
+
+ if( className != null ) {
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "Could not find
ComponentHandler, attempting to create "
+ + "one for role [" + role + "]" );
+ }
+
+ try {
+ final Class componentClass = this.loader.loadClass(
className );
+
+ final Configuration configuration = new
DefaultConfiguration( "", "-" );
+
+ handler = this.getComponentHandler( role,
+ componentClass,
+ configuration,
+ this);
+
+ handler.initialize();
+ } catch (ServiceException se) {
+ throw se;
+ } catch( final Exception e ) {
+ final String message = "Could not find component";
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( message + " for role: " +
role, e );
+ }
+ throw new ServiceException( role, message, e );
+ }
+
+ this.componentHandlers.put( role, handler );
+ }
+ } else {
+ this.getLogger().debug( "Component requested without a
RoleManager set.\n"
+ + "That means setRoleManager() was not called during
initialization." );
+ }
+ }
+
+ if( handler == null ) {
+ final String message = "Could not find component";
+ if( this.getLogger().isDebugEnabled() )
+ {
+ this.getLogger().debug( message + " for role: " + role );
+ }
+ throw new ServiceException( role, message );
+ }
+
+ Object component = null;
+
+ try {
+ component = handler.get();
+ } catch( final IllegalStateException ise ) {
+ try {
+ handler.initialize();
+ component = handler.get();
+ } catch( final ServiceException ce ) {
+ // Rethrow instead of wrapping a ComponentException with
another one
+ throw ce;
+ } catch( final Exception e ) {
+ final String message = "Could not access the Component";
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( message + " for role [" + role +
"]", e );
+ }
+
+ throw new ServiceException( role, message, e );
+ }
+ } catch ( ServiceException se) {
+ throw se;
+ } catch( final Exception e ) {
+ final String message = "Could not access the Component";
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( message + " for role [" + role + "]",
e );
+ }
+
+ throw new ServiceException( role, message, e );
+ }
+
+ // Add a mapping between the component and its handler.
+ // In the case of a ThreadSafeComponentHandler, the same component
will be mapped
+ // multiple times but because each put will overwrite the last, this
is not a
+ // problem. Checking to see if the put has already been done would
be slower.
+ this.componentMapping.put( component, handler );
+
+ if ( null != component && component instanceof SitemapConfigurable) {
+
+ // FIXME: how can we prevent that this is called over and over
again?
+ SitemapConfigurationHolder holder;
+
+ holder =
(SitemapConfigurationHolder)this.sitemapConfigurationHolders.get( role );
+ if ( null == holder ) {
+ // create new holder
+ holder = new DefaultSitemapConfigurationHolder( role,
this.roleManager );
+ this.sitemapConfigurationHolders.put( role, holder );
+ }
+
+ try {
+ ((SitemapConfigurable)component).configure(holder);
+ } catch (ConfigurationException ce) {
+ throw new ServiceException(role, "Exception during setup of
SitemapConfigurable.", ce);
+ }
+ }
+ return component;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+ */
+ public boolean hasService( final String role ) {
+ if( !this.initialized ) return false;
+ if( this.disposed ) return false;
+
+ boolean exists = this.componentHandlers.containsKey( role );
+
+ if( !exists && null != this.parentManager ) {
+ exists = this.parentManager.hasService( role );
+ }
+
+ return exists;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+ */
+ public void release( final Object component ) {
+ if( null == component ) {
+ return;
+ }
+
+ // The componentMapping StaticBucketMap itself is threadsafe, and
because the same component
+ // will never be released by more than one thread, this method does
not need any
+ // synchronization around the access to the map.
+
+ final AbstractComponentHandler handler =
+ (AbstractComponentHandler)this.componentMapping.get( component );
+
+ if ( handler != null ) {
+ // ThreadSafe components will always be using a
ThreadSafeComponentHandler,
+ // they will only have a single entry in the m_componentMapping
map which
+ // should not be removed until the ComponentLocator is disposed.
All
+ // other components have an entry for each instance which should
be
+ // removed.
+ if( !( handler instanceof ThreadSafeComponentHandler ) ) {
+ // Remove the component before calling put. This is critical
to avoid the
+ // problem where another thread calls put on the same
component before
+ // remove can be called.
+ this.componentMapping.remove( component );
+ }
+
+ try {
+ handler.put( component );
+ } catch( Exception e ) {
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "Error trying to release
component.", e );
+ }
+ }
+ }
+ else if( this.parentManager != null ) {
+ this.parentManager.release( component );
+ } else {
+ this.getLogger().warn( "Attempted to release a " +
component.getClass().getName() +
+ " but its handler could not be located." );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+ */
+ public void configure( final Configuration configuration )
+ throws ConfigurationException {
+ if( null == roleManager ) {
+ final RoleManager roleInfo = new RoleManager();
+ roleInfo.enableLogging( getLogger() );
+ roleInfo.configure( configuration );
+ this.roleManager = roleInfo;
+ this.getLogger().debug( "No RoleManager given, deriving one from
configuration" );
+ }
+
+ // Set components
+
+ final Configuration[] configurations = configuration.getChildren();
+
+ for( int i = 0; i < configurations.length; i++ ) {
+ String type = configurations[ i ].getName();
+
+ if( !type.equals( "role" ) ) {
+ String role = configurations[ i ].getAttribute( "role", "" );
+ String className = configurations[ i ].getAttribute( "class",
"" );
+
+ if( role.equals( "" ) ) {
+ role = roleManager.getRoleForName( type );
+ }
+
+ if( null != role && !role.equals( "" ) ) {
+ if( className.equals( "" ) ) {
+ className = roleManager.getDefaultClassNameForRole(
role );
+ }
+
+ this.addComponent(className, role, configurations[i]);
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+ */
+ public void contextualize( final Context context ) {
+ this.context = context;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Initializable#initialize()
+ */
+ public void initialize()
+ throws Exception {
+ super.initialize();
+
+ for( int i = 0; i < this.newComponentHandlers.size(); i++ )
+ {
+ final AbstractComponentHandler handler =
+ (AbstractComponentHandler)this.newComponentHandlers.get( i );
+ try {
+ handler.initialize();
+ } catch( Exception e ) {
+ if( this.getLogger().isErrorEnabled() )
+ {
+ this.getLogger().error( "Caught an exception trying to
initialize "
+ + "the component handler.", e );
+ }
+
+ // Rethrow the exception
+ throw e;
+ }
+ }
+
+ List keys = new ArrayList( this.componentHandlers.keySet() );
+
+ for( int i = 0; i < keys.size(); i++ ) {
+ final Object key = keys.get( i );
+ final AbstractComponentHandler handler =
+ (AbstractComponentHandler)this.componentHandlers.get( key );
+
+ if( !this.newComponentHandlers.contains( handler ) ) {
+ try {
+ handler.initialize();
+
+ } catch( Exception e ) {
+ if( this.getLogger().isErrorEnabled() ) {
+ this.getLogger().error( "Caught an exception trying to
initialize "
+ + "the component handler.", e );
+
+ }
+ // Rethrow the exception
+ throw e;
+ }
+ }
+ }
+ this.newComponentHandlers.clear();
+
+ if (parentAwareComponents == null) {
+ throw new ServiceException(null, "CocoonServiceManager already
initialized");
+ }
+ // Set parents for parentAware components
+ Iterator iter = parentAwareComponents.iterator();
+ while (iter.hasNext()) {
+ String role = (String)iter.next();
+ if ( parentManager != null && parentManager.hasService( role ) ) {
+ // lookup new component
+ Object component = null;
+ try {
+ component = this.lookup( role );
+ ((CocoonServiceSelector)component).setParentLocator(
this.parentManager, role );
+ } catch (ServiceException ignore) {
+ // we don't set the parent then
+ } finally {
+ this.release( component );
+ }
+ }
+ }
+ parentAwareComponents = null; // null to save memory, and catch logic
bugs.
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ */
+ public void dispose() {
+ boolean forceDisposal = false;
+
+ final List disposed = new ArrayList();
+
+ while( componentHandlers.size() > 0 ) {
+ for( Iterator iterator = componentHandlers.keySet().iterator();
+ iterator.hasNext(); ) {
+ final Object role = iterator.next();
+
+ final AbstractComponentHandler handler =
+ (AbstractComponentHandler)componentHandlers.get( role );
+
+ if( forceDisposal || handler.canBeDisposed() ) {
+ if( forceDisposal && getLogger().isWarnEnabled() ) {
+ this.getLogger().warn
+ ( "disposing of handler for unreleased component."
+ + " role [" + role + "]" );
+ }
+
+ handler.dispose();
+ disposed.add( role );
+ }
+ }
+
+ if( disposed.size() > 0 ) {
+ final Iterator i = disposed.iterator();
+ while ( i.hasNext() ) {
+ this.componentHandlers.remove( i.next() );
+ }
+ disposed.clear();
+ } else {
+ // no more disposable handlers!
+ forceDisposal = true;
+ }
+ }
+ super.dispose();
+ }
+
+ /**
+ * Add a new component to the manager.
+ *
+ * @param role the role name for the new component.
+ * @param component the class of this component.
+ * @param configuration the configuration for this component.
+ */
+ public void addComponent( final Object role,
+ final Class component,
+ final Configuration configuration )
+ throws ServiceException {
+ if( this.initialized ) {
+ throw new ServiceException( role.toString(),
+ "Cannot add components to an initialized
CocoonServiceManager." );
+ }
+
+ try {
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "Attempting to get handler for role ["
+ role.toString() + "]" );
+ }
+
+ final AbstractComponentHandler handler = this.getComponentHandler(
role.toString(),
+ component,
+
configuration,
+ this);
+
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "Handler type = " +
handler.getClass().getName() );
+ }
+
+ this.componentHandlers.put( role.toString(), handler );
+ this.newComponentHandlers.add( handler );
+ } catch ( final ServiceException se ) {
+ throw se;
+ } catch( final Exception e ) {
+ throw new ServiceException( role.toString(), "Could not set up
component handler.", e );
+ }
+ // Note that at this point, we're not initialized and cannot do
+ // lookups, so defer parental introductions to initialize().
+ if ( CocoonServiceSelector.class.isAssignableFrom( component ) ) {
+ this.parentAwareComponents.add(role);
+ }
+ }
+
+}
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceSelector.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.component.ComponentException;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+
+/**
+ * Default component selector for Cocoon's components.
+ *
+ * @version CVS $Id: CocoonServiceSelector.java 55144 2004-10-20 12:26:09Z ugo
$
+ */
+public class CocoonServiceSelector
+extends AbstractServiceManager
+implements ServiceSelector, Serviceable, Configurable {
+
+ /** The application context for components
+ */
+ private ServiceManager serviceManager;
+
+ /** The parent selector, if any */
+ protected CocoonServiceSelector parentSelector;
+
+ /** The parent locator, if any */
+ protected ServiceManager parentLocator;
+
+ /** The role of this selector. Set in <code>configure()</code>. */
+ protected String roleName;
+
+ /** The default hint */
+ protected String defaultHint;
+
+ /** Create the ComponentSelector */
+ public CocoonServiceSelector() {
+ super(null);
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.service.ServiceSelector#select(java.lang.Object)
+ */
+ public Object select( Object hint )
+ throws ServiceException {
+ if( !this.initialized ) {
+ if( this.getLogger().isWarnEnabled() ) {
+ this.getLogger().warn( "Looking up component on an
uninitialized ComponentLocator "
+ + "with hint [" + hint + "]" );
+ }
+ }
+
+ if( this.disposed ) {
+ throw new IllegalStateException(
+ "You cannot select a Component from a disposed
ComponentSelector" );
+ }
+
+ if (hint == null) {
+ hint = this.defaultHint;
+ }
+
+ AbstractComponentHandler handler =
(AbstractComponentHandler)this.componentHandlers.get( hint );
+
+ // Retrieve the instance of the requested component
+ if( null == handler ) {
+ // Doesn't exist here : try in parent selector
+ if ( this.parentSelector != null ) {
+ return this.parentSelector.select(hint);
+ }
+ final String message = this.roleName
+ + ": ComponentSelector could not find the component for hint
[" + hint + "]";
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( message );
+ }
+ throw new ServiceException( hint.toString(), message );
+ }
+
+ Object component = null;
+
+ try {
+ component = handler.get();
+ } catch( final ServiceException ce ) {
+ //rethrow
+ throw ce;
+ } catch( final Exception e ) {
+ final String message = this.roleName
+ + ": ComponentSelector could not access the Component for hint
[" + hint + "]";
+
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( message, e );
+ }
+ throw new ServiceException( hint.toString(), message, e );
+ }
+
+ if( null == component ) {
+ // Doesn't exist here : try in parent selector
+ if ( this.parentSelector != null ) {
+ component = this.parentSelector.select(hint);
+ } else {
+ final String message = this.roleName
+ + ": ComponentSelector could not find the component for
hint [" + hint + "]";
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( message );
+ }
+ throw new ServiceException( hint.toString(), message );
+ }
+ }
+
+ this.componentMapping.put( component, handler );
+ return component;
+
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.service.ServiceSelector#isSelectable(java.lang.Object)
+ */
+ public boolean isSelectable( Object hint ) {
+ if( !this.initialized ) return false;
+ if( this.disposed ) return false;
+
+ if (hint == null) {
+ hint = this.defaultHint;
+ }
+
+ boolean exists = false;
+
+ try {
+ AbstractComponentHandler handler =
(AbstractComponentHandler)this.componentHandlers.get( hint );
+ exists = (handler != null);
+ } catch( Throwable t ) {
+ // We can safely ignore all exceptions
+ }
+
+ if ( !exists && this.parentSelector != null ) {
+ exists = this.parentSelector.isSelectable( hint );
+ }
+ return exists;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.service.ServiceSelector#release(java.lang.Object)
+ */
+ public void release( final Object component ) {
+ if( null == component ) {
+ return;
+ }
+
+ // Was it selected on the parent ?
+ if ( this.parentSelector != null &&
+ this.parentSelector.canRelease(component) ) {
+ this.parentSelector.release(component);
+
+ } else {
+ final AbstractComponentHandler handler =
+ (AbstractComponentHandler)this.componentMapping.get( component
);
+
+ if( null == handler ) {
+ this.getLogger().warn( "Attempted to release a " +
component.getClass().getName()
+ + " but its handler could not be located." );
+ return;
+ }
+
+ // ThreadSafe components will always be using a
ThreadSafeComponentHandler,
+ // they will only have a single entry in the m_componentMapping
map which
+ // should not be removed until the ComponentLocator is disposed.
All
+ // other components have an entry for each instance which should
be
+ // removed.
+ if( !( handler instanceof ThreadSafeComponentHandler ) ) {
+ // Remove the component before calling put. This is critical
to avoid the
+ // problem where another thread calls put on the same
component before
+ // remove can be called.
+ this.componentMapping.remove( component );
+ }
+
+ try {
+ handler.put( component );
+ } catch( Exception e ) {
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "Error trying to release
component", e );
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service( final ServiceManager componentManager )
+ throws ServiceException {
+ this.serviceManager = componentManager;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+ */
+ public void configure( final Configuration config )
+ throws ConfigurationException {
+ this.roleName = getRoleName(config);
+
+ // Get default hint
+ this.defaultHint =
config.getAttribute(this.getDefaultHintAttributeName(), null);
+
+ // Add components
+ String compInstanceName = getComponentInstanceName();
+
+ Configuration[] instances = config.getChildren();
+
+ for (int i = 0; i < instances.length; i++) {
+
+ Configuration instance = instances[i];
+
+ Object hint = instance.getAttribute("name").trim();
+
+ String classAttr = instance.getAttribute(getClassAttributeName(),
null);
+ String className;
+
+ if (compInstanceName == null) {
+ // component-instance implicitly defined by the presence of
the 'class' attribute
+ if (classAttr == null) {
+ className =
this.roleManager.getDefaultClassNameForHint(roleName, instance.getName());
+ } else {
+ className = classAttr.trim();
+ }
+
+ } else {
+ // component-instances names explicitly defined
+ if (compInstanceName.equals(instance.getName())) {
+ className = (classAttr == null) ? null : classAttr.trim();
+ } else {
+ className =
this.roleManager.getDefaultClassNameForHint(roleName, instance.getName());
+ }
+ }
+
+ if (className == null) {
+ String message = "Unable to determine class name for component
named '" + hint +
+ "' at " + instance.getLocation();
+
+ getLogger().error(message);
+ throw new ConfigurationException(message);
+ }
+
+ this.addComponent( className, hint, instance );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Initializable#initialize()
+ */
+ public void initialize()
+ throws Exception {
+ super.initialize();
+
+ List keys = new ArrayList( this.componentHandlers.keySet() );
+
+ for( int i = 0; i < keys.size(); i++ ) {
+ final Object key = keys.get( i );
+ final AbstractComponentHandler handler =
+ (AbstractComponentHandler)this.componentHandlers.get( key );
+
+ try {
+ handler.initialize();
+ } catch( Exception e ) {
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "Caught an exception trying to
initialize "
+ + "of the component handler.", e );
+ }
+ }
+
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ */
+ public void dispose() {
+ Iterator keys = this.componentHandlers.keySet().iterator();
+ List keyList = new ArrayList();
+
+ while( keys.hasNext() ) {
+ Object key = keys.next();
+ AbstractComponentHandler handler =
+ (AbstractComponentHandler)this.componentHandlers.get( key );
+
+ handler.dispose();
+
+ keyList.add( key );
+ }
+
+ keys = keyList.iterator();
+
+ while( keys.hasNext() ) {
+ this.componentHandlers.remove( keys.next() );
+ }
+
+ keyList.clear();
+
+ if ( this.parentLocator != null ) {
+ this.parentLocator.release( this.parentSelector );
+ this.parentLocator = null;
+ this.parentSelector = null;
+ }
+
+ super.dispose();
+ }
+
+ /**
+ * Makes the ComponentHandlers available to subclasses.
+ *
+ * @return A reference to the componentHandler Map.
+ */
+ protected Map getComponentHandlers() {
+ return this.componentHandlers;
+ }
+
+ /** Add a new component to the manager.
+ * @param hint the hint name for the new component.
+ * @param component the class of this component.
+ * @param configuration the configuration for this component.
+ */
+ public void addComponent( final Object hint,
+ final Class component,
+ final Configuration configuration )
+ throws ServiceException {
+ if( this.initialized ) {
+ throw new ServiceException( hint.toString(),
+ "Cannot add components to an initialized ComponentSelector",
null );
+ }
+
+ try {
+ final AbstractComponentHandler handler = getComponentHandler(
this.roleName,
+ component,
+
configuration,
+
this.serviceManager);
+
+ handler.initialize();
+ this.componentHandlers.put( hint, handler );
+
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug(
+ "Adding " + component.getName() + " for hint [" +
hint.toString() + "]" );
+ }
+ } catch (ServiceException se) {
+ throw se;
+ } catch( final Exception e ) {
+ final String message =
+ "Could not set up Component for hint [ " + hint + "]";
+ if( this.getLogger().isErrorEnabled() ) {
+ this.getLogger().error( message, e );
+ }
+
+ throw new ServiceException( hint.toString(), message, e );
+ }
+ }
+
+ /**
+ * Get the name for component-instance elements (i.e. components not
defined
+ * by their role shortcut. If <code>null</code>, any element having a
'class'
+ * attribute will be considered as a component instance.
+ * <p>
+ * The default here is to return <code>null</code>, and subclasses can
redefine
+ * this method to return particular values.
+ *
+ * @return <code>null</code>, but can be changed by subclasses
+ */
+ protected String getComponentInstanceName() {
+ return null;
+ }
+
+ /**
+ * Get the name of the attribute giving the class name of a component.
+ * The default here is "class", but this can be overriden in subclasses.
+ *
+ * @return "<code>class</code>", but can be changed by subclasses
+ */
+ protected String getClassAttributeName() {
+ return "class";
+ }
+
+ /**
+ * Get the name of the attribute giving the default hint to use if
+ * none is given. The default here is "default", but this can be
+ * overriden in subclasses. If this method returns <code>null</code>,
+ * no default hint can be specified.
+ *
+ * @return "<code>default</code>", but can be changed by subclasses
+ */
+ protected String getDefaultHintAttributeName() {
+ return "default";
+ }
+
+ /**
+ * Get the role name for this selector. This is called by
<code>configure()</code>
+ * to set the value of <code>this.roleName</code>.
+ *
+ * @return the role name, or <code>null<code> if it couldn't be determined.
+ */
+ protected String getRoleName(Configuration config) {
+ // Get the role for this selector
+ String name = config.getAttribute("role", null);
+ if (name == null && this.roleManager != null) {
+ name = this.roleManager.getRoleForName(config.getName());
+ }
+
+ return name;
+ }
+
+ /**
+ * Get the default hint, if any for this selector.
+ */
+ public String getDefaultHint() {
+ return this.defaultHint;
+ }
+
+ /**
+ * Does this selector declare a given hint? Check is performed on the
components declared for this
+ * selector only, and <strong>not</strong> those potentially inherited
from the parent selector.
+ *
+ * @param hint the hint to check for
+ * @return <code>true</code> if this selector has the specified hint
+ */
+ protected boolean hasDeclaredComponent(Object hint) {
+ if (hint == null) {
+ hint = this.defaultHint;
+ }
+
+ return this.isSelectable(hint);
+ }
+
+ /**
+ * Set the ComponentLocatorImpl that allows access to a possible
+ * parent of this selector
+ * @param locator
+ * @throws ComponentException
+ */
+ public void setParentLocator(ServiceManager locator, String role)
+ throws ServiceException {
+ if (this.parentSelector != null) {
+ throw new ServiceException(null, "Parent selector is already set");
+ }
+ this.parentLocator = locator;
+
+ // Get the parent, unwrapping it as far as needed
+ Object parent = locator.lookup(role);
+
+ if (parent instanceof CocoonServiceSelector) {
+ this.parentSelector = (CocoonServiceSelector)parent;
+ } else {
+ throw new IllegalArgumentException("Parent selector is not an
extended component selector (" + parent + ")");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.excalibur.component.ExcaliburComponentSelector#canRelease(org.apache.avalon.framework.component.Component)
+ */
+ protected boolean canRelease(Object component) {
+ if ( this.parentSelector != null &&
+ this.parentSelector.canRelease(component) ) {
+ return true;
+ }
+ return this.componentMapping.containsKey( component );
+ }
+
+
+
+}
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+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.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;
+
+/**
+ * Factory for Avalon based components.
+ *
+ * @version CVS $Id: ComponentFactory.java 55172 2004-10-20 17:52:18Z
cziegeler $
+ */
+public class ComponentFactory {
+
+ /** The class which this <code>ComponentFactory</code>
+ * should create.
+ */
+ private final Class componentClass;
+
+ /** The Context for the component
+ */
+ private final Context context;
+
+ /** The service manager for this component
+ */
+ private final ServiceManager serviceManager;
+
+ /** The configuration for this component.
+ */
+ private final Configuration configuration;
+
+ /** The parameters for this component
+ */
+ private Parameters parameters;
+
+ private final Logger logger;
+
+ private final String role;
+
+ private final LoggerManager loggerManager;
+
+ private final RoleManager roleManager;
+
+ /**
+ * Construct a new component factory for the specified component.
+ *
+ * @param componentClass the class to instantiate (must have a default
constructor).
+ * @param configuration the <code>Configuration</code> object to pass to
new instances.
+ * @param seerviceManager the service manager to pass to
<code>Serviceable</code>s.
+ * @param context the <code>Context</code> to pass to
<code>Contexutalizable</code>s.
+ *
+ */
+ public ComponentFactory( final String role,
+ final Class componentClass,
+ final Configuration configuration,
+ final ServiceManager serviceManager,
+ final Context context,
+ final Logger logger,
+ final LoggerManager loggerManager,
+ final RoleManager roleManager) {
+ this.role = role;
+ this.componentClass = componentClass;
+ this.configuration = configuration;
+ this.serviceManager = serviceManager;
+ this.context = context;
+ this.logger = logger;
+ this.loggerManager = loggerManager;
+ this.roleManager = roleManager;
+ }
+
+ /**
+ * Create a new instance
+ */
+ public Object newInstance()
+ throws Exception {
+ final Object component = this.componentClass.newInstance();
+
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "ComponentFactory creating new instance of " +
+ this.componentClass.getName() + "." );
+ }
+
+ if ( component instanceof LogEnabled ) {
+ if( null == this.configuration ) {
+ ContainerUtil.enableLogging( component, this.logger );
+ } else {
+ final String logger = this.configuration.getAttribute(
"logger", null );
+ if( null == logger ) {
+ this.logger.debug( "no logger attribute available, using
standard logger" );
+ ContainerUtil.enableLogging( component, this.logger );
+ } else {
+ this.logger.debug( "logger attribute is " + this.logger );
+ ContainerUtil.enableLogging( component,
this.loggerManager.getLoggerForCategory( logger ) );
+ }
+ }
+ }
+
+
+ if( component instanceof Contextualizable ) {
+ ContainerUtil.contextualize( component, this.context );
+ }
+
+ if( component instanceof Serviceable ) {
+ ContainerUtil.service( component, this.serviceManager );
+ }
+
+ if ( component instanceof CocoonServiceSelector ) {
+
((CocoonServiceSelector)component).setLoggerManager(this.loggerManager);
+
((CocoonServiceSelector)component).setRoleManager(this.roleManager);
+ }
+
+ ContainerUtil.configure( component, this.configuration );
+
+ if( component instanceof Parameterizable ) {
+ if ( this.parameters == null ) {
+ this.parameters = Parameters.fromConfiguration(
this.configuration );
+ }
+ ContainerUtil.parameterize( component, this.parameters );
+ }
+
+ ContainerUtil.initialize( component );
+
+ ContainerUtil.start( component );
+
+ return component;
+ }
+
+ public Class getCreatedClass() {
+ return this.componentClass;
+ }
+
+ /**
+ * Destroy an instance
+ */
+ public void decommission( final Object component )
+ throws Exception {
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "ComponentFactory decommissioning instance of "
+
+ this.componentClass.getName() + "." );
+ }
+
+ ContainerUtil.stop( component );
+ ContainerUtil.dispose( component );
+ }
+
+}
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.avalon.excalibur.pool.Poolable;
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.logger.Logger;
+
+/**
+ * The PoolableComponentHandler to make sure that poolable components are
initialized
+ * destroyed and pooled correctly.
+ * <p>
+ * Components which implement Poolable may be configured to be pooled using
the following
+ * example configuration. This example assumes that the user component class
MyComp
+ * implements Poolable.
+ * <p>
+ * Configuration Example:
+ * <pre>
+ * <my-comp pool-max="8"/>
+ * </pre>
+ * <p>
+ * Roles Example:
+ * <pre>
+ * <role name="com.mypkg.MyComponent"
+ * shorthand="my-comp"
+ * default-class="com.mypkg.DefaultMyComponent"/>
+ * </pre>
+ * <p>
+ * Configuration Attributes:
+ * <ul>
+ * <li>The <code>pool-max</code> attribute is used to set the maximum number
of components which
+ * will be pooled. (Defaults to "8") If additional instances are required,
they're created,
+ * but not pooled.</li>
+ * </ul>
+ *
+ * @version CVS $Id: PoolableComponentHandler.java 55144 2004-10-20 12:26:09Z
ugo $
+ */
+public class PoolableComponentHandler
+extends AbstractComponentHandler {
+
+ /** The default max size of the pool */
+ public static final int DEFAULT_MAX_POOL_SIZE = 8;
+
+ /**
+ * Object used to synchronize access to the get and put methods
+ */
+ protected final Object semaphore = new Object();
+
+ /**
+ * The maximum size of the pool.
+ */
+ private final int max;
+
+ /**
+ * List of the Poolable instances which are available for use.
+ */
+ private LinkedList ready;
+
+ /**
+ * Store the size of the ready list to optimize operations which require
this value.
+ */
+ private int readySize;
+
+ /**
+ * Total number of Poolable instances in the pool
+ */
+ private int size;
+
+ /**
+ * Create a PoolableComponentHandler which manages a pool of Components
+ * created by the specified factory object.
+ *
+ * @param factory The factory object which is responsible for creating the
components
+ * managed by the ComponentHandler.
+ * @param config The configuration to use to configure the pool.
+ */
+ public PoolableComponentHandler( final Logger logger,
+ final ComponentFactory factory,
+ final Configuration config )
+ throws Exception {
+ super(logger, factory);
+
+ final int poolMax = config.getAttributeAsInteger( "pool-max",
DEFAULT_MAX_POOL_SIZE );
+ this.max = ( poolMax <= 0 ? Integer.MAX_VALUE : poolMax );
+
+ // Create the pool lists.
+ this.ready = new LinkedList();
+ }
+
+ /**
+ * Dispose of the ComponentHandler and any associated Pools and Factories.
+ */
+ public void dispose() {
+ super.dispose();
+
+ // Any Poolables in the m_ready list need to be disposed of
+ synchronized( this.semaphore ) {
+ // Remove objects in the ready list.
+ for( Iterator iter = this.ready.iterator(); iter.hasNext(); ) {
+ Poolable poolable = (Poolable)iter.next();
+ iter.remove();
+ this.readySize--;
+ permanentlyRemovePoolable( poolable );
+ }
+
+ if( ( this.size > 0 ) && this.logger.isDebugEnabled() ) {
+ this.logger.debug( "There were " + this.size
+ + " outstanding objects when the pool was
disposed." );
+ }
+ }
+ }
+
+ /**
+ * Permanently removes a poolable from the pool's active list and
+ * destroys it so that it will not ever be reused.
+ * <p>
+ * This method is only called by threads that have m_semaphore locked.
+ */
+ protected void permanentlyRemovePoolable( Object poolable ) {
+ this.size--;
+ this.removePoolable( poolable );
+ }
+
+ /**
+ * Called when an object is being removed permanently from the pool.
+ * This is the method to override when you need to enforce destructional
+ * policies.
+ * <p>
+ * This method is only called by threads that have m_semaphore locked.
+ *
+ * @param poolable Poolable to be completely removed from the pool.
+ */
+ protected void removePoolable( Object poolable ) {
+ try {
+ this.factory.decommission( poolable );
+ } catch( Exception e ) {
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "Error decommissioning object", e );
+ }
+ }
+ }
+
+ /**
+ * Gets a Poolable from the pool. If there is room in the pool, a new
Poolable will be
+ * created. Depending on the parameters to the constructor, the method
may block or throw
+ * an exception if a Poolable is not available on the pool.
+ *
+ * @return Always returns a Poolable. Contract requires that put must
always be called with
+ * the Poolable returned.
+ * @throws Exception An exception may be thrown as described above or if
there is an exception
+ * thrown by the ObjectFactory's newInstance() method.
+ */
+ protected Object doGet() throws Exception {
+ Object poolable;
+ synchronized( this.semaphore ) {
+ // Look for a Poolable at the end of the m_ready list
+ if( this.readySize > 0 ){
+ // A poolable is ready and waiting in the pool
+ poolable = (Poolable)this.ready.removeLast();
+ this.readySize--;
+ } else {
+ // Create a new poolable. May throw an exception if the
poolable can not be
+ // instantiated.
+ poolable = this.factory.newInstance();
+ this.size++;
+
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "Created a new " +
poolable.getClass().getName()
+ + " from the object factory." );
+ }
+ }
+ }
+
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "Got a " + poolable.getClass().getName() + "
from the pool." );
+ }
+
+ return poolable;
+ }
+
+ /**
+ * Returns a poolable to the pool
+ *
+ * @param poolable Poolable to return to the pool.
+ */
+ protected void doPut( final Object poolable ) {
+ // Handle Recyclable objects
+ if( poolable instanceof Recyclable ) {
+ ( (Recyclable)poolable ).recycle();
+ }
+
+ synchronized( this.semaphore ) {
+ if( this.size <= this.max )
+ {
+ if( this.disposed ) {
+ // The pool has already been disposed.
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "Put called for a " +
poolable.getClass().getName()
+ + " after the pool was disposed." );
+ }
+
+ this.permanentlyRemovePoolable( poolable );
+ } else {
+ // There is room in the pool to keep this poolable.
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "Put a " +
poolable.getClass().getName()
+ + " back into the pool." );
+ }
+
+ this.ready.addLast( poolable );
+ this.readySize++;
+
+ }
+ } else {
+ // More Poolables were created than can be held in the pool,
so remove.
+ if( this.logger.isDebugEnabled() ) {
+ this.logger.debug( "No room to put a " +
poolable.getClass().getName()
+ + " back into the pool, so remove it."
);
+ }
+
+ this.permanentlyRemovePoolable( poolable );
+ }
+ }
+ }
+
+
+}
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/RoleManager.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+/**
+ * Default RoleManager implementation. It populates the RoleManager
+ * from a configuration file.
+ *
+ * @version CVS $Id: RoleManager.java 55144 2004-10-20 12:26:09Z ugo $
+ */
+public class RoleManager
+extends AbstractLogEnabled
+implements Configurable {
+
+ /** Map for shorthand to role mapping */
+ private Map shorthands;
+
+ /** Map for role to default classname mapping */
+ private Map classNames;
+
+ /** Map for role->hint to classname mapping */
+ private Map hintClassNames;
+
+ /** Parent <code>RoleManager</code> for nested resolution */
+ private final RoleManager parent;
+
+ /**
+ * Default constructor--this RoleManager has no parent.
+ */
+ public RoleManager() {
+ this.parent = null;
+ }
+
+ /**
+ * Alternate constructor--this RoleManager has the specified
+ * parent.
+ *
+ * @param parent The parent <code>RoleManager</code>.
+ */
+ public RoleManager( RoleManager parent ) {
+ this.parent = parent;
+ }
+
+ /**
+ * Retrieves the real role name from a shorthand name. Usually
+ * the shorthand name refers to a configuration element name. If
+ * this RoleManager does not have the match, and there is a parent
+ * RoleManager, the parent will be asked to resolve the role.
+ *
+ * @param shorthandName The shortname that is an alias for the role.
+ * @return the official role name.
+ */
+ public final String getRoleForName( final String shorthandName ) {
+ final String role = (String)this.shorthands.get( shorthandName );
+
+ if( null == role && null != this.parent ) {
+ return this.parent.getRoleForName( shorthandName );
+ }
+
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "looking up shorthand " + shorthandName +
+ ", returning " + role );
+ }
+
+ return role;
+ }
+
+ /**
+ * Retrieves the default class name for the specified role. This
+ * is only called when the configuration does not specify the
+ * class explicitly. If this RoleManager does not have the match,
+ * and there is a parent RoleManager, the parent will be asked
+ * to resolve the class name.
+ *
+ * @param role The role that has a default implementation.
+ * @return the Fully Qualified Class Name (FQCN) for the role.
+ */
+ public final String getDefaultClassNameForRole( final String role ) {
+ final String className = (String)this.classNames.get( role );
+
+ if( null == className && null != this.parent ) {
+ return this.parent.getDefaultClassNameForRole( role );
+ }
+
+ return className;
+ }
+
+ /**
+ * Retrieves a default class name for a role/hint combination.
+ * This is only called when a role is mapped to a
+ * DefaultComponentSelector, and the configuration elements use
+ * shorthand names for the type of component. If this RoleManager
+ * does not have the match, and there is a parent RoleManager, the
+ * parent will be asked to resolve the class name.
+ *
+ * @param role The role that this shorthand refers to.
+ * @param shorthand The shorthand name for the type of Component
+ * @return the FQCN for the role/hint combination.
+ */
+ public final String getDefaultClassNameForHint( final String role,
+ final String shorthand ) {
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "looking up hintmap for role " + role );
+ }
+
+ final Map hintMap = (Map)this.hintClassNames.get( role );
+
+ if( null == hintMap ) {
+ if( null != this.parent ) {
+ return this.parent.getDefaultClassNameForHint( role, shorthand
);
+ }
+ return "";
+ }
+
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "looking up classname for hint " +
shorthand );
+ }
+
+ final String s = ( String ) hintMap.get( shorthand );
+
+ if( s == null && null != this.parent ) {
+ return this.parent.getDefaultClassNameForHint( role, shorthand );
+ }
+ return s;
+ }
+
+ /**
+ * Reads a configuration object and creates the role, shorthand,
+ * and class name mapping.
+ *
+ * @param configuration The configuration object.
+ * @throws ConfigurationException if the configuration is malformed
+ */
+ public final void configure( final Configuration configuration )
+ throws ConfigurationException {
+ final Map shorts = new HashMap();
+ final Map classes = new HashMap();
+ final Map hintclasses = new HashMap();
+
+ final Configuration[] roles = configuration.getChildren( "role" );
+
+ for( int i = 0; i < roles.length; i++ ) {
+ final String name = roles[ i ].getAttribute( "name" );
+ final String shorthand = roles[ i ].getAttribute( "shorthand" );
+ final String defaultClassName = roles[ i ].getAttribute(
"default-class", null );
+
+ shorts.put( shorthand, name );
+
+ if( null != defaultClassName ) {
+ classes.put( name, defaultClassName );
+ }
+
+ final Configuration[] hints = roles[ i ].getChildren( "hint" );
+ if( hints.length > 0 ) {
+ HashMap hintMap = new HashMap();
+
+ for( int j = 0; j < hints.length; j++ ) {
+ final String shortHand = hints[ j ].getAttribute(
"shorthand" ).trim();
+ String className = hints[ j ].getAttribute( "class"
).trim();
+
+ hintMap.put( shortHand, className );
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "Adding hint type " +
shortHand +
+ " associated with role " +
name +
+ " and class " + className );
+ }
+ }
+
+ hintclasses.put( name, Collections.unmodifiableMap( hintMap )
);
+ }
+
+ if( this.getLogger().isDebugEnabled() ) {
+ this.getLogger().debug( "added Role " + name + " with
shorthand " +
+ shorthand + " for " + defaultClassName );
+ }
+ }
+
+ this.shorthands = Collections.unmodifiableMap( shorts );
+ this.classNames = Collections.unmodifiableMap( classes );
+ this.hintClassNames = Collections.unmodifiableMap( hintclasses );
+ }
+}
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import org.apache.avalon.framework.logger.Logger;
+
+/**
+ * The DefaultComponentHandler to make sure components are initialized
+ * and destroyed correctly.
+ *
+ * @version CVS $Id: SingleThreadedComponentHandler.java 55144 2004-10-20
12:26:09Z ugo $
+ */
+public class SingleThreadedComponentHandler
+extends AbstractComponentHandler {
+
+ /**
+ * Create a SingleThreadedComponentHandler which manages a pool of
Components
+ * created by the specified factory object.
+ *
+ * @param logger The logger to use
+ * @param factory The factory object which is responsible for creating the
components
+ * managed by the handler.
+ */
+ public SingleThreadedComponentHandler( final Logger logger,
+ final ComponentFactory factory ) {
+ super(logger, factory);
+ }
+
+ /**
+ * Get a reference of the desired Component
+ *
+ * @return A component instance.
+ *
+ * @throws Exception If there are any problems encountered acquiring a
+ * component instance.
+ */
+ protected Object doGet()
+ throws Exception {
+ return this.factory.newInstance();
+ }
+
+ /**
+ * Return a reference of the desired Component
+ *
+ * @param component Component to be be put/released back to the handler.
+ */
+ protected void doPut( final Object component ) {
+ try {
+ this.factory.decommission( component );
+ } catch( final Exception e ) {
+ if( this.logger.isWarnEnabled() )
+ {
+ this.logger.warn( "Error decommissioning component: "
+ + this.factory.getCreatedClass().getName(), e );
+ }
+ }
+ }
+
+}
Added:
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import org.apache.avalon.framework.logger.Logger;
+
+/**
+ * The ThreadSafeComponentHandler to make sure components are initialized
+ * and destroyed correctly.
+ *
+ * @version CVS $Id: ThreadSafeComponentHandler.java 55144 2004-10-20
12:26:09Z ugo $
+ */
+public class ThreadSafeComponentHandler
+extends AbstractComponentHandler {
+
+ private Object instance;
+
+ /**
+ * Create a ThreadSafeComponentHandler which manages a single instance
+ * of an object return by the component factory.
+ * @param logger The logger to use
+ * @param factory The factory object which is responsible for creating the
components
+ * managed by the handler.
+ */
+ public ThreadSafeComponentHandler( final Logger logger,
+ final ComponentFactory factory ) {
+ super(logger, factory);
+ }
+
+ public void initialize()
+ throws Exception {
+ if( this.initialized ) {
+ return;
+ }
+ if( this.instance == null ) {
+ this.instance = this.factory.newInstance();
+ }
+ super.initialize();
+ }
+
+ /**
+ * Get a reference of the desired Component
+ */
+ protected Object doGet()
+ throws Exception {
+ return this.instance;
+ }
+
+ /**
+ * Return a reference of the desired Component
+ */
+ protected void doPut( final Object component ) {
+ // nothing to do
+ }
+
+ /**
+ * Dispose of the ComponentHandler and any associated Pools and Factories.
+ */
+ public void dispose() {
+ try {
+ this.factory.decommission( this.instance );
+ this.instance = null;
+ } catch( final Exception e ) {
+ if( this.logger.isWarnEnabled() ) {
+ this.logger.warn( "Error decommissioning component: " +
+ this.factory.getCreatedClass().getName(), e
);
+ }
+ }
+ super.dispose();
+ }
+}
Added:
cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java
==============================================================================
--- (empty file)
+++
cocoon/trunk/src/core/test/org/apache/cocoon/core/container/RoleManagerTestCase.java
Thu Oct 21 12:25:56 2004
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.container;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.container.RoleManager;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+
+/**
+ * Test cases for [EMAIL PROTECTED] RoleManager}.
+ *
+ * @version CVS $Id: RoleManagerTestCase.java 55163 2004-10-20 16:41:11Z ugo $
+ */
+public class RoleManagerTestCase extends MockObjectTestCase {
+
+ /**
+ * Constructor for RoleManagerTestCase.
+ * @param name The test name
+ */
+ public RoleManagerTestCase(String name) {
+ super(name);
+ }
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ }
+
+ public void testConfigureWithoutHints() throws ConfigurationException {
+ Mock conf = new Mock(Configuration.class);
+ Mock child0 = new Mock(Configuration.class);
+ Configuration roles[] = new Configuration[1];
+ roles[0] = (Configuration) child0.proxy();
+ Configuration hints[] = new Configuration[0];
+ conf.expects(once()).method("getChildren").with(eq("role"))
+ .will(returnValue(roles));
+ child0.expects(once()).method("getAttribute").with(eq("name"))
+ .will(returnValue("testName"));
+ child0.expects(once()).method("getAttribute").with(eq("shorthand"))
+ .will(returnValue("testShorthand"));
+
child0.expects(once()).method("getAttribute").with(eq("default-class"),
eq(null))
+ .will(returnValue("testClass"));
+ child0.expects(once()).method("getChildren").with(eq("hint"))
+ .will(returnValue(hints));
+ Mock logger = new Mock(Logger.class);
+
logger.expects(this.atLeastOnce()).method("isDebugEnabled").will(returnValue(false));
+ RoleManager rm = new RoleManager(null);
+ rm.enableLogging((Logger) logger.proxy());
+ rm.configure((Configuration) conf.proxy());
+ conf.verify();
+ child0.verify();
+ assertEquals("Role name for shorthand incorrect", "testName",
rm.getRoleForName("testShorthand"));
+ assertEquals("Default class for role incorrect", "testClass",
rm.getDefaultClassNameForRole("testName"));
+ assertEquals("Default class for hint must be empty", "",
rm.getDefaultClassNameForHint("testName", "testShorthand"));
+ }
+
+}
Modified: cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java Thu Oct 21 12:25:56 2004
@@ -23,17 +23,10 @@
import java.util.Enumeration;
import java.util.Map;
-import org.apache.avalon.excalibur.component.ComponentProxyGenerator;
-import org.apache.avalon.excalibur.component.DefaultRoleManager;
-import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
import org.apache.avalon.excalibur.logger.LoggerManager;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
-import org.apache.avalon.framework.component.Component;
-import org.apache.avalon.framework.component.ComponentException;
-import org.apache.avalon.framework.component.ComponentManager;
-import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
@@ -45,15 +38,17 @@
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.components.ContextHelper;
-import org.apache.cocoon.components.container.CocoonComponentManager;
import org.apache.cocoon.components.container.ComponentContext;
-import org.apache.cocoon.components.container.ComponentManagerWrapper;
import org.apache.cocoon.components.source.SourceUtil;
import org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper;
+import org.apache.cocoon.core.container.CocoonServiceManager;
+import org.apache.cocoon.core.container.RoleManager;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
@@ -66,8 +61,6 @@
import org.apache.excalibur.event.command.CommandManager;
import org.apache.excalibur.event.command.TPCThreadManager;
import org.apache.excalibur.event.command.ThreadManager;
-import org.apache.excalibur.instrument.InstrumentManageable;
-import org.apache.excalibur.instrument.InstrumentManager;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.apache.excalibur.source.impl.URLSource;
@@ -86,14 +79,13 @@
public class Cocoon
extends AbstractLogEnabled
implements ThreadSafe,
- Component,
Initializable,
Disposable,
Modifiable,
Processor,
Contextualizable,
- Composable,
- InstrumentManageable {
+ Serviceable {
+
static Cocoon instance;
private ThreadManager threads;
@@ -112,20 +104,14 @@
/** The logger manager */
private LoggerManager loggerManager;
- /** The instrument manager */
- private InstrumentManager instrumentManager;
-
/** The classpath (null if not available) */
private String classpath;
/** The working directory (null if not available) */
private File workDir;
- /** The component manager. */
- private ExcaliburComponentManager componentManager;
-
- /** The parent component manager. */
- private ComponentManager parentComponentManager;
+ /** The parent service manager. */
+ private ServiceManager parentComponentManager;
/** flag for disposed or not */
private boolean disposed = false;
@@ -142,8 +128,8 @@
/** The environment helper */
protected EnvironmentHelper environmentHelper;
- /** A service manager (wrapper) */
- protected ServiceManager serviceManager;
+ /** A service manager */
+ protected CocoonServiceManager serviceManager;
/** An optional Avalon Component that is called before and after
processing all requests. */
protected RequestListener requestListener;
@@ -163,13 +149,13 @@
}
/**
- * Get the parent component manager. For purposes of
+ * Get the parent service manager. For purposes of
* avoiding extra method calls, the manager parameter may be null.
*
* @param manager the parent component manager. May be <code>null</code>
*/
- public void compose(ComponentManager manager)
- throws ComponentException {
+ public void service(ServiceManager manager)
+ throws ServiceException {
this.parentComponentManager = manager;
}
@@ -238,29 +224,21 @@
}
/**
- * Set the <code>InstrumentManager</code> for this Cocoon instance.
- *
- * @param manager an <code>InstrumentManager</code> instance
- */
- public void setInstrumentManager(final InstrumentManager manager) {
- this.instrumentManager = manager;
- }
-
- /**
* The <code>initialize</code> method
*
* @exception Exception if an error occurs
*/
public void initialize() throws Exception {
if (parentComponentManager != null) {
- this.componentManager = new
CocoonComponentManager(parentComponentManager,
+ // TODO: wrap parent component manager
+ this.serviceManager = new CocoonServiceManager(null,
(ClassLoader)
this.context.get(Constants.CONTEXT_CLASS_LOADER));
} else {
- this.componentManager = new CocoonComponentManager((ClassLoader)
this.context.get(Constants.CONTEXT_CLASS_LOADER));
+ this.serviceManager = new CocoonServiceManager(null,
+ (ClassLoader)
this.context.get(Constants.CONTEXT_CLASS_LOADER));
}
- ContainerUtil.enableLogging(this.componentManager,
getLogger().getChildLogger("manager"));
- ContainerUtil.contextualize(this.componentManager, this.context);
- this.componentManager.setInstrumentManager(this.instrumentManager);
+ ContainerUtil.enableLogging(this.serviceManager,
getLogger().getChildLogger("manager"));
+ ContainerUtil.contextualize(this.serviceManager, this.context);
if (getLogger().isDebugEnabled()) {
getLogger().debug("New Cocoon object.");
@@ -278,7 +256,7 @@
getLogger().debug("Work directory = " +
workDir.getCanonicalPath());
}
- ExcaliburComponentManager startupManager = new
ExcaliburComponentManager((ClassLoader)
this.context.get(Constants.CONTEXT_CLASS_LOADER));
+ CocoonServiceManager startupManager = new
CocoonServiceManager(null,(ClassLoader)
this.context.get(Constants.CONTEXT_CLASS_LOADER));
ContainerUtil.enableLogging(startupManager,
getLogger().getChildLogger("startup"));
ContainerUtil.contextualize(startupManager, this.context);
startupManager.setLoggerManager(this.loggerManager);
@@ -299,14 +277,11 @@
startupManager = null;
// add the logger manager to the component locator
- final ComponentProxyGenerator proxyGenerator = new
ComponentProxyGenerator();
- final Component loggerManagerProxy =
proxyGenerator.getProxy(LoggerManager.class.getName(),loggerManager);
-
componentManager.addComponentInstance(LoggerManager.ROLE,loggerManagerProxy);
- ContainerUtil.initialize(this.componentManager);
+ ContainerUtil.initialize(this.serviceManager);
// Get the Processor and keep it if it's ThreadSafe
- Processor processor =
(Processor)this.componentManager.lookup(Processor.ROLE);
+ Processor processor =
(Processor)this.serviceManager.lookup(Processor.ROLE);
if (processor instanceof ThreadSafe) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Processor of class " +
processor.getClass().getName() +
@@ -318,20 +293,18 @@
getLogger().debug("Processor of class " +
processor.getClass().getName() +
" is NOT ThreadSafe -- will be looked up at
each request");
}
- this.componentManager.release(processor);
+ this.serviceManager.release(processor);
}
- this.serviceManager = new
ComponentManagerWrapper(this.componentManager);
-
this.environmentHelper = new EnvironmentHelper(
(String) this.context.get(ContextHelper.CONTEXT_ROOT_URL));
ContainerUtil.enableLogging(this.environmentHelper, getLogger());
ContainerUtil.service(this.environmentHelper, this.serviceManager);
- this.sourceResolver =
(SourceResolver)this.componentManager.lookup(SourceResolver.ROLE);
+ this.sourceResolver =
(SourceResolver)this.serviceManager.lookup(SourceResolver.ROLE);
- if (this.componentManager.hasComponent(RequestListener.ROLE)){
- this.requestListener = (RequestListener)
this.componentManager.lookup(RequestListener.ROLE);
+ if (this.serviceManager.hasService(RequestListener.ROLE)){
+ this.requestListener = (RequestListener)
this.serviceManager.lookup(RequestListener.ROLE);
}
}
@@ -359,7 +332,7 @@
* @exception ConfigurationException if an error occurs
* @exception ContextException if an error occurs
*/
- public void configure(ExcaliburComponentManager startupManager) throws
ConfigurationException, ContextException {
+ public void configure(CocoonServiceManager startupManager) throws
ConfigurationException, ContextException {
SAXParser p = null;
Configuration roleConfig = null;
@@ -375,10 +348,10 @@
} catch (Exception e) {
throw new ConfigurationException("Error trying to load
configurations", e);
} finally {
- if (p != null) startupManager.release((Component)p);
+ if (p != null) startupManager.release(p);
}
- DefaultRoleManager drm = new DefaultRoleManager();
+ RoleManager drm = new RoleManager();
ContainerUtil.enableLogging(drm, getLogger().getChildLogger("roles"));
ContainerUtil.configure(drm, roleConfig);
roleConfig = null;
@@ -392,7 +365,7 @@
} catch (Exception e) {
throw new ConfigurationException("Error trying to load
configurations",e);
} finally {
- if (p != null) startupManager.release((Component)p);
+ if (p != null) startupManager.release(p);
}
Configuration conf = this.configuration;
@@ -427,23 +400,23 @@
} catch (Exception e) {
throw new ConfigurationException("Error trying to load
user-roles configuration", e);
} finally {
- startupManager.release((Component)p);
+ startupManager.release(p);
}
- DefaultRoleManager urm = new DefaultRoleManager(drm);
+ RoleManager urm = new RoleManager(drm);
ContainerUtil.enableLogging(urm,
getLogger().getChildLogger("roles").getChildLogger("user"));
ContainerUtil.configure(urm, roleConfig);
roleConfig = null;
drm = urm;
}
- this.componentManager.setRoleManager(drm);
- this.componentManager.setLoggerManager(this.loggerManager);
+ this.serviceManager.setRoleManager(drm);
+ this.serviceManager.setLoggerManager(this.loggerManager);
if (getLogger().isDebugEnabled()) {
getLogger().debug("Setting up components...");
}
- ContainerUtil.configure(this.componentManager, conf);
+ ContainerUtil.configure(this.serviceManager, conf);
}
/**
@@ -494,18 +467,18 @@
ContainerUtil.dispose(this.threads);
this.threads = null;
- if (this.componentManager != null) {
+ if (this.serviceManager != null) {
if (this.requestListener != null) {
- this.componentManager.release(this.requestListener);
+ this.serviceManager.release(this.requestListener);
}
- this.componentManager.release(this.threadSafeProcessor);
+ this.serviceManager.release(this.threadSafeProcessor);
this.threadSafeProcessor = null;
- this.componentManager.release(this.sourceResolver);
+ this.serviceManager.release(this.sourceResolver);
this.sourceResolver = null;
- ContainerUtil.dispose(this.componentManager);
- this.componentManager = null;
+ ContainerUtil.dispose(this.serviceManager);
+ this.serviceManager = null;
}
this.context = null;
@@ -651,7 +624,7 @@
}
}
} else {
- Processor processor =
(Processor)this.componentManager.lookup(Processor.ROLE);
+ Processor processor =
(Processor)this.serviceManager.lookup(Processor.ROLE);
try {
result = processor.process(environment);
if (this.requestListener != null) {
@@ -662,7 +635,7 @@
}
}
} finally {
- this.componentManager.release(processor);
+ this.serviceManager.release(processor);
}
}
// commit response on success
@@ -709,11 +682,11 @@
if (this.threadSafeProcessor != null) {
return this.threadSafeProcessor.buildPipeline(environment);
} else {
- Processor processor =
(Processor)this.componentManager.lookup(Processor.ROLE);
+ Processor processor =
(Processor)this.serviceManager.lookup(Processor.ROLE);
try {
return processor.buildPipeline(environment);
} finally {
- this.componentManager.release(processor);
+ this.serviceManager.release(processor);
}
}
@@ -760,7 +733,10 @@
return this.environmentHelper.getContext();
}
- public ExcaliburComponentManager getComponentManager() {
- return this.componentManager;
+ /**
+ * FIXME - Do we really need this method?
+ */
+ public ServiceManager getServiceManager() {
+ return this.serviceManager;
}
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/bean/BeanListener.java
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/bean/BeanListener.java
(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/bean/BeanListener.java Thu Oct
21 12:25:56 2004
@@ -15,8 +15,6 @@
*/
package org.apache.cocoon.bean;
-import java.util.List;
-
/**
* Interface allowing caller to install a listener so that it can be informed
* as the bean makes progress through the links to be called.
Modified: cocoon/trunk/src/java/org/apache/cocoon/bean/CocoonBean.java
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/bean/CocoonBean.java
(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/bean/CocoonBean.java Thu Oct
21 12:25:56 2004
@@ -98,7 +98,7 @@
super.initialize();
this.sourceResolver =
- (SourceResolver) getComponentManager().lookup(
+ (SourceResolver) getServiceManager().lookup(
SourceResolver.ROLE);
initialized = true;
@@ -328,7 +328,7 @@
public void dispose() {
if (this.initialized) {
if (this.sourceResolver != null) {
- getComponentManager().release(this.sourceResolver);
+ getServiceManager().release(this.sourceResolver);
this.sourceResolver = null;
}
super.dispose();
Modified: cocoon/trunk/src/java/org/apache/cocoon/bean/CocoonWrapper.java
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/bean/CocoonWrapper.java
(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/bean/CocoonWrapper.java Thu Oct
21 12:25:56 2004
@@ -29,7 +29,6 @@
import java.util.Map;
import java.util.TreeMap;
-import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
import org.apache.avalon.excalibur.logger.LogKitLoggerManager;
import org.apache.avalon.framework.configuration.Configuration;
@@ -38,6 +37,7 @@
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
import org.apache.cocoon.Cocoon;
import org.apache.cocoon.Constants;
@@ -63,7 +63,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Upayavira</a>
- * @version CVS $Id: CocoonWrapper.java,v 1.14 2004/07/11 23:02:54 antonio Exp
$
+ * @version CVS $Id$
*/
public class CocoonWrapper {
@@ -160,8 +160,8 @@
initialized = true;
}
- protected ExcaliburComponentManager getComponentManager() {
- return cocoon.getComponentManager();
+ protected ServiceManager getServiceManager() {
+ return cocoon.getServiceManager();
}
/**
Modified:
cocoon/trunk/src/java/org/apache/cocoon/components/container/DefaultSitemapConfigurationHolder.java
==============================================================================
---
cocoon/trunk/src/java/org/apache/cocoon/components/container/DefaultSitemapConfigurationHolder.java
(original)
+++
cocoon/trunk/src/java/org/apache/cocoon/components/container/DefaultSitemapConfigurationHolder.java
Thu Oct 21 12:25:56 2004
@@ -19,10 +19,10 @@
import java.util.HashMap;
import java.util.Map;
-import org.apache.avalon.excalibur.component.RoleManager;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.cocoon.components.ChainedConfiguration;
import org.apache.cocoon.components.SitemapConfigurationHolder;
+import org.apache.cocoon.core.container.RoleManager;
import org.apache.cocoon.environment.internal.EnvironmentHelper;
/**
Modified:
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
==============================================================================
---
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
(original)
+++
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
Thu Oct 21 12:25:56 2004
@@ -21,9 +21,6 @@
import java.util.List;
import java.util.Map;
-import org.apache.avalon.excalibur.component.ExcaliburComponentSelector;
-import org.apache.avalon.excalibur.component.RoleManageable;
-import org.apache.avalon.excalibur.component.RoleManager;
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
@@ -38,8 +35,7 @@
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.avalon.framework.service.Serviceable;
-import org.apache.avalon.framework.service.WrapperServiceSelector;
-import org.apache.cocoon.components.ExtendedComponentSelector;
+import org.apache.cocoon.core.container.CocoonServiceSelector;
import org.apache.cocoon.components.LifecycleHelper;
import org.apache.cocoon.components.source.SourceUtil;
import
org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
@@ -56,7 +52,7 @@
public class DefaultTreeBuilder
extends AbstractLogEnabled
implements TreeBuilder, Contextualizable, Serviceable,
- RoleManageable, Initializable, Recyclable, Disposable {
+ Initializable, Recyclable, Disposable {
protected Map attributes = new HashMap();
@@ -74,12 +70,6 @@
*/
protected ServiceManager ownManager;
- /**
- * The parent role manager, set using <code>setRoleManager</code>
(implementation of
- * <code>RoleManageable</code>).
- */
- protected RoleManager ownRoleManager;
-
// -------------------------------------
/**
@@ -158,7 +148,7 @@
}
// Create the NodeBuilder selector.
- ExcaliburComponentSelector selector = new ExtendedComponentSelector() {
+ CocoonServiceSelector selector = new CocoonServiceSelector() {
protected String getComponentInstanceName() {
return "node";
}
@@ -177,19 +167,12 @@
true
);
- this.builderSelector = new WrapperServiceSelector("BuilderSelector",
selector);
+ this.builderSelector = selector;
}
public void setParentProcessorManager(ServiceManager manager) {
this.parentProcessorManager = manager;
- }
-
- /* (non-Javadoc)
- * @see
org.apache.avalon.excalibur.component.RoleManageable#setRoleManager(org.apache.avalon.excalibur.component.RoleManager)
- */
- public void setRoleManager(RoleManager rm) {
- this.ownRoleManager = rm;
}
/* (non-Javadoc)
Modified:
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
==============================================================================
---
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
(original)
+++
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
Thu Oct 21 12:25:56 2004
@@ -47,7 +47,6 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
* @version CVS $Id$
*/
-
public class TreeProcessor
extends AbstractLogEnabled
implements ThreadSafe,
@@ -147,10 +146,16 @@
return new TreeProcessor(this, delayedSource, checkReload, prefix);
}
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+ */
public void contextualize(Context context) throws ContextException {
this.context = context;
}
+ /* (non-Javadoc)
+ * @see
org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
public void service(ServiceManager manager) throws ServiceException {
this.parentServiceManager = manager;
this.resolver =
(SourceResolver)this.parentServiceManager.lookup(SourceResolver.ROLE);
Modified:
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsSelector.java
==============================================================================
---
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsSelector.java
(original)
+++
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsSelector.java
Thu Oct 21 12:25:56 2004
@@ -18,16 +18,14 @@
import java.util.HashSet;
import java.util.Set;
-import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.component.ComponentException;
-import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.service.ServiceException;
import org.apache.cocoon.acting.Action;
-import org.apache.cocoon.components.ExtendedComponentSelector;
import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.core.container.CocoonServiceSelector;
import org.apache.cocoon.generation.Generator;
import org.apache.cocoon.generation.GeneratorFactory;
import org.apache.cocoon.matching.Matcher;
@@ -41,11 +39,9 @@
/**
* Component selector for sitemap components.
*
- * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @author <a href="mailto:[EMAIL PROTECTED]">Upayavira</a>
* @version CVS $Id$
*/
-public class ComponentsSelector extends ExtendedComponentSelector {
+public class ComponentsSelector extends CocoonServiceSelector {
public static final int UNKNOWN = -1;
public static final int GENERATOR = 0;
@@ -124,7 +120,7 @@
/**
* Add a component in this selector.
*/
- public void addComponent(Object hint, Class clazz, Configuration config)
throws ComponentException {
+ public void addComponent(Object hint, Class clazz, Configuration config)
throws ServiceException {
super.addComponent(hint, clazz, config);
// Add to known hints. This is needed as we cannot call isSelectable()
if initialize()
@@ -174,7 +170,7 @@
// Don't keep known hints (they're no more needed)
this.knownHints = null;
} catch (Exception e) {
- throw new CascadingRuntimeException("Cannot setup default
components", e);
+ throw new RuntimeException("Cannot setup default components", e);
}
}
@@ -183,9 +179,9 @@
* since it requires to be initialized, and we want to add components, and
this must
* be done before initialization.
*/
- private void ensureExists(Object hint, Class clazz, Configuration config)
throws ComponentException {
+ private void ensureExists(Object hint, Class clazz, Configuration config)
throws ServiceException {
if (!this.knownHints.contains(hint)) {
- if (this.parentSelector == null ||
!this.parentSelector.hasComponent(hint)) {
+ if (this.parentSelector == null ||
!this.parentSelector.isSelectable(hint)) {
addComponent(hint, clazz, config);
}
}
@@ -195,8 +191,8 @@
* Override parent to implement support for [EMAIL PROTECTED]
GeneratorFactory},
* [EMAIL PROTECTED] TransformerFactory}, and [EMAIL PROTECTED]
SerializerFactory}.
*/
- public Component select(Object hint) throws ComponentException {
- final Component component = super.select(hint);
+ public Object select(Object hint) throws ServiceException {
+ final Object component = super.select(hint);
switch (this.roleId) {
case GENERATOR:
@@ -223,7 +219,7 @@
* Override parent to implement support for [EMAIL PROTECTED]
GeneratorFactory},
* [EMAIL PROTECTED] TransformerFactory}, and [EMAIL PROTECTED]
SerializerFactory}.
*/
- public void release(Component component) {
+ public void release(Object component) {
// If component is an Instance returned by Factory, get the Factory.
switch (this.roleId) {
Modified:
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
==============================================================================
---
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
(original)
+++
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
Thu Oct 21 12:25:56 2004
@@ -25,21 +25,18 @@
import java.util.Set;
import java.util.StringTokenizer;
-import org.apache.avalon.excalibur.logger.LoggerManager;
-import org.apache.avalon.framework.component.WrapperComponentManager;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.service.WrapperServiceManager;
import org.apache.cocoon.acting.Action;
-import org.apache.cocoon.components.container.CocoonComponentManager;
import org.apache.cocoon.components.pipeline.ProcessingPipeline;
import org.apache.cocoon.components.treeprocessor.CategoryNode;
import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
import org.apache.cocoon.components.treeprocessor.DefaultTreeBuilder;
import org.apache.cocoon.components.treeprocessor.ProcessorComponentInfo;
import
org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.core.container.CocoonServiceManager;
import org.apache.cocoon.generation.Generator;
import org.apache.cocoon.matching.Matcher;
import org.apache.cocoon.reading.Reader;
@@ -79,15 +76,11 @@
config = new DefaultConfiguration("", "");
}
- final LoggerManager loggerManager = (LoggerManager)
this.parentProcessorManager.lookup(LoggerManager.ROLE);
-
- CocoonComponentManager newManager = new CocoonComponentManager(new
WrapperComponentManager(this.parentProcessorManager));
+ CocoonServiceManager newManager = new
CocoonServiceManager(this.parentProcessorManager, null);
// Go through the component lifecycle
newManager.enableLogging(getLogger());
- newManager.setLoggerManager(loggerManager);
newManager.contextualize(this.context);
- newManager.setRoleManager(this.ownRoleManager);
newManager.configure(config);
newManager.initialize();
@@ -112,7 +105,7 @@
setupMimeTypes(config, Reader.ROLE, "readers");
// Wrap the ComponentManager in a ServiceManager
- ServiceManager result = new WrapperServiceManager(newManager);
+ ServiceManager result = newManager;
// Register manager and prevent further modifications
getProcessor().getComponentInfo().setServiceManager(result);
Modified: cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java
(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java Thu Oct
21 12:25:56 2004
@@ -1376,12 +1376,10 @@
ContainerUtil.enableLogging(c, getCocoonLogger());
c.setLoggerManager(getLoggerManager());
ContainerUtil.contextualize(c, this.appContext);
+ // TODO - ServiceManager
final ComponentManager parent = this.getParentComponentManager();
if (parent != null) {
ContainerUtil.compose(c, parent);
- }
- if (this.enableInstrumentation) {
- c.setInstrumentManager(getInstrumentManager());
}
ContainerUtil.initialize(c);
this.creationTime = System.currentTimeMillis();
Modified:
cocoon/trunk/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.java
==============================================================================
---
cocoon/trunk/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.java
(original)
+++
cocoon/trunk/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.java
Thu Oct 21 12:25:56 2004
@@ -19,10 +19,11 @@
import junit.framework.Test;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
+
import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.WrapperServiceManager;
import org.apache.cocoon.Processor;
import org.apache.cocoon.SitemapComponentTestCase;
-import org.apache.cocoon.components.container.ComponentManagerWrapper;
import org.apache.cocoon.environment.internal.EnvironmentHelper;
import org.apache.cocoon.environment.mock.MockEnvironment;
import org.w3c.dom.Document;
@@ -32,7 +33,7 @@
* A simple testcase for AugmentTransformer.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bernhard Huber</a>
- * @version CVS $Id: AugmentTransformerTestCase.java,v 1.1 2004/07/04 18:01:39
huber Exp $
+ * @version CVS $Id$
*/
public class AugmentTransformerTestCase extends SitemapComponentTestCase {
@@ -80,7 +81,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
Document resultDocument = load(result);
Document inputDocument = load(input);
Modified:
cocoon/trunk/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.java
==============================================================================
---
cocoon/trunk/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.java
(original)
+++
cocoon/trunk/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.java
Thu Oct 21 12:25:56 2004
@@ -22,7 +22,7 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.Processor;
import org.apache.cocoon.SitemapComponentTestCase;
-import org.apache.cocoon.components.container.ComponentManagerWrapper;
+import org.apache.avalon.framework.service.WrapperServiceManager;
import org.apache.cocoon.environment.internal.EnvironmentHelper;
import org.apache.cocoon.environment.mock.MockEnvironment;
@@ -30,7 +30,7 @@
* A simple testcase for FilterTransformer.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels </a>
- * @version CVS $Id: CIncludeTransformerTestCase.java,v 1.3 2004/05/25
07:28:26 cziegeler Exp $
+ * @version CVS $Id$
*/
public class CIncludeTransformerTestCase extends SitemapComponentTestCase {
@@ -78,7 +78,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
assertEqual( load(result),
transform("cinclude", src, parameters, load(input)));
@@ -106,7 +106,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
assertEqual( load(result),
transform("cinclude", src, parameters, load(input)));
@@ -134,7 +134,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
assertEqual( load(result),
transform("cinclude", src, parameters, load(input)));
Modified:
cocoon/trunk/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.java
==============================================================================
---
cocoon/trunk/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.java
(original)
+++
cocoon/trunk/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.java
Thu Oct 21 12:25:56 2004
@@ -22,7 +22,7 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.Processor;
import org.apache.cocoon.SitemapComponentTestCase;
-import org.apache.cocoon.components.container.ComponentManagerWrapper;
+import org.apache.avalon.framework.service.WrapperServiceManager;
import org.apache.cocoon.environment.internal.EnvironmentHelper;
import org.apache.cocoon.environment.mock.MockEnvironment;
import org.apache.cocoon.environment.mock.MockRequest;
@@ -35,7 +35,7 @@
* A simple testcase for FilterTransformer.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels </a>
- * @version CVS $Id: EncodeURLTransformerTestCase.java,v 1.1 2004/07/04
18:01:39 huber Exp $
+ * @version CVS $Id$
*/
public class EncodeURLTransformerTestCase extends SitemapComponentTestCase {
@@ -84,7 +84,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
Document inputDocument = load(input);
Document resultDocument = load(result);
@@ -127,7 +127,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
Document inputDocument = load(input);
Document resultDocument = load(result);
Modified:
cocoon/trunk/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.java
==============================================================================
---
cocoon/trunk/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.java
(original)
+++
cocoon/trunk/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.java
Thu Oct 21 12:25:56 2004
@@ -22,7 +22,7 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.Processor;
import org.apache.cocoon.SitemapComponentTestCase;
-import org.apache.cocoon.components.container.ComponentManagerWrapper;
+import org.apache.avalon.framework.service.WrapperServiceManager;
import org.apache.cocoon.environment.internal.EnvironmentHelper;
import org.apache.cocoon.environment.mock.MockEnvironment;
@@ -30,7 +30,7 @@
* A simple testcase for FilterTransformer.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels </a>
- * @version CVS $Id: I18NTransformerTestCase.java,v 1.3 2004/05/25 07:28:26
cziegeler Exp $
+ * @version CVS $Id$
*/
public class I18NTransformerTestCase extends SitemapComponentTestCase {
@@ -78,7 +78,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
assertEqual( load(result),
transform("i18n", src, parameters, load(input)));
@@ -105,7 +105,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
assertEqual( load(result),
transform("i18n", src, parameters, load(input)));
Modified:
cocoon/trunk/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.java
==============================================================================
---
cocoon/trunk/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.java
(original)
+++
cocoon/trunk/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.java
Thu Oct 21 12:25:56 2004
@@ -22,7 +22,7 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.Processor;
import org.apache.cocoon.SitemapComponentTestCase;
-import org.apache.cocoon.components.container.ComponentManagerWrapper;
+import org.apache.avalon.framework.service.WrapperServiceManager;
import org.apache.cocoon.environment.internal.EnvironmentHelper;
import org.apache.cocoon.environment.mock.MockEnvironment;
@@ -30,7 +30,7 @@
* A simple testcase for FilterTransformer.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels </a>
- * @version CVS $Id: XIncludeTransformerTestCase.java,v 1.3 2004/05/25
07:28:26 cziegeler Exp $
+ * @version CVS $Id$
*/
public class XIncludeTransformerTestCase extends SitemapComponentTestCase {
@@ -77,7 +77,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
assertEqual( load(result),
transform("xinclude", src, parameters, load(input)));
@@ -102,7 +102,7 @@
MockEnvironment env = new MockEnvironment();
Processor processor = (Processor)this.manager.lookup(Processor.ROLE);
- EnvironmentHelper.enterProcessor(processor, new
ComponentManagerWrapper(this.manager), env);
+ EnvironmentHelper.enterProcessor(processor, new
WrapperServiceManager(this.manager), env);
assertEqual( load(result),
transform("xinclude", src, parameters, load(input)));