Author: cziegeler Date: Mon Mar 21 08:06:51 2005 New Revision: 158476 URL: http://svn.apache.org/viewcvs?view=rev&rev=158476 Log: Create and destroy listeners
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java 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&r1=158475&r2=158476 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java Mon Mar 21 08:06:51 2005 @@ -16,6 +16,8 @@ package org.apache.cocoon.components.treeprocessor; import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import org.apache.avalon.framework.activity.Disposable; @@ -71,6 +73,12 @@ /** Optional application container */ private ComponentLocator applicationContainer; + /** Optional event listeners for the enter sitemap event */ + private List enterSitemapEventListeners = new ArrayList(); + + /** Optional event listeners for the leave sitemap event */ + private List leaveSitemapEventListeners = new ArrayList(); + /** * Builds a concrete processig, given the wrapping processor */ @@ -99,6 +107,8 @@ this.classloader = classloader; this.rootNode = rootNode; this.disposableNodes = disposableNodes; + this.enterSitemapEventListeners = enterSitemapEventListeners; + this.leaveSitemapEventListeners = leaveSitemapEventListeners; } /** Set the sitemap component configurations (called as part of the tree building process) */ @@ -315,8 +325,27 @@ // Ensure it won't be used anymore this.rootNode = null; this.sitemapExecutor = null; + + // dispose listeners + this.disposeListeners(this.enterSitemapEventListeners); + this.disposeListeners(this.leaveSitemapEventListeners); + + // dispose component locator ContainerUtil.dispose(this.applicationContainer); this.applicationContainer = null; + } + + protected void disposeListeners(List l) { + Iterator i = l.iterator(); + while ( i.hasNext() ) { + final TreeBuilder.EventComponent current = (TreeBuilder.EventComponent)i.next(); + if ( current.releaseUsingManager ) { + this.manager.release(current.component); + } else { + ContainerUtil.dispose(current.component); + } + } + l.clear(); } private class TreeProcessorRedirector extends ForwardRedirector { 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&r1=158475&r2=158476 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java Mon Mar 21 08:06:51 2005 @@ -31,6 +31,16 @@ String ROLE = TreeBuilder.class.getName(); + public static class EventComponent { + + public final Object component; + public final boolean releaseUsingManager; + + public EventComponent(Object c, boolean releaseUsingManager) { + this.component = c; + this.releaseUsingManager = releaseUsingManager; + } + } void setParentProcessorManager(ServiceManager manager); @@ -114,13 +124,16 @@ /** * Return all event listers that are registered for the * [EMAIL PROTECTED] org.apache.cocoon.sitemap.EnterSitemapEvent}. + * @return A list of [EMAIL PROTECTED] EventComponent}s. */ List getEnterSitemapEventListeners(); /** * Return all event listers that are registered for the * [EMAIL PROTECTED] org.apache.cocoon.sitemap.LeaveSitemapEvent}. + * @return A list of [EMAIL PROTECTED] EventComponent}s. */ List getLeaveSitemapEventListeners(); + } 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&r1=158475&r2=158476 ============================================================================== --- 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 Mon Mar 21 08:06:51 2005 @@ -32,11 +32,13 @@ import org.apache.avalon.framework.context.DefaultContext; import org.apache.avalon.framework.service.ServiceManager; import org.apache.cocoon.Constants; +import org.apache.cocoon.components.LifecycleHelper; import org.apache.cocoon.components.classloader.ClassLoaderFactory; import org.apache.cocoon.components.container.CocoonServiceManager; 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.TreeBuilder; import org.apache.cocoon.environment.Environment; import org.apache.cocoon.environment.internal.EnvironmentHelper; import org.apache.cocoon.generation.Generator; @@ -64,7 +66,8 @@ * Build a component manager with the contents of the <map:components> element of * the tree. */ - protected ServiceManager createServiceManager(Context context, Configuration tree) throws Exception { + protected ServiceManager createServiceManager(Context context, Configuration tree) + throws Exception { // Get the map:component node // Don't check namespace here : this will be done by node builders @@ -121,21 +124,36 @@ ContainerUtil.initialize(newManager); // check for an application specific container - Configuration appContainer = config.getChild("application-container", false); + final Configuration appContainer = config.getChild("application-container", false); if ( appContainer != null ) { final String clazzName = appContainer.getAttribute("class"); - ComponentLocator cl = (ComponentLocator)ClassUtils.newInstance(clazzName); + final ComponentLocator cl = (ComponentLocator)ClassUtils.newInstance(clazzName); // Go through the component lifecycle - ContainerUtil.enableLogging(cl, this.getLogger()); - ContainerUtil.contextualize(cl, context); - ContainerUtil.service(cl, newManager); - ContainerUtil.configure(cl, appContainer); - ContainerUtil.initialize(cl); + LifecycleHelper.setupComponent(cl, this.getLogger(), context, newManager, config); + this.applicationContainer = cl; newManager = new ComponentManager(newManager, cl); } + + // and finally the listeners + final Configuration listenersWrapper = config.getChild("listeners", false); + if ( listenersWrapper != null ) { + final Configuration[] listeners = listenersWrapper.getChildren("listener"); + for(int i = 0; i < listeners.length; i++) { + final Configuration current = listeners[i]; + // TODO - we could use a string tokenizer and allow several invoke keys + final String invoke = current.getAttribute("invoke"); + if ( "on-enter".equals(invoke) ) { + this.enterSitemapEventListeners.add(this.createListener(newManager, context, current)); + } else if ( "on-leave".equals(invoke) ) { + this.leaveSitemapEventListeners.add(this.createListener(newManager, context, current)); + } else { + throw new ConfigurationException("Unknown invokation key '" + invoke + "' for sitemap listener."); + } + } + } } finally { currentThread.setContextClassLoader(oldClassLoader); } @@ -143,6 +161,28 @@ return newManager; } + /** + * Create a listener + */ + protected Object createListener(ServiceManager manager, Context context, Configuration config) + throws Exception { + // role or class? + final String role = config.getAttribute("role", null); + if ( role != null ) { + return new TreeBuilder.EventComponent(manager.lookup(role), true); + } else { + final String className = config.getAttribute("class"); + final Object component = ClassUtils.newInstance(className); + + LifecycleHelper.setupComponent(component, this.getLogger(), context, manager, config); + + return new TreeBuilder.EventComponent(component, false); + } + } + + /** + * @see org.apache.cocoon.components.treeprocessor.DefaultTreeBuilder#createContext(org.apache.avalon.framework.configuration.Configuration) + */ protected Context createContext(Configuration tree) throws Exception { // Create sub-context for this sitemap DefaultContext newContext = new DefaultContext(super.createContext(tree));