Author: sylvain Date: Sun Jan 2 07:12:01 2005 New Revision: 123887 URL: http://svn.apache.org/viewcvs?view=rev&rev=123887 Log: include feature for components, now available in sitemap. The ProcessorComponentInfo object 'listens' to declaration of sitemap components to grab the additional attributes such as label and mime-type' Added: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractFactoryHandler.java (contents, props changed) cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AliasComponentHandler.java (contents, props changed) cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java - copied, changed from r123885, cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java cocoon/trunk/src/core/java/org/apache/cocoon/core/container/InstanceComponentHandler.java (contents, props changed) cocoon/trunk/src/webapp/sitemap-additions.xconf (contents, props changed) Removed: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java Modified: 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/ComponentFactory.java cocoon/trunk/src/core/java/org/apache/cocoon/core/container/DefaultServiceSelector.java cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java cocoon/trunk/src/core/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java cocoon/trunk/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java cocoon/trunk/src/test/org/apache/cocoon/CocoonTestCase.java cocoon/trunk/src/test/org/apache/cocoon/SitemapComponentTestCase.java cocoon/trunk/src/webapp/sitemap.xmap cocoon/trunk/status.xml cocoon/trunk/tools/targets/webapp-build.xml
Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java&r1=123886&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java Sun Jan 2 07:12:01 2005 @@ -41,9 +41,6 @@ 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; @@ -136,7 +133,7 @@ factory = new ComponentFactory(env, info); } - AbstractComponentHandler handler; + ComponentHandler handler; if( info.getModel() == ServiceInfo.MODEL_POOLED ) { handler = new PoolableComponentHandler( info, logger, factory, configuration ); @@ -153,10 +150,9 @@ /** * Creates a new ComponentHandler. */ - public AbstractComponentHandler(ServiceInfo info, Logger logger, ComponentFactory factory) { - this.info = info; + public AbstractComponentHandler(ServiceInfo info, Logger logger) { this.logger = logger; - this.factory = factory; + this.info = info; } public ServiceInfo getInfo() { @@ -275,24 +271,5 @@ return; } this.initialized = true; - if( this.logger.isDebugEnabled() ) { - this.logger.debug( "ThreadSafeComponentHandler initialized for: " + this.factory.getCreatedClass().getName() ); - } } - - /** - * Decommission a component - * @param component Object to be decommissioned - */ - protected void decommission( 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/AbstractFactoryHandler.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractFactoryHandler.java?view=auto&rev=123887 ============================================================================== --- (empty file) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractFactoryHandler.java Sun Jan 2 07:12:01 2005 @@ -0,0 +1,56 @@ +/* + * 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; +import org.apache.cocoon.components.ServiceInfo; + +/** + * This class acts like a Factory to instantiate the correct version + * of the component handler that you need. + * + * @version CVS $Id$ + */ +public abstract class AbstractFactoryHandler extends AbstractComponentHandler { + + /** This factory is used to created new objects */ + protected final ComponentFactory factory; + + /** + * Creates a new ComponentHandler. + */ + public AbstractFactoryHandler(ServiceInfo info, Logger logger, ComponentFactory factory) { + super(info, logger); + this.factory = factory; + } + + /** + * Decommission a component + * @param component Object to be decommissioned + */ + protected void decommission( 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 ); + } + } + } + +} Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java&r1=123886&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractServiceManager.java Sun Jan 2 07:12:01 2005 @@ -123,7 +123,7 @@ } // FIXME - use different classloader final Class clazz = this.getClass().getClassLoader().loadClass( className ); - this.doAddComponent( role, clazz, configuration ); + this.addComponent( role, clazz, configuration ); } catch( final ClassNotFoundException cnfe ) { final String message = "Could not get class (" + className + ") for role " + role + " at " + configuration.getLocation(); @@ -151,7 +151,7 @@ } } - protected abstract void doAddComponent(String role, Class clazz, Configuration config) + protected abstract void addComponent(String role, Class clazz, Configuration config) throws ServiceException; Added: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AliasComponentHandler.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AliasComponentHandler.java?view=auto&rev=123887 ============================================================================== --- (empty file) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AliasComponentHandler.java Sun Jan 2 07:12:01 2005 @@ -0,0 +1,49 @@ +/* + * 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; +import org.apache.cocoon.components.ServiceInfo; + +/** + * A component handler used to alias roles: it delegates all its calls to another + * handler. + * + * @version SVN $Id$ + */ +public class AliasComponentHandler extends AbstractComponentHandler { + + ComponentHandler aliasedHandler; + + public AliasComponentHandler(Logger logger, ComponentHandler aliasedHandler) { + super(new ServiceInfo(), logger); + getInfo().setConfiguration(CoreServiceManager.EMPTY_CONFIGURATION); + this.aliasedHandler = aliasedHandler; + } + + protected Object doGet() throws Exception { + return this.aliasedHandler.get(); + } + + protected void doPut(Object component) throws Exception { + this.aliasedHandler.put(component); + } + + public boolean isSingleton() { + return this.aliasedHandler.isSingleton(); + } +} Deleted: /cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java?view=auto&rev=123886 ============================================================================== Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java&r1=123886&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java Sun Jan 2 07:12:01 2005 @@ -105,10 +105,20 @@ /** * Create a new instance */ - public Object newInstance() + public final Object newInstance() throws Exception { final Object component = this.serviceClass.newInstance(); + setupInstance(component); + return component; + } + + /** + * Invoke the various lifecycle interfaces to setup a newly created component + * @param component + * @throws Exception + */ + protected void setupInstance(Object component) throws Exception { if( this.environment.logger.isDebugEnabled() ) { this.environment.logger.debug( "ComponentFactory creating new instance of " + this.serviceClass.getName() + "." ); @@ -133,8 +143,6 @@ } ContainerUtil.start( component ); - - return component; } public Class getCreatedClass() { Copied: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java (from r123885, cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java) Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java&r1=123885&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java Sun Jan 2 07:12:01 2005 @@ -45,10 +45,16 @@ * * @version SVN $Revision: 1.6 $Id$ */ -public class CocoonServiceManager +public class CoreServiceManager extends AbstractServiceManager implements ServiceManager, Configurable { + /** + * An empty configuration object, that can be used when no configuration is known but one + * is needed. + */ + public static final Configuration EMPTY_CONFIGURATION = new DefaultConfiguration("-", "unknown location"); + /** The location where this manager is defined */ protected String location; @@ -68,21 +74,25 @@ private SourceResolver cachedSourceResolver; /** Create the ServiceManager with a parent ServiceManager */ - public CocoonServiceManager( final ServiceManager parent ) { + public CoreServiceManager( final ServiceManager parent ) { this.parentManager = parent; RoleManager parentRoleManager = null; // get role manager and logger manager - if ( parent instanceof CocoonServiceManager ) { - parentRoleManager = ((CocoonServiceManager)parent).roleManager; - this.loggerManager = ((CocoonServiceManager)parent).loggerManager; + if ( parent instanceof CoreServiceManager ) { + parentRoleManager = ((CoreServiceManager)parent).roleManager; + this.loggerManager = ((CoreServiceManager)parent).loggerManager; } // Always create a role manager, it can be filled several times either through // the root "roles" attribute or through loading of includes this.roleManager = new RoleManager(parentRoleManager); } - + + //============================================================================================= + // Avalon lifecycle + //============================================================================================= + /* (non-Javadoc) * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger) */ @@ -92,6 +102,180 @@ } /* (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.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration) + */ + public void configure(Configuration configuration) throws ConfigurationException { + // Setup location + this.location = configuration.getLocation(); + + // Find the current URI + String currentURI; + int pos = this.location.lastIndexOf(':'); + if (pos == -1) { + // No available location: start at the context + currentURI = "context://"; + } else { + pos = this.location.lastIndexOf(':', pos); + currentURI = this.location.substring(0, pos-1); + } + + try { + // and load configuration with a empty list of loaded configurations + parseConfiguration(configuration, currentURI, new HashSet()); + } finally { + // Release any source resolver that may have been created to load includes + releaseCachedSourceResolver(); + } + } + + /* (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 ComponentHandler handler = + (ComponentHandler)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 ComponentHandler handler = + (ComponentHandler)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(); + + // Initialize parent aware components + if (this.parentAwareComponents == null) { + throw new ServiceException(null, "CoreServiceManager already initialized"); + } + + // Set parents for parentAware components + Iterator iter = this.parentAwareComponents.iterator(); + while (iter.hasNext()) { + String role = (String)iter.next(); + if ( this.parentManager != null && this.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 ); + } + } + } + this.parentAwareComponents = null; // null to save memory, and catch logic bugs. + +// Object[] keyArray = this.componentHandlers.keySet().toArray(); +// java.util.Arrays.sort(keyArray); +// for (int i = 0; i < keyArray.length; i++) { +// System.err.println("Component key = " + keyArray[i]); +// } + } + + /* (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 ComponentHandler handler = + (ComponentHandler)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(); + } + + //============================================================================================= + // ServiceManager implementation + //============================================================================================= + + /* (non-Javadoc) + * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String) + */ + public boolean hasService( final String role ) { + if( !this.initialized || 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#lookup(java.lang.String) */ public Object lookup( final String role ) @@ -99,18 +283,18 @@ if( !this.initialized ) { if( this.getLogger().isWarnEnabled() ) { this.getLogger().warn( - "Looking up component on an uninitialized CocoonServiceManager [" + role + "]" ); + "Looking up component on an uninitialized CoreServiceManager [" + role + "]" ); } } if( this.disposed ) { throw new IllegalStateException( - "You cannot lookup components on a disposed CocoonServiceManager" ); + "You cannot lookup components on a disposed CoreServiceManager" ); } if( role == null ) { final String message = - "CocoonServiceManager attempted to retrieve service with null role."; + "CoreServiceManager attempted to retrieve service with null role."; if( this.getLogger().isErrorEnabled() ) { this.getLogger().error( message ); @@ -225,31 +409,6 @@ return component; } - /** - * Initialize the component - * @throws ServiceException - */ - protected void initialize(String role, Object component) - throws ServiceException { - // we do nothing here, can be used in subclasses - } - - /* (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) */ @@ -294,34 +453,135 @@ } } - /* (non-Javadoc) - * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration) + //============================================================================================= + // Additional public & protected contract + //============================================================================================= + + /** + * 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 configure(Configuration configuration) throws ConfigurationException { - // Setup location - this.location = configuration.getLocation(); + public void addComponent( final String role, + final Class component, + final Configuration configuration ) + throws ServiceException { + if( this.initialized ) { + throw new ServiceException( role, + "Cannot add components to an initialized CoreServiceManager." ); + } + + ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role); + if (handler != null) { + // Overloaded component: we only allow selectors to be overloaded + ServiceInfo info = handler.getInfo(); + // FIXME - info should not contain the class, we need to get it from somewhere else + if (!DefaultServiceSelector.class.isAssignableFrom(component) || + !DefaultServiceSelector.class.isAssignableFrom(info.getServiceClass())) { + throw new ServiceException(role, "Component declared at " + info.getLocation() + " is redefined at " + + configuration.getLocation()); + } + } + try { + handler = this.getComponentHandler(role, component, configuration, this); + + if( this.getLogger().isDebugEnabled() ) { + this.getLogger().debug( "Handler type = " + handler.getClass().getName() ); + } + + this.componentHandlers.put( role, handler ); + this.newComponentHandlers.add( handler ); + } catch ( final ServiceException se ) { + throw se; + } catch( final Exception e ) { + throw new ServiceException( role, "Could not set up component handler.", e ); + } - // Find the current URI - String currentURI; - int pos = this.location.lastIndexOf(':'); - if (pos == -1) { - // No available location: start at the context - currentURI = "context://"; - } else { - pos = this.location.lastIndexOf(':', pos); - currentURI = this.location.substring(0, pos-1); + if ( CocoonServiceSelector.class.isAssignableFrom( component ) ) { + this.parentAwareComponents.add(role); + } + // Initialize shadow selector now, it will feed this service manager + if ( DefaultServiceSelector.class.isAssignableFrom( component )) { + try { + handler.initialize(); + } catch(ServiceException se) { + throw se; + } catch(Exception e) { + throw new ServiceException(role, "Could not initialize selector", e); + } + } + } + + /** + * Add an existing object to the manager. The object should be fully configured as no + * setup lifecycle methods are called. On manager disposal, the <code>Disposable</code> + * method is considered. + * + * @param role the role under which the object will be known + * @param instance the component instance + * @throws ServiceException + */ + public void addInstance(String role, Object instance) throws ServiceException { + if( this.initialized ) { + throw new ServiceException(role, + "Cannot add components to an initialized CoreServiceManager."); } - try { - // and load configuration with a empty list of loaded configurations - doConfigure(configuration, currentURI, new HashSet()); - } finally { - // Release any source resolver that may have been created to load includes - releaseCachedSourceResolver(); + ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role); + if (handler != null) { + ServiceInfo info = handler.getInfo(); + throw new ServiceException(role, "Component already defined at " + info.getLocation()); } + + this.componentHandlers.put(role, new InstanceComponentHandler(getLogger(), instance)); } - - private void doConfigure(final Configuration configuration, String contextURI, Set loadedURIs) + + /** + * Add an alias to a role, i.e. define a synonym for the role. + * + * @param existingRole the existing role that will be aliased + * @param newRole the new role + * @throws ServiceException if the existing role could not be found in the current + * manager and its ancestors + */ + public void addRoleAlias(String existingRole, String newRole) throws ServiceException { + ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(existingRole); + if (handler == null) { + // Aliased component not found here, but can be defined by an ancestor + CoreServiceManager current = this; + while(handler == null && current.parentManager != null) { + if (!(current.parentManager instanceof CoreServiceManager)) { + throw new ServiceException(newRole, "Cannot alias to components not managed by CoreServiceManager"); + } else { + current = (CoreServiceManager)current.parentManager; + handler = (ComponentHandler)current.componentHandlers.get(existingRole); + } + } + } + + if (handler == null) { + throw new ServiceException(newRole, "Cannot alias non-existing role " + existingRole); + } + + this.componentHandlers.put(newRole, new AliasComponentHandler(this.getLogger(), handler)); + } + + /** + * Initialize the component + * @throws ServiceException + */ + protected void initialize(String role, Object component) + throws ServiceException { + // we do nothing here, can be used in subclasses + } + + //============================================================================================= + // Private methods + //============================================================================================= + + private void parseConfiguration(final Configuration configuration, String contextURI, Set loadedURIs) throws ConfigurationException { final Configuration[] configurations = configuration.getChildren(); @@ -372,7 +632,7 @@ } } - protected void handleInclude(String contextURI, Set loadedURIs, Configuration includeStatement) + private void handleInclude(String contextURI, Set loadedURIs, Configuration includeStatement) throws ConfigurationException { String includeURI = includeStatement.getAttribute("src", null); String directoryURI = null; @@ -418,7 +678,7 @@ } } - protected void loadURI(Source src, Set loadedURIs, Configuration includeStatement) + private void loadURI(Source src, Set loadedURIs, Configuration includeStatement) throws ConfigurationException { // If already loaded: do nothing try { @@ -442,7 +702,7 @@ String includeKind = includeConfig.getName(); if (includeKind.equals("components")) { // more components - doConfigure(includeConfig, uri, loadedURIs); + parseConfiguration(includeConfig, uri, loadedURIs); } else if (includeKind.equals("role-list")) { // more roles this.roleManager.configure(includeConfig); @@ -456,200 +716,11 @@ } } - /* (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 ComponentHandler handler = - (ComponentHandler)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 ComponentHandler handler = - (ComponentHandler)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(); - - // Initialize parent aware components - if (this.parentAwareComponents == null) { - throw new ServiceException(null, "CocoonServiceManager already initialized"); - } - - // Set parents for parentAware components - Iterator iter = this.parentAwareComponents.iterator(); - while (iter.hasNext()) { - String role = (String)iter.next(); - if ( this.parentManager != null && this.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 ); - } - } - } - this.parentAwareComponents = null; // null to save memory, and catch logic bugs. - -// Object[] keyArray = this.componentHandlers.keySet().toArray(); -// Arrays.sort(keyArray); -// for (int i = 0; i < keyArray.length; i++) { -// System.err.println("Component key = " + keyArray[i]); -// } - } - - /* (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 ComponentHandler handler = - (ComponentHandler)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 doAddComponent( final String role, - final Class component, - final Configuration configuration ) - throws ServiceException { - if( this.initialized ) { - throw new ServiceException( role, - "Cannot add components to an initialized CocoonServiceManager." ); - } - - if( this.getLogger().isDebugEnabled() ) { - this.getLogger().debug( "Attempting to get handler for role [" + role + "]" ); - } - - ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role); - if (handler != null) { - // Overloaded component: we only allow selectors to be overloaded - ServiceInfo info = handler.getInfo(); - // FIXME - info should not contain the class, we need to get it from somewhere else - if (!DefaultServiceSelector.class.isAssignableFrom(component) || - !DefaultServiceSelector.class.isAssignableFrom(info.getServiceClass())) { - throw new ServiceException(role, "Component declared at " + info.getLocation() + " is redefined at " + - configuration.getLocation()); - } - } - try { - handler = this.getComponentHandler(role, component, configuration, this); - - if( this.getLogger().isDebugEnabled() ) { - this.getLogger().debug( "Handler type = " + handler.getClass().getName() ); - } - - this.componentHandlers.put( role, handler ); - this.newComponentHandlers.add( handler ); - } catch ( final ServiceException se ) { - throw se; - } catch( final Exception e ) { - throw new ServiceException( role, "Could not set up component handler.", e ); - } - - if ( CocoonServiceSelector.class.isAssignableFrom( component ) ) { - this.parentAwareComponents.add(role); - } - // Initialize shadow selector now, it will feed this service manager - if ( DefaultServiceSelector.class.isAssignableFrom( component )) { - try { - handler.initialize(); - } catch(ServiceException se) { - throw se; - } catch(Exception e) { - throw new ServiceException(role, "Could not initialize selector", e); - } - } - } - /** * If the parent manager does not exist or does not * provide a source resolver, a simple one is created here to load the file. */ - protected void setupSourceResolver() { + private void setupSourceResolver() { if (this.cachedSourceResolver == null) { if (this.parentManager != null && this.parentManager.hasService(SourceResolver.ROLE)) { Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/DefaultServiceSelector.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/DefaultServiceSelector.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/DefaultServiceSelector.java&r1=123886&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/DefaultServiceSelector.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/DefaultServiceSelector.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/DefaultServiceSelector.java Sun Jan 2 07:12:01 2005 @@ -38,19 +38,20 @@ */ public class DefaultServiceSelector extends AbstractLogEnabled implements ThreadSafe, Serviceable, Configurable, ServiceSelector { - private CocoonServiceManager manager; + /** Synthetic hint to alias the default component */ + public static final String DEFAULT_HINT = "$default$"; + + private CoreServiceManager manager; private RoleManager roleManager; private String roleName; private String rolePrefix; - private String defaultKey; - private String location; public void service(ServiceManager manager) throws ServiceException { try { - this.manager = (CocoonServiceManager)manager; + this.manager = (CoreServiceManager)manager; } catch (ClassCastException cce) { throw new ServiceException ("DefaultServiceSelector", - "A FlatServiceSelector can only be hosted by a CocoonServiceManager"); + "A DefaultServiceSelector can only be hosted by a CoreServiceManager"); } } @@ -63,12 +64,9 @@ } public void configure(Configuration config) throws ConfigurationException { - // Get the role for this selector - - this.location = config.getLocation(); - + if (roleName == null) { - throw new ConfigurationException("No role given for DefaultServiceSelector at " + this.location); + throw new ConfigurationException("No role given for DefaultServiceSelector at " + config.getLocation()); } // Remove "Selector" suffix, if any and add a trailing "/" @@ -78,9 +76,6 @@ this.rolePrefix = roleName + "/"; } - // Get default key - this.defaultKey = config.getAttribute(this.getDefaultKeyAttributeName(), null); - // Add components String compInstanceName = getComponentInstanceName(); @@ -125,20 +120,26 @@ // Add this component in the manager this.manager.addComponent(className, this.rolePrefix + key, instance); } + + // Register default key, if any + String defaultKey = config.getAttribute(this.getDefaultKeyAttributeName(), null); + if (defaultKey != null) { + try { + this.manager.addRoleAlias(this.rolePrefix + defaultKey, this.rolePrefix + DEFAULT_HINT); + } catch (ServiceException e) { + throw new ConfigurationException("Cannot set default to " + defaultKey + " at " + config.getLocation(), e); + } + } } public Object select(Object hint) throws ServiceException { - String key = (hint == null) ? this.defaultKey : hint.toString(); - - if (key == null) { - throw new ServiceException(roleName, "Hint is null and no default hint provided for selector at " + this.location); - } + String key = (hint == null) ? DEFAULT_HINT : hint.toString(); return this.manager.lookup(this.rolePrefix + key); } public boolean isSelectable(Object hint) { - String key = hint == null ? this.defaultKey : hint.toString(); + String key = hint == null ? DEFAULT_HINT : hint.toString(); return key != null && this.manager.hasService(this.rolePrefix + key); } @@ -199,10 +200,10 @@ this.roleManager = manager; } - public Object newInstance() + protected void setupInstance(Object object) throws Exception { - final DefaultServiceSelector component = (DefaultServiceSelector)this.serviceClass.newInstance(); - + DefaultServiceSelector component = (DefaultServiceSelector)object; + ContainerUtil.enableLogging(component, this.environment.logger); ContainerUtil.contextualize(component, this.environment.context); ContainerUtil.service(component, this.environment.serviceManager); @@ -213,8 +214,6 @@ ContainerUtil.configure(component, this.serviceInfo.getConfiguration()); ContainerUtil.initialize(component); ContainerUtil.start(component); - - return component; } } } Added: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/InstanceComponentHandler.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/InstanceComponentHandler.java?view=auto&rev=123887 ============================================================================== --- (empty file) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/InstanceComponentHandler.java Sun Jan 2 07:12:01 2005 @@ -0,0 +1,68 @@ +/* + * Copyright 2002-2005 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.activity.Disposable; +import org.apache.avalon.framework.logger.Logger; +import org.apache.cocoon.components.ServiceInfo; + +/** + * A component handler for instances created outside the container. + * + * @version SVN $Id$ + */ +public class InstanceComponentHandler extends AbstractComponentHandler { + + private Object obj; + + /** + * Creates a new ComponentHandler. + */ + public InstanceComponentHandler(Logger logger, Object obj) { + super(new ServiceInfo(), logger); + // For info.getLocation() to work properly + this.getInfo().setConfiguration(CoreServiceManager.EMPTY_CONFIGURATION); + this.obj = obj; + } + + public boolean isSingleton() { + return true; + } + + /* (non-Javadoc) + * @see org.apache.cocoon.core.container.AbstractComponentHandler#doGet() + */ + protected Object doGet() throws Exception { + return this.obj; + } + + /* (non-Javadoc) + * @see org.apache.cocoon.core.container.AbstractComponentHandler#doPut(java.lang.Object) + */ + protected void doPut(Object component) throws Exception { + // nothing + } + + /* (non-Javadoc) + * @see org.apache.cocoon.core.container.ComponentHandler#dispose() + */ + public void dispose() { + if (this.obj instanceof Disposable) { + ((Disposable)this.obj).dispose(); + } + } +} Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java&r1=123886&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java Sun Jan 2 07:12:01 2005 @@ -53,7 +53,7 @@ * @version CVS $Id$ */ public class PoolableComponentHandler -extends AbstractComponentHandler { +extends AbstractFactoryHandler { /** The default max size of the pool */ public static final int DEFAULT_MAX_POOL_SIZE = 8; @@ -223,6 +223,4 @@ } } } - - } Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java&r1=123886&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/SingleThreadedComponentHandler.java Sun Jan 2 07:12:01 2005 @@ -26,7 +26,7 @@ * @version CVS $Id$ */ public class SingleThreadedComponentHandler -extends AbstractComponentHandler { +extends AbstractFactoryHandler { /** * Create a SingleThreadedComponentHandler which manages a pool of Components Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java&r1=123886&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java Sun Jan 2 07:12:01 2005 @@ -333,7 +333,7 @@ * @param component the class of this component. * @param configuration the configuration for this component. */ - public void doAddComponent( final String key, + public void addComponent( final String key, final Class component, final Configuration configuration ) throws ServiceException { @@ -464,9 +464,9 @@ this.roleManager = roleManager; } - public Object newInstance() + protected void setupObject(Object obj) throws Exception { - final StandaloneServiceSelector component = (StandaloneServiceSelector)this.serviceClass.newInstance(); + final StandaloneServiceSelector component = (StandaloneServiceSelector)obj; ContainerUtil.enableLogging(component, this.environment.logger); ContainerUtil.contextualize(component, this.environment.context); @@ -478,8 +478,6 @@ ContainerUtil.configure(component, this.serviceInfo.getConfiguration()); ContainerUtil.initialize(component); ContainerUtil.start(component); - - return component; } } } Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java&r1=123886&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ThreadSafeComponentHandler.java Sun Jan 2 07:12:01 2005 @@ -26,7 +26,7 @@ * @version CVS $Id$ */ public class ThreadSafeComponentHandler -extends AbstractComponentHandler { +extends AbstractFactoryHandler { private Object instance; Modified: cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java?view=diff&rev=123887&p1=cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java&r1=123886&p2=cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java&r2=123887 ============================================================================== --- cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java (original) +++ cocoon/trunk/src/core/test/org/apache/cocoon/core/container/ContainerTestCase.java Sun Jan 2 07:12:01 2005 @@ -258,7 +258,7 @@ * This method may be overwritten by subclasses to add aditional * components. */ - protected void addComponents( CocoonServiceManager manager) + protected void addComponents( CoreServiceManager manager) throws ServiceException { // subclasses can add components here } @@ -272,7 +272,7 @@ roleManager.configure( confRM ); // Set up the ComponentLocator - CocoonServiceManager ecManager = new CocoonServiceManager(null); + CoreServiceManager ecManager = new CoreServiceManager(null); ecManager.enableLogging( this.getLogger() ); ecManager.contextualize( this.context ); ecManager.setRoleManager( roleManager ); Modified: cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/Cocoon.java Sun Jan 2 07:12:01 2005 @@ -221,7 +221,7 @@ startupManager.setLoggerManager(this.loggerManager); try { - startupManager.doAddComponent(SAXParser.ROLE, + startupManager.addComponent(SAXParser.ROLE, ClassUtils.loadClass(parser), new DefaultConfiguration("", "empty")); } catch (Exception e) { Modified: cocoon/trunk/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java Sun Jan 2 07:12:01 2005 @@ -19,28 +19,60 @@ import java.util.HashMap; import java.util.Map; +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.cocoon.components.SitemapConfigurable; import org.apache.cocoon.components.SitemapConfigurationHolder; +import org.apache.cocoon.components.treeprocessor.ProcessorComponentInfo; +import org.apache.cocoon.core.container.CoreServiceManager; /** * 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 org.apache.cocoon.core.container.CocoonServiceManager { +public class CocoonServiceManager extends CoreServiceManager { /** The [EMAIL PROTECTED] SitemapConfigurationHolder}s */ private Map sitemapConfigurationHolders = new HashMap(15); + + private ProcessorComponentInfo info; /** Create the ServiceManager with a parent ServiceManager */ public CocoonServiceManager( final ServiceManager parent) { super( parent ); + ProcessorComponentInfo parentInfo = null; + if (parent != null) { + try { + parentInfo = (ProcessorComponentInfo) parent.lookup(ProcessorComponentInfo.ROLE); + } catch (ServiceException e) { + // no parent + } + } + this.info = new ProcessorComponentInfo(parentInfo); + } + + public void addComponent(String role, Class clazz, Configuration config) throws ServiceException { + super.addComponent(role, clazz, config); + // Let's ProcessorComponentInfo do its stuff. + // Note: if more behaviours of this kind are needed, we may setup an + // event listener mechanism on the core service manager + this.info.componentAdded(role, clazz, config); } + public void addRoleAlias(String existingRole, String newRole) throws ServiceException { + super.addRoleAlias(existingRole, newRole); + this.info.roleAliased(existingRole, newRole); + } + + public void initialize() throws Exception { + this.info.lock(); + this.addInstance(ProcessorComponentInfo.ROLE, this.info); + super.initialize(); + } + /* (non-Javadoc) * @see org.apache.cocoon.core.container.CocoonServiceManager#initialize(java.lang.String, java.lang.Object) */ Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java Sun Jan 2 07:12:01 2005 @@ -42,7 +42,7 @@ */ public void setBuilder(TreeBuilder treeBuilder) { this.treeBuilder = treeBuilder; - this.manager = treeBuilder.getProcessor().getComponentInfo().getServiceManager(); + this.manager = treeBuilder.getBuiltProcessorManager(); } /** Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java Sun Jan 2 07:12:01 2005 @@ -15,10 +15,13 @@ */ package org.apache.cocoon.components.treeprocessor; +import java.io.IOException; +import java.util.List; + import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.logger.AbstractLogEnabled; - +import org.apache.avalon.framework.service.ServiceManager; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.Processor; import org.apache.cocoon.components.source.impl.SitemapSourceInfo; @@ -31,9 +34,6 @@ import org.apache.cocoon.environment.wrapper.MutableEnvironmentFacade; import org.apache.cocoon.sitemap.SitemapExecutor; -import java.io.IOException; -import java.util.List; - /** * The concrete implementation of [EMAIL PROTECTED] Processor}, containing the evaluation tree and associated * data such as component manager. @@ -42,6 +42,9 @@ */ public class ConcreteTreeProcessor extends AbstractLogEnabled implements Processor { + /** Our ServiceManager */ + private ServiceManager manager; + /** The processor that wraps us */ private TreeProcessor wrappingProcessor; @@ -51,9 +54,6 @@ /** Root node of the processing tree */ private ProcessingNode rootNode; - /** The component info needed to build child processors */ - private ProcessorComponentInfo componentInfo; - private Configuration componentConfigurations; /** Number of simultaneous uses of this processor (either by concurrent request or by internal requests) */ @@ -66,33 +66,25 @@ * Builds a concrete processig, given the wrapping processor */ public ConcreteTreeProcessor(TreeProcessor wrappingProcessor, - SitemapExecutor sitemapExecutor, - ProcessorComponentInfo componentInfo) { + SitemapExecutor sitemapExecutor) { // Store our wrapping processor this.wrappingProcessor = wrappingProcessor; - // Initialize component info - this.componentInfo = new ProcessorComponentInfo(componentInfo); - // Get the sitemap executor - we use the same executor for each sitemap this.sitemapExecutor = sitemapExecutor; } - + /** Set the processor data, result of the treebuilder job */ - public void setProcessorData(ProcessingNode rootNode, List disposableNodes) { + public void setProcessorData(ServiceManager manager, ProcessingNode rootNode, List disposableNodes) { if (this.rootNode != null) { throw new IllegalStateException("setProcessorData() can only be called once"); } + this.manager = manager; this.rootNode = rootNode; this.disposableNodes = disposableNodes; } - /** Get the component info for this processor */ - public ProcessorComponentInfo getComponentInfo() { - return this.componentInfo; - } - /** Set the sitemap component configurations (called as part of the tree building process) */ public void setComponentConfigurations(Configuration componentConfigurations) { this.componentConfigurations = componentConfigurations; @@ -197,14 +189,14 @@ try { // and now process - EnvironmentHelper.enterProcessor(this, this.componentInfo.getServiceManager(), environment); + EnvironmentHelper.enterProcessor(this, this.manager, environment); final Redirector oldRedirector = context.getRedirector(); // Build a redirector TreeProcessorRedirector redirector = new TreeProcessorRedirector(environment, context); setupLogger(redirector); context.setRedirector(redirector); - context.service(this.componentInfo.getServiceManager()); + context.service(this.manager); context.setLastProcessor(this); try { @@ -330,5 +322,9 @@ */ public SitemapExecutor getSitemapExecutor() { return this.sitemapExecutor; + } + + public ServiceManager getServiceManager() { + return this.manager; } } Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java Sun Jan 2 07:12:01 2005 @@ -105,6 +105,11 @@ */ private ServiceSelector itsBuilders; + /** + * The sitemap component information grabbed while building itsMaanger + */ + protected ProcessorComponentInfo itsComponentInfo; + // ------------------------------------- /** @@ -224,6 +229,10 @@ public ConcreteTreeProcessor getProcessor() { return this.processor; } + + public ServiceManager getBuiltProcessorManager() { + return this.itsManager; + } /** @@ -317,6 +326,7 @@ // Context and manager for the sitemap we build this.itsContext = createContext(tree); this.itsManager = createServiceManager(this.itsContext, tree); + this.itsComponentInfo = (ProcessorComponentInfo)this.itsManager.lookup(ProcessorComponentInfo.ROLE); // Create a helper object to setup components this.itsLifecycle = new LifecycleHelper(getLogger(), @@ -472,7 +482,7 @@ // Get the component type for the statement String type = statement.getAttribute("type", null); if (type == null) { - type = getProcessor().getComponentInfo().getDefaultType(role); + type = this.itsComponentInfo.getDefaultType(role); } if (type == null) { @@ -491,12 +501,12 @@ e); } - this.itsManager.release(selector); - if (!selector.isSelectable(type)) { throw new ConfigurationException("Type '" + type + "' does not exist for 'map:" + statement.getName() + "' at " + statement.getLocation()); } + + this.itsManager.release(selector); return type; } Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java Sun Jan 2 07:12:01 2005 @@ -15,10 +15,24 @@ */ package org.apache.cocoon.components.treeprocessor; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.service.ServiceManager; +import org.apache.cocoon.acting.Action; +import org.apache.cocoon.components.pipeline.ProcessingPipeline; +import org.apache.cocoon.core.container.DefaultServiceSelector; +import org.apache.cocoon.generation.Generator; +import org.apache.cocoon.matching.Matcher; +import org.apache.cocoon.reading.Reader; +import org.apache.cocoon.selection.Selector; +import org.apache.cocoon.serialization.Serializer; +import org.apache.cocoon.transformation.Transformer; /** * Holds informations defined in <map:components> such as default hint, labels and mime-types @@ -27,12 +41,31 @@ * In previous versions of the sitemap engine, these informations where store in specialized * extensions of ComponentSelector (<code>SitemapComponentSelector</code> and * <code>OutputComponentSelector</code>), which led to a strong dependency on the chosen component - * container implementation. + * container implementation. This is now a regular component that also "listens" to modifications + * of the service manager when it is built. * * @version CVS $Id$ */ public class ProcessorComponentInfo { + public static final String ROLE = ProcessorComponentInfo.class.getName(); + + private static final String GENERATOR_PREFIX = Generator.ROLE + "/"; + private static final String TRANSFORMER_PREFIX = Transformer.ROLE + "/"; + private static final String SERIALIZER_PREFIX = Serializer.ROLE + "/"; + private static final String READER_PREFIX = Reader.ROLE + "/"; + + private static final Set DEFAULT_ROLES = new HashSet(Arrays.asList(new String[] { + Generator.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT, + Transformer.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT, + Serializer.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT, + Reader.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT, + ProcessingPipeline.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT, + Matcher.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT, + Selector.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT, + Action.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT + })); + /** Component info for the parent processor */ ProcessorComponentInfo parent; @@ -52,15 +85,68 @@ this.parent = parent; } - public void setServiceManager(ServiceManager manager) { - if (locked) throw new IllegalStateException("ProcessorComponentInfo is locked"); - this.manager = manager; + /** + * Grabs on the fly the sitemap-related information on generators, transformers, + * serializers and readers when they're declared in the <code>ServiceManager</code>. + * <p> + * This method is triggered when a component is added on a <code>CocoonServiceManager</code>. + * + * @param role the component's role + * @param clazz the component's class + * @param config the component's configuration + */ + public void componentAdded(String role, Class clazz, Configuration config) { + if (role.startsWith(GENERATOR_PREFIX)) { + setupLabelAndPipelineHint(role, config); + + } else if (role.startsWith(TRANSFORMER_PREFIX)) { + setupLabelAndPipelineHint(role, config); + + } else if (role.startsWith(SERIALIZER_PREFIX)) { + setupLabelAndPipelineHint(role, config); + setupMimeType(role, config); + + } else if (role.startsWith(READER_PREFIX)) { + setupMimeType(role, config); + } } - public ServiceManager getServiceManager() { - return this.manager; + public void roleAliased(String existingRole, String newRole) { + if (DEFAULT_ROLES.contains(newRole)) { + // A default role for a sitemap component has been added + int pos = existingRole.indexOf('/'); + String role = existingRole.substring(0, pos); + String hint = existingRole.substring(pos+1); + + this.setDefaultType(role, hint); + } } + private void setupLabelAndPipelineHint(String role, Configuration config) { + + // Labels + String label = config.getAttribute("label", null); + if (label != null) { + StringTokenizer st = new StringTokenizer(label, " ,", false); + String[] labels = new String[st.countTokens()]; + for (int tokenIdx = 0; tokenIdx < labels.length; tokenIdx++) { + labels[tokenIdx] = st.nextToken(); + } + setLabels(role, labels); + } else { + // Set no labels, overriding those defined in the parent sitemap, if any + setLabels(role, null); + } + + // Pipeline hints + String pipelineHint = config.getAttribute("hint", null); + setPipelineHint(role, pipelineHint); + } + + private void setupMimeType(String role, Configuration config) { + setMimeType(role, config.getAttribute("mime-type", null)); + } + /** Store some data, creating the storage map if needed */ private void setData(String key, Object value) { if (locked) throw new IllegalStateException("ProcessorComponentInfo is locked"); @@ -89,7 +175,7 @@ this.locked = true; } - public void setDefaultType(String role, String hint) { + private void setDefaultType(String role, String hint) { setData("defaultType/" + role, hint); } @@ -97,24 +183,24 @@ return (String)getData("defaultType/" + role); } - public void setPipelineHint(String role, String type, String hint) { - setData("pipelineHint/" + role + "/" + type, hint); + private void setPipelineHint(String role, String hint) { + setData("pipelineHint/" + role, hint); } public String getPipelineHint(String role, String type) { return (String)getData("pipelineHint/" + role + "/" + type); } - public void setMimeType(String role, String type, String mimeType) { - setData("mimeType/" + role + "/" + type, mimeType); + private void setMimeType(String role, String mimeType) { + setData("mimeType/" + role, mimeType); } public String getMimeType(String role, String type) { return (String)getData("mimeType/" + role + "/" + type); } - public void setLabels(String role, String type, String[] labels) { - setData("labels/" + role + "/" + type, labels); + private void setLabels(String role, String[] labels) { + setData("labels/" + role, labels); } public String[] getLabels(String role, String type) { Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java Sun Jan 2 07:12:01 2005 @@ -32,6 +32,8 @@ void setParentProcessorManager(ServiceManager manager); + + ServiceManager getBuiltProcessorManager(); ConcreteTreeProcessor getProcessor(); Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java Sun Jan 2 07:12:01 2005 @@ -130,7 +130,7 @@ this.checkReload = checkReload; this.lastModifiedDelay = parent.lastModifiedDelay; - this.manager = parent.concreteProcessor.getComponentInfo().getServiceManager(); + this.manager = parent.concreteProcessor.getServiceManager(); this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE); this.environmentHelper = new EnvironmentHelper(parent.environmentHelper); @@ -273,9 +273,9 @@ return result; } - /** - * Set the sitemap component configurations - */ +// /** +// * Set the sitemap component configurations +// */ // public void setComponentConfigurations(Configuration componentConfigurations) { // this.concreteProcessor.setComponentConfigurations(componentConfigurations); // } @@ -399,7 +399,7 @@ treeBuilder.setParentProcessorManager(this.manager); ProcessingNode root = treeBuilder.build(sitemapProgram); - newProcessor.setProcessorData(root, treeBuilder.getDisposableNodes()); + newProcessor.setProcessorData(treeBuilder.getBuiltProcessorManager(), root, treeBuilder.getDisposableNodes()); } finally { this.manager.release(treeBuilder); } @@ -424,11 +424,7 @@ } private ConcreteTreeProcessor createConcreteTreeProcessor() { - ProcessorComponentInfo componentInfo = this.parent == null? - null : this.parent.concreteProcessor.getComponentInfo(); - ConcreteTreeProcessor processor = new ConcreteTreeProcessor(this, - this.sitemapExecutor, - componentInfo); + ConcreteTreeProcessor processor = new ConcreteTreeProcessor(this, this.sitemapExecutor); setupLogger(processor); return processor; } Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java Sun Jan 2 07:12:01 2005 @@ -25,7 +25,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Id: ReadNodeBuilder.java,v 1.3 2004/07/15 12:49:50 sylvain Exp $ + * @version CVS $Id$ */ public class ReadNodeBuilder extends AbstractProcessingNodeBuilder implements ThreadSafe { @@ -36,7 +36,7 @@ String mimeType = config.getAttribute("mime-type", null); if (mimeType == null) { - mimeType = this.treeBuilder.getProcessor().getComponentInfo().getMimeType(Reader.ROLE, type); + mimeType = ((SitemapLanguage)this.treeBuilder).getMimeType(Reader.ROLE, type); } ReadNode node = new ReadNode( Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java&r2=123887 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java Sun Jan 2 07:12:01 2005 @@ -28,7 +28,7 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Id: SerializeNodeBuilder.java,v 1.5 2004/07/16 12:36:45 sylvain Exp $ + * @version CVS $Id$ */ public class SerializeNodeBuilder extends AbstractProcessingNodeBuilder @@ -47,14 +47,16 @@ public ProcessingNode buildNode(Configuration config) throws Exception { String type = this.treeBuilder.getTypeForStatement(config, Serializer.ROLE); + + SitemapLanguage sitemapBuilder = (SitemapLanguage)this.treeBuilder; String mimeType = config.getAttribute("mime-type", null); if (mimeType == null) { - mimeType = this.treeBuilder.getProcessor().getComponentInfo().getMimeType(Serializer.ROLE, type); + mimeType = sitemapBuilder.getMimeType(Serializer.ROLE, type); } - this.views = ((SitemapLanguage)this.treeBuilder).getViewsForStatement(Serializer.ROLE, type, config); - this.pipelineHints = ((SitemapLanguage)this.treeBuilder).getHintsForStatement(Serializer.ROLE, type, config); + this.views = sitemapBuilder.getViewsForStatement(Serializer.ROLE, type, config); + this.pipelineHints = sitemapBuilder.getHintsForStatement(Serializer.ROLE, type, config); this.node = new SerializeNode( type, Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java?view=diff&rev=123887&p1=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java&r1=123886&p2=cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java&r2=123887 ============================================================================== --- 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 Sun Jan 2 07:12:01 2005 @@ -15,44 +15,34 @@ */ package org.apache.cocoon.components.treeprocessor.sitemap; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + 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.context.DefaultContext; import org.apache.avalon.framework.service.ServiceManager; - import org.apache.cocoon.Constants; -import org.apache.cocoon.acting.Action; import org.apache.cocoon.components.container.CocoonServiceManager; -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.environment.Environment; import org.apache.cocoon.environment.internal.EnvironmentHelper; import org.apache.cocoon.generation.Generator; -import org.apache.cocoon.matching.Matcher; -import org.apache.cocoon.reading.Reader; -import org.apache.cocoon.selection.Selector; import org.apache.cocoon.serialization.Serializer; import org.apache.cocoon.sitemap.PatternException; -import org.apache.cocoon.transformation.Transformer; import org.apache.cocoon.util.StringUtils; - import org.apache.regexp.RE; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - /** * The tree builder for the sitemap language. * @@ -64,7 +54,7 @@ // Regexp's for splitting expressions private static final String COMMA_SPLIT_REGEXP = "[\\s]*,[\\s]*"; private static final String EQUALS_SPLIT_REGEXP = "[\\s]*=[\\s]*"; - + /** * Build a component manager with the contents of the <map:components> element of * the tree. @@ -90,30 +80,6 @@ newManager.configure(config); newManager.initialize(); - // Extract additional component info - // Default component types - setupDefaultType(config, Action.ROLE, "actions"); - setupDefaultType(config, Matcher.ROLE, "matchers"); - setupDefaultType(config, Selector.ROLE, "selectors"); - setupDefaultType(config, Generator.ROLE, "generators"); - setupDefaultType(config, Transformer.ROLE, "transformers"); - setupDefaultType(config, Serializer.ROLE, "serializers"); - setupDefaultType(config, Reader.ROLE, "readers"); - setupDefaultType(config, ProcessingPipeline.ROLE, "pipes"); - - // Labels and pipeline hints - setupLabelsAndPipelineHints(config, Generator.ROLE, "generators"); - setupLabelsAndPipelineHints(config, Transformer.ROLE, "transformers"); - setupLabelsAndPipelineHints(config, Serializer.ROLE, "serializers"); - - // Mime types - setupMimeTypes(config, Serializer.ROLE, "serializers"); - setupMimeTypes(config, Reader.ROLE, "readers"); - - // Register manager and prevent further modifications - getProcessor().getComponentInfo().setServiceManager(newManager); - getProcessor().getComponentInfo().lock(); - return newManager; } @@ -128,76 +94,6 @@ return newContext; } - /** - * Setup the default compnent type for a given role. - * - * @param componentsConfig the <map:components> configuration - * @param role the compomonent role - * @param childName the name of the configuration element defining <code>role</code>'s selector - */ - private void setupDefaultType(Configuration componentsConfig, String role, String childName) { - Configuration selectorConfig = componentsConfig.getChild(childName, false); - if (selectorConfig != null) { - getProcessor().getComponentInfo().setDefaultType(role, selectorConfig.getAttribute("default", null)); - } - } - - /** - * Setup view labels and pipeline hints for the components of a given role - */ - private void setupLabelsAndPipelineHints(Configuration componentsConfig, String role, String childName) - throws ConfigurationException { - - Configuration selectorConfig = componentsConfig.getChild(childName, false); - ProcessorComponentInfo info = getProcessor().getComponentInfo(); - if (selectorConfig != null) { - Configuration[] configs = selectorConfig.getChildren(); - for (int configIdx = 0; configIdx < configs.length; configIdx++) { - Configuration config = configs[configIdx]; - String name = config.getAttribute("name"); - - // Labels - String label = config.getAttribute("label", null); - if (label != null) { - StringTokenizer st = new StringTokenizer(label, " ,", false); - String[] labels = new String[st.countTokens()]; - for (int tokenIdx = 0; tokenIdx < labels.length; tokenIdx++) { - labels[tokenIdx] = st.nextToken(); - } - info.setLabels(role, name, labels); - } else { - // Set no labels, overriding those defined in the parent sitemap, if any - info.setLabels(role, name, null); - } - - // Pipeline hints - String pipelineHint = config.getAttribute("hint", null); - info.setPipelineHint(role, name, pipelineHint); - } - } - } - - /** - * Setup mime types for components of a given role - */ - private void setupMimeTypes(Configuration componentsConfig, String role, String childName) - throws ConfigurationException { - - Configuration selectorConfig = componentsConfig.getChild(childName, false); - ProcessorComponentInfo info = getProcessor().getComponentInfo(); - if (selectorConfig != null) { - Configuration[] configs = selectorConfig.getChildren(); - for (int i = 0; i < configs.length; i++) { - Configuration config = configs[i]; - info.setMimeType( - role, - config.getAttribute("name"), - config.getAttribute("mime-type", null) - ); - } - } - } - //---- Views management /** Collection of view names for each label */ @@ -312,7 +208,7 @@ // 1 - labels defined on the component if (role != null && role.length() > 0) { - String[] compLabels = getProcessor().getComponentInfo().getLabels(role, hint); + String[] compLabels = this.itsComponentInfo.getLabels(role, hint); if (compLabels != null) { for (int i = 0; i < compLabels.length; i++) { labels.add(compLabels[i]); @@ -439,7 +335,7 @@ // firstly, determine if any pipeline-hints are defined at the component level // if so, inherit these pipeline-hints (these hints can be overriden by local pipeline-hints) - componentHintParams = getProcessor().getComponentInfo().getPipelineHint(role, hint); + componentHintParams = this.itsComponentInfo.getPipelineHint(role, hint); if (componentHintParams != null) { hintParams = componentHintParams; @@ -495,6 +391,17 @@ } return params; + } + + /** + * Get the mime-type for a component (either a serializer or a reader) + * + * @param role the component role (e.g. <code>Serializer.ROLE</code>) + * @param hint the component hint, i.e. the 'type' attribute + * @return the mime-type, or <code>null</code> if none was set + */ + public String getMimeType(String role, String hint) { + return this.itsComponentInfo.getMimeType(role, hint); } /** Modified: cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java?view=diff&rev=123887&p1=cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java&r1=123886&p2=cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java&r2=123887 ============================================================================== --- cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java (original) +++ cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java Sun Jan 2 07:12:01 2005 @@ -23,7 +23,7 @@ import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceManager; -import org.apache.cocoon.core.container.CocoonServiceManager; +import org.apache.cocoon.core.container.CoreServiceManager; import javax.naming.Context; import java.util.Hashtable; @@ -52,13 +52,13 @@ * The delegate that will be configured and provide the * functionality for this component manager. */ - private final CocoonServiceManager delegate; + private final CoreServiceManager delegate; public ParentServiceManager(final String jndiName) { this.jndiName = jndiName; // Initialize it here so we can let it be final. - this.delegate = new CocoonServiceManager(null); + this.delegate = new CoreServiceManager(null); } /* (non-Javadoc) Modified: cocoon/trunk/src/test/org/apache/cocoon/CocoonTestCase.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/test/org/apache/cocoon/CocoonTestCase.java?view=diff&rev=123887&p1=cocoon/trunk/src/test/org/apache/cocoon/CocoonTestCase.java&r1=123886&p2=cocoon/trunk/src/test/org/apache/cocoon/CocoonTestCase.java&r2=123887 ============================================================================== --- cocoon/trunk/src/test/org/apache/cocoon/CocoonTestCase.java (original) +++ cocoon/trunk/src/test/org/apache/cocoon/CocoonTestCase.java Sun Jan 2 07:12:01 2005 @@ -18,7 +18,7 @@ import org.apache.avalon.framework.configuration.DefaultConfiguration; import org.apache.avalon.framework.service.ServiceException; -import org.apache.cocoon.core.container.CocoonServiceManager; +import org.apache.cocoon.core.container.CoreServiceManager; import org.apache.cocoon.core.container.CocoonServiceSelector; import org.apache.cocoon.core.container.ContainerTestCase; import org.apache.excalibur.source.SourceResolver; @@ -36,7 +36,7 @@ /* (non-Javadoc) * @see org.apache.cocoon.core.container.ContainerTestCase#addComponents(org.apache.cocoon.core.container.CocoonServiceManager) */ - protected void addComponents(CocoonServiceManager manager) + protected void addComponents(CoreServiceManager manager) throws ServiceException { super.addComponents(manager); if ( this.addSourceFactories() ) { @@ -50,12 +50,12 @@ factory.setAttribute("class", URLSourceFactory.class.getName()); factory.setAttribute("name", "*"); df.addChild(factory); - manager.doAddComponent("org.apache.excalibur.source.SourceFactorySelector", + manager.addComponent("org.apache.excalibur.source.SourceFactorySelector", CocoonServiceSelector.class, df); } if ( this.addSourceResolver() ) { - manager.doAddComponent(SourceResolver.ROLE, + manager.addComponent(SourceResolver.ROLE, SourceResolverImpl.class, new DefaultConfiguration("", "-")); } Modified: cocoon/trunk/src/test/org/apache/cocoon/SitemapComponentTestCase.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/test/org/apache/cocoon/SitemapComponentTestCase.java?view=diff&rev=123887&p1=cocoon/trunk/src/test/org/apache/cocoon/SitemapComponentTestCase.java&r1=123886&p2=cocoon/trunk/src/test/org/apache/cocoon/SitemapComponentTestCase.java&r2=123887 ============================================================================== --- cocoon/trunk/src/test/org/apache/cocoon/SitemapComponentTestCase.java (original) +++ cocoon/trunk/src/test/org/apache/cocoon/SitemapComponentTestCase.java Sun Jan 2 07:12:01 2005 @@ -39,7 +39,7 @@ import org.apache.cocoon.components.flow.FlowHelper; import org.apache.cocoon.components.flow.Interpreter; import org.apache.cocoon.components.source.SourceResolverAdapter; -import org.apache.cocoon.core.container.CocoonServiceManager; +import org.apache.cocoon.core.container.CoreServiceManager; import org.apache.cocoon.core.container.CocoonServiceSelector; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.internal.EnvironmentHelper; @@ -129,7 +129,7 @@ /* (non-Javadoc) * @see org.apache.cocoon.core.container.ContainerTestCase#addComponents(org.apache.cocoon.core.container.CocoonServiceManager) */ - protected void addComponents(CocoonServiceManager manager) + protected void addComponents(CoreServiceManager manager) throws ServiceException { super.addComponents(manager); final String[] o = this.getSitemapComponentInfo(); @@ -144,7 +144,7 @@ factory.setAttribute("class", componentClassName); factory.setAttribute("name", key); df.addChild(factory); - manager.doAddComponent(typeClassName + "Selector", + manager.addComponent(typeClassName + "Selector", CocoonServiceSelector.class, df); } Added: cocoon/trunk/src/webapp/sitemap-additions.xconf Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/sitemap-additions.xconf?view=auto&rev=123887 ============================================================================== --- (empty file) +++ cocoon/trunk/src/webapp/sitemap-additions.xconf Sun Jan 2 07:12:01 2005 @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 1999-2005 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. +--> +<!--+ + | This file defines some additional components for the sitemap. + | + | SVN $Id$ + +--> + +<components> + <generators> + <generator label="content" logger="sitemap.generator.mp3directory" name="mp3directory" src="org.apache.cocoon.generation.MP3DirectoryGenerator"/> + </generators> + + <transformers> + <transformer logger="sitemap.transformer.jpath" name="jpath" src="org.apache.cocoon.transformation.JPathTransformer"/> + <transformer logger="sitemap.transformer.filter" name="filter" src="org.apache.cocoon.transformation.FilterTransformer"/> + </transformers> + + <serializers> + <serializer logger="sitemap.serializer.vrml" mime-type="model/vrml" name="vrml" src="org.apache.cocoon.serialization.TextSerializer"/> + </serializers> + +</components> \ No newline at end of file Modified: cocoon/trunk/src/webapp/sitemap.xmap Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/sitemap.xmap?view=diff&rev=123887&p1=cocoon/trunk/src/webapp/sitemap.xmap&r1=123886&p2=cocoon/trunk/src/webapp/sitemap.xmap&r2=123887 ============================================================================== --- cocoon/trunk/src/webapp/sitemap.xmap (original) +++ cocoon/trunk/src/webapp/sitemap.xmap Sun Jan 2 07:12:01 2005 @@ -69,7 +69,6 @@ <map:generator label="content" logger="sitemap.generator.directory" name="directory" pool-grow="2" pool-max="16" pool-min="2" src="org.apache.cocoon.generation.DirectoryGenerator"/> <map:generator label="content" logger="sitemap.generator.xpathdirectory" name="xpathdirectory" src="org.apache.cocoon.generation.XPathDirectoryGenerator"/> <map:generator label="content" logger="sitemap.generator.imagedirectory" name="imagedirectory" src="org.apache.cocoon.generation.ImageDirectoryGenerator"/> - <map:generator label="content" logger="sitemap.generator.mp3directory" name="mp3directory" src="org.apache.cocoon.generation.MP3DirectoryGenerator"/> <map:generator label="content" logger="sitemap.generator.request" name="request" pool-grow="2" pool-max="16" pool-min="2" src="org.apache.cocoon.generation.RequestGenerator"/> <map:generator label="content" logger="sitemap.generator.stream" name="stream" pool-grow="2" pool-max="16" pool-min="1" src="org.apache.cocoon.generation.StreamGenerator"/> <map:generator label="content" logger="sitemap.generator.status" name="status" pool-grow="2" pool-max="16" pool-min="2" src="org.apache.cocoon.generation.StatusGenerator"/> @@ -131,8 +130,6 @@ <map:transformer logger="sitemap.transformer.cinclude" name="cinclude" pool-grow="2" pool-max="16" pool-min="2" src="org.apache.cocoon.transformation.CIncludeTransformer"/> <map:transformer logger="sitemap.transformer.encodeURL" name="encodeURL" src="org.apache.cocoon.transformation.EncodeURLTransformer"/> <map:transformer logger="sitemap.transformer.write-source" name="write-source" src="org.apache.cocoon.transformation.SourceWritingTransformer"/> - <map:transformer logger="sitemap.transformer.jpath" name="jpath" src="org.apache.cocoon.transformation.JPathTransformer"/> - <map:transformer logger="sitemap.transformer.filter" name="filter" src="org.apache.cocoon.transformation.FilterTransformer"/> <map:transformer logger="sitemap.transformer.writeDOMsession" name="writeDOMsession" src="org.apache.cocoon.transformation.WriteDOMSessionTransformer"/> <map:transformer logger="sitemap.transformer.readDOMsession" name="readDOMsession" src="org.apache.cocoon.transformation.ReadDOMSessionTransformer"/> <map:transformer logger="sitemap.transformer.log" name="log" pool-grow="2" pool-max="16" pool-min="2" src="org.apache.cocoon.transformation.LogTransformer"/> @@ -202,7 +199,6 @@ </map:serializer> <map:serializer logger="sitemap.serializer.text" mime-type="text/plain" name="text" src="org.apache.cocoon.serialization.TextSerializer"/> - <map:serializer logger="sitemap.serializer.vrml" mime-type="model/vrml" name="vrml" src="org.apache.cocoon.serialization.TextSerializer"/> <map:serializer logger="sitemap.serializer.zip" mime-type="application/zip" name="zip" src="org.apache.cocoon.serialization.ZipArchiveSerializer"/> <map:serializer logger="sitemap.serializer.sxw" mime-type="application/vnd.sun.xml.writer" name="sxw" src="org.apache.cocoon.serialization.ZipArchiveSerializer"/> <map:serializer logger="sitemap.serializer.sxc" mime-type="application/vnd.sun.xml.calc" name="sxc" src="org.apache.cocoon.serialization.ZipArchiveSerializer"/> @@ -435,6 +431,9 @@ <!-- parameter name="outputBufferSize" value="8192"/ --> </map:pipe> </map:pipes> + + <!-- include some additional components --> + <include src="sitemap-additions.xconf"/> </map:components> Modified: cocoon/trunk/status.xml Url: http://svn.apache.org/viewcvs/cocoon/trunk/status.xml?view=diff&rev=123887&p1=cocoon/trunk/status.xml&r1=123886&p2=cocoon/trunk/status.xml&r2=123887 ============================================================================== --- cocoon/trunk/status.xml (original) +++ cocoon/trunk/status.xml Sun Jan 2 07:12:01 2005 @@ -203,7 +203,7 @@ <changes> <release version="@version@" date="@date@"> <action dev="SW" type="add"> - Add an include feature to xconf files, to allow an easier configuration of the system. + Add an include feature to xconf files and xmap files, to allow an easier configuration of the system. The main cocoon.xconf is now a list of inclusion of the main core components and a separate xconf file for each block. Additional role files can also be included. </action> Modified: cocoon/trunk/tools/targets/webapp-build.xml Url: http://svn.apache.org/viewcvs/cocoon/trunk/tools/targets/webapp-build.xml?view=diff&rev=123887&p1=cocoon/trunk/tools/targets/webapp-build.xml&r1=123886&p2=cocoon/trunk/tools/targets/webapp-build.xml&r2=123887 ============================================================================== --- cocoon/trunk/tools/targets/webapp-build.xml (original) +++ cocoon/trunk/tools/targets/webapp-build.xml Sun Jan 2 07:12:01 2005 @@ -27,6 +27,7 @@ <copy file="${webapp}/not-found.xml" tofile="${build.webapp}/not-found.xml" filtering="on"/> <copy file="${webapp}/welcome.xslt" tofile="${build.webapp}/welcome.xslt" filtering="on"/> <copy file="${webapp}/sitemap.xmap" tofile="${build.webapp}/sitemap.xmap"/> + <copy file="${webapp}/sitemap-additions.xconf" tofile="${build.webapp}/sitemap-additions.xconf"/> <!-- generate sitemap entries <sitemap-components sitemap="${build.webapp}/sitemap.xmap" source="${java}"/>