KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > CocoonComponentManager


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.components;
17
18 import java.io.IOException JavaDoc;
19 import java.net.MalformedURLException JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
27 import org.apache.avalon.framework.component.Component;
28 import org.apache.avalon.framework.component.ComponentException;
29 import org.apache.avalon.framework.component.ComponentManager;
30 import org.apache.avalon.framework.component.ComponentSelector;
31 import org.apache.avalon.framework.component.Recomposable;
32 import org.apache.avalon.framework.configuration.Configuration;
33 import org.apache.avalon.framework.configuration.ConfigurationException;
34 import org.apache.avalon.framework.logger.Logger;
35 import org.apache.cocoon.ProcessingException;
36 import org.apache.cocoon.Processor;
37 import org.apache.cocoon.environment.Environment;
38 import org.apache.cocoon.xml.XMLConsumer;
39 import org.apache.excalibur.source.Source;
40 import org.apache.excalibur.source.SourceException;
41 import org.apache.excalibur.source.SourceResolver;
42
43 /**
44  * Cocoon Component Manager.
45  * This manager extends the {@link ExcaliburComponentManager}
46  * by a special lifecycle handling for a {@link RequestLifecycleComponent}
47  * and by handling the lookup of the {@link SourceResolver}.
48  * WARNING: This is a "private" Cocoon core class - do NOT use this class
49  * directly - and do not assume that a {@link ComponentManager} you get
50  * via the compose() method is an instance of CocoonComponentManager.
51  *
52  * @author <a HREF="mailto:bluetkemeier@s-und-n.de">Bj&ouml;rn L&uuml;tkemeier</a>
53  * @author <a HREF="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
54  * @version CVS $Id: CocoonComponentManager.java 265589 2005-08-31 21:45:13Z vgritsenko $
55  */

56 public final class CocoonComponentManager extends ExcaliburComponentManager
57                                           implements SourceResolver {
58
59     /** The key used to store the current process environment */
60     private static final String JavaDoc PROCESS_KEY = CocoonComponentManager.class.getName();
61
62     /** The environment attribute used to keep track of the actual environment in which the pipeline was built. */
63     private static final String JavaDoc PROCESSOR_ATTR = "CocoonComponentManager.processor";
64
65     /** The environment information */
66     protected static final ThreadLocal JavaDoc environmentStack = new ThreadLocal JavaDoc();
67
68     /** The configured {@link SourceResolver} */
69     private SourceResolver sourceResolver;
70
71     /** The {@link SitemapConfigurationHolder}s */
72     private Map JavaDoc sitemapConfigurationHolders = new HashMap JavaDoc(15);
73
74     /** The parent component manager for implementing parent aware components */
75     private ComponentManager parentManager;
76
77     /** Temporary list of parent-aware components. Will be null for most of
78      * our lifecycle. */

79     private ArrayList JavaDoc parentAwareComponents = new ArrayList JavaDoc();
80
81     /** has this been disposed? */
82     private boolean wasDisposed;
83
84
85     /** Create the ComponentManager */
86     public CocoonComponentManager() {
87         super(null, Thread.currentThread().getContextClassLoader());
88     }
89
90     /** Create the ComponentManager with a Classloader */
91     public CocoonComponentManager(final ClassLoader JavaDoc loader) {
92         super(null, loader);
93     }
94
95     /** Create the ComponentManager with a Classloader and parent ComponentManager */
96     public CocoonComponentManager(final ComponentManager manager, final ClassLoader JavaDoc loader) {
97         super(manager, loader);
98         this.parentManager = manager;
99     }
100
101     /** Create the ComponentManager with a parent ComponentManager */
102     public CocoonComponentManager(final ComponentManager manager) {
103         super(manager);
104         this.parentManager = manager;
105     }
106
107     /**
108      * This hook must be called by the sitemap each time a sitemap is entered
109      * This method should never raise an exception, except when the
110      * parameters are not set!
111      */

112     public static void enterEnvironment(Environment env,
113                                         ComponentManager manager,
114                                         Processor processor) {
115         if (null == env || null == manager || null == processor) {
116             throw new RuntimeException JavaDoc("CocoonComponentManager.enterEnvironment: " +
117                                        "All parameters must be set: " + env + " - " + manager + " - " + processor);
118         }
119
120         EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
121         if (stack == null) {
122             stack = new EnvironmentStack();
123             environmentStack.set(stack);
124         }
125         stack.push(new EnvironmentStack.Item(env, processor, manager, stack.getOffset()));
126         stack.setOffset(stack.size()-1);
127
128         env.setAttribute(PROCESSOR_ATTR, processor);
129     }
130
131     /**
132      * This hook must be called by the sitemap each time a sitemap is left.
133      * It's the counterpart to {@link #enterEnvironment(Environment, ComponentManager, Processor)}.
134      */

135     public static void leaveEnvironment() {
136         // Calling with true will avoid any change on the active processor
137
leaveEnvironment(true);
138     }
139
140     /**
141      * This hook must be called by the sitemap each time a sitemap is left.
142      * It's the counterpart to {@link #enterEnvironment(Environment, ComponentManager, Processor)}.
143      *
144      * @param success indicates if the request was successfully handled by the environment that's being left
145      */

146     public static void leaveEnvironment(boolean success) {
147         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
148         final EnvironmentStack.Item objs = (EnvironmentStack.Item)stack.pop();
149         stack.setOffset(objs.offset);
150
151         if (stack.isEmpty()) {
152             final Environment env = objs.env;
153             final Map JavaDoc globalComponents = (Map JavaDoc)env.getAttribute(GlobalRequestLifecycleComponent.class.getName());
154             if (globalComponents != null) {
155
156                 final Iterator JavaDoc iter = globalComponents.values().iterator();
157                 while (iter.hasNext()) {
158                     final Object JavaDoc[] o = (Object JavaDoc[])iter.next();
159                     final Component c = (Component)o[0];
160                     ((CocoonComponentManager)o[1]).releaseRLComponent( c );
161                 }
162             }
163             env.removeAttribute(GlobalRequestLifecycleComponent.class.getName());
164
165             // Setting this ThreadLocal to null allows it to be garbage collected
166
CocoonComponentManager.environmentStack.set(null);
167         } else {
168             if (!success) {
169                 // Restore the current processor as being the active one
170
getCurrentEnvironment().setAttribute(PROCESSOR_ATTR, getCurrentProcessor());
171             }
172         }
173     }
174
175     /**
176      * INTERNAL METHOD. Do not use, can be removed without warning or deprecation cycle.
177      */

178     public static int markEnvironment() {
179         // TODO (CZ): This is only for testing - remove it later on. See also Cocoon.java.
180
final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
181         if (stack != null) {
182             return stack.size();
183         }
184
185         return 0;
186     }
187
188     /**
189      * INTERNAL METHOD. Do not use, can be removed without warning or deprecation cycle.
190      */

191     public static void checkEnvironment(int depth, Logger logger)
192     throws Exception JavaDoc {
193         // TODO (CZ): This is only for testing - remove it later on. See also Cocoon.java.
194
final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
195         int currentDepth = stack != null? stack.size() : 0;
196         if (currentDepth != depth) {
197             logger.error("ENVIRONMENT STACK HAS NOT BEEN CLEANED PROPERLY!");
198             throw new ProcessingException("Environment stack has not been cleaned up properly. " +
199                                           "Please report this (and if possible, together with a test case) " +
200                                           "to the Cocoon developers.");
201         }
202     }
203
204     /**
205      * Create an environment aware xml consumer for the cocoon
206      * protocol
207      */

208     public static XMLConsumer createEnvironmentAwareConsumer(XMLConsumer consumer) {
209         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
210         final EnvironmentStack.Item objs = stack.getCurrent();
211         return stack.getEnvironmentAwareConsumerWrapper(consumer, objs.offset);
212     }
213
214     /**
215      * This hook has to be called before a request is processed.
216      * The hook is called by the Cocoon component and by the
217      * cocoon protocol implementation.
218      * This method should never raise an exception, except when
219      * the environment is not set.
220      *
221      * @return A unique key within this thread.
222      */

223     public static Object JavaDoc startProcessing(Environment env) {
224         if (null == env) {
225             throw new RuntimeException JavaDoc("CocoonComponentManager.startProcessing: environment must be set.");
226         }
227         final EnvironmentDescription desc = new EnvironmentDescription(env);
228         env.getObjectModel().put(PROCESS_KEY, desc);
229         env.startingProcessing();
230         return desc;
231     }
232
233     /**
234      * This hook has to be called before a request is processed.
235      * The hook is called by the Cocoon component and by the
236      * cocoon protocol implementation.
237      * @param key A unique key within this thread return by
238      * {@link #startProcessing(Environment)}.
239      */

240     public static void endProcessing(Environment env, Object JavaDoc key) {
241         env.finishingProcessing();
242         final EnvironmentDescription desc = (EnvironmentDescription)key;
243         desc.release();
244         env.getObjectModel().remove(PROCESS_KEY);
245     }
246
247     /**
248      * Return the current environment (for the cocoon: protocol)
249      */

250     public static Environment getCurrentEnvironment() {
251         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
252         if (null != stack && !stack.isEmpty()) {
253             return stack.getCurrent().env;
254         }
255         return null;
256     }
257
258     /**
259      * Return the current processor (for the cocoon: protocol)
260      */

261     public static Processor getCurrentProcessor() {
262         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
263         if (null != stack && !stack.isEmpty()) {
264             return stack.getCurrent().processor;
265         }
266         return null;
267     }
268
269     /**
270      * Return the processor that has actually processed the request
271      */

272     public static Processor getActiveProcessor(Environment env) {
273         return (Processor) env.getAttribute(PROCESSOR_ATTR);
274     }
275
276     /**
277      * Get the current sitemap component manager.
278      * This method return the current sitemap component manager. This
279      * is the manager that holds all the components of the currently
280      * processed (sub)sitemap.
281      */

282     static public ComponentManager getSitemapComponentManager() {
283         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
284         if (null != stack && !stack.isEmpty()) {
285             EnvironmentStack.Item o = (EnvironmentStack.Item) stack.peek();
286             return o.manager;
287         }
288
289         // If we don't have an environment yet, just return null
290
return null;
291     }
292
293     /**
294      * Return an instance of a component based on a Role. The Role is usually the Interface's
295      * Fully Qualified Name(FQN)--unless there are multiple Components for the same Role. In that
296      * case, the Role's FQN is appended with "Selector", and we return a ComponentSelector.
297      */

298     public Component lookup(final String JavaDoc role)
299     throws ComponentException {
300         if (null == role) {
301             final String JavaDoc message =
302                 "ComponentLocator Attempted to retrieve component with null role.";
303             throw new ComponentException(role, message);
304         }
305
306         if (role.equals(SourceResolver.ROLE)) {
307             if (null == this.sourceResolver) {
308                 if(wasDisposed) {
309                     // (BD) working on bug 27249: I think we could throw an Exception here, as
310
// the following call fails anyway, but I'm not sure enough ;-)
311
getLogger().warn("Trying to lookup SourceResolver on disposed CocoonComponentManager");
312                 }
313                 this.sourceResolver = (SourceResolver) super.lookup( role );
314             }
315             return this;
316         }
317
318         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
319         if ( null != stack && !stack.isEmpty()) {
320             final EnvironmentStack.Item objects = stack.getCurrent();
321             final Map JavaDoc objectModel = objects.env.getObjectModel();
322             EnvironmentDescription desc = (EnvironmentDescription)objectModel.get(PROCESS_KEY);
323             if ( null != desc ) {
324                 Component component = desc.getRequestLifecycleComponent(role);
325                 if (null != component) {
326                     return component;
327                 }
328                 component = desc.getGlobalRequestLifecycleComponent(role);
329                 if (null != component) {
330                     return component;
331                 }
332             }
333         }
334
335         final Component component = super.lookup(role);
336
337         if (component != null && component instanceof RequestLifecycleComponent) {
338             if (stack == null || stack.isEmpty()) {
339                 throw new ComponentException(role, "ComponentManager has no Environment Stack.");
340             }
341
342             final EnvironmentStack.Item objects = stack.getCurrent();
343             final Map JavaDoc objectModel = objects.env.getObjectModel();
344             EnvironmentDescription desc = (EnvironmentDescription) objectModel.get(PROCESS_KEY);
345             if (null != desc) {
346                 // first test if the parent CM has already initialized this component
347
if (!desc.containsRequestLifecycleComponent(role)) {
348                     try {
349                         if (component instanceof Recomposable) {
350                             ((Recomposable) component).recompose(this);
351                         }
352                         ((RequestLifecycleComponent) component).setup((org.apache.cocoon.environment.SourceResolver)objects.env,
353                                                                       objectModel);
354                     } catch (Exception JavaDoc local) {
355                         throw new ComponentException(role, "Exception during setup of RequestLifecycleComponent.", local);
356                     }
357                     desc.addRequestLifecycleComponent(role, component, this);
358                 }
359             }
360         }
361
362         if (component != null && component instanceof GlobalRequestLifecycleComponent) {
363             if (stack == null || stack.isEmpty()) {
364                 throw new ComponentException(role, "ComponentManager has no Environment Stack.");
365             }
366
367             final EnvironmentStack.Item objects = stack.getCurrent();
368             final Map JavaDoc objectModel = objects.env.getObjectModel();
369             EnvironmentDescription desc = (EnvironmentDescription) objectModel.get(PROCESS_KEY);
370             if (null != desc) {
371                 // first test if the parent CM has already initialized this component
372
if ( !desc.containsGlobalRequestLifecycleComponent( role ) ) {
373                     try {
374                         if (component instanceof Recomposable) {
375                             ((Recomposable) component).recompose(this);
376                         }
377                         ((GlobalRequestLifecycleComponent) component).setup((org.apache.cocoon.environment.SourceResolver)objects.env,
378                                                                       objectModel);
379                     } catch (Exception JavaDoc local) {
380                         throw new ComponentException(role, "Exception during setup of RequestLifecycleComponent.", local);
381                     }
382                     desc.addGlobalRequestLifecycleComponent(role, component, this);
383                 }
384             }
385         }
386
387         if (component != null && component instanceof SitemapConfigurable) {
388             // FIXME: how can we prevent that this is called over and over again?
389
SitemapConfigurationHolder holder;
390
391             holder = (SitemapConfigurationHolder) this.sitemapConfigurationHolders.get(role);
392             if (null == holder) {
393                 // create new holder
394
holder = new DefaultSitemapConfigurationHolder(role);
395                 this.sitemapConfigurationHolders.put(role, holder);
396             }
397
398             try {
399                 ((SitemapConfigurable)component).configure(holder);
400             } catch (ConfigurationException ce) {
401                 throw new ComponentException(role, "Exception during setup of SitemapConfigurable.", ce);
402             }
403         }
404
405         return component;
406     }
407
408     /**
409      * Release a Component. This implementation makes sure it has a handle on the propper
410      * ComponentHandler, and let's the ComponentHandler take care of the actual work.
411      */

412     public void release(final Component component) {
413         if (null == component) {
414             return;
415         }
416
417         if (component instanceof RequestLifecycleComponent
418                 || component instanceof GlobalRequestLifecycleComponent) {
419             return;
420         }
421
422         if (component == this) {
423             return;
424         }
425
426         super.release(component);
427     }
428
429     /**
430      * Release a RequestLifecycleComponent
431      */

432     protected void releaseRLComponent(final Component component) {
433         super.release(component);
434     }
435
436     /**
437      * Add an automatically released component
438      */

439     public static void addComponentForAutomaticRelease(final ComponentSelector selector,
440                                                        final Component component,
441                                                        final ComponentManager manager)
442     throws ProcessingException {
443         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
444         if ( null != stack && !stack.isEmpty()) {
445             final EnvironmentStack.Item objects = (EnvironmentStack.Item)stack.get(0);
446             final Map JavaDoc objectModel = objects.env.getObjectModel();
447             EnvironmentDescription desc = (EnvironmentDescription)objectModel.get(PROCESS_KEY);
448             if ( null != desc ) {
449                 desc.addToAutoRelease(selector, component, manager);
450             }
451         } else {
452             throw new ProcessingException("Unable to add component for automatic release: no environment available.");
453         }
454     }
455
456     /**
457      * Add an automatically released component
458      */

459     public static void addComponentForAutomaticRelease(final ComponentManager manager,
460                                                        final Component component)
461     throws ProcessingException {
462         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
463         if ( null != stack && !stack.isEmpty()) {
464             final EnvironmentStack.Item objects = (EnvironmentStack.Item)stack.get(0);
465             final Map JavaDoc objectModel = objects.env.getObjectModel();
466             EnvironmentDescription desc = (EnvironmentDescription)objectModel.get(PROCESS_KEY);
467             if ( null != desc ) {
468                 desc.addToAutoRelease(manager, component);
469             }
470         } else {
471             throw new ProcessingException("Unable to add component for automatic release: no environment available.");
472         }
473     }
474
475     /**
476      * Remove from automatically released components
477      */

478     public static void removeFromAutomaticRelease(final Component component)
479     throws ProcessingException {
480         final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
481         if ( null != stack && !stack.isEmpty()) {
482             final EnvironmentStack.Item objects = (EnvironmentStack.Item)stack.get(0);
483             final Map JavaDoc objectModel = objects.env.getObjectModel();
484             EnvironmentDescription desc = (EnvironmentDescription)objectModel.get(PROCESS_KEY);
485             if ( null != desc ) {
486                 desc.removeFromAutoRelease(component);
487             }
488         } else {
489             throw new ProcessingException("Unable to remove component from automatic release: no environment available.");
490         }
491     }
492
493     /**
494      * Dispose
495      */

496     public void dispose() {
497         if (getLogger().isDebugEnabled()) {
498             getLogger().debug("CocoonComponentManager.dispose() called");
499         }
500
501         if (null != this.sourceResolver) {
502             super.release(this.sourceResolver);
503             // We cannot null out sourceResolver here yet as some other not
504
// disposed yet components might still have unreleased sources,
505
// and they will call {@link #release(Source)} during their
506
// dispose().
507
}
508
509         super.dispose();
510
511         // All components now are released so sourceResolver should be not
512
// needed anymore.
513
this.sourceResolver = null;
514
515         // This is used to track bug 27249
516
this.wasDisposed = true;
517     }
518
519     /**
520      * Get a <code>Source</code> object.
521      */

522     public Source resolveURI(final String JavaDoc location)
523     throws MalformedURLException JavaDoc, IOException JavaDoc, SourceException {
524         return this.resolveURI(location, null, null);
525     }
526
527     /**
528      * Get a <code>Source</code> object.
529      */

530     public Source resolveURI(final String JavaDoc location,
531                              String JavaDoc baseURI,
532                              final Map JavaDoc parameters)
533     throws MalformedURLException JavaDoc, IOException JavaDoc, SourceException {
534         if (baseURI == null) {
535             final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
536             if ( null != stack && !stack.isEmpty()) {
537                 final EnvironmentStack.Item objects = stack.getCurrent();
538                 baseURI = objects.env.getContext();
539             }
540         }
541         return this.sourceResolver.resolveURI(location, baseURI, parameters);
542     }
543
544     /**
545      * Releases a resolved resource
546      */

547     public void release(final Source source) {
548         this.sourceResolver.release(source);
549     }
550
551
552     /* (non-Javadoc)
553      * @see org.apache.avalon.excalibur.component.ExcaliburComponentManager#addComponent(java.lang.String, java.lang.Class, org.apache.avalon.framework.configuration.Configuration)
554      */

555     public void addComponent(String JavaDoc role, Class JavaDoc clazz, Configuration conf)
556     throws ComponentException {
557         super.addComponent(role, clazz, conf);
558         // Note that at this point, we're not initialized and cannot do
559
// lookups, so defer parental introductions to initialize().
560
if (ParentAware.class.isAssignableFrom(clazz)) {
561             parentAwareComponents.add(role);
562         }
563     }
564
565     public void initialize() throws Exception JavaDoc {
566         super.initialize();
567         if (parentAwareComponents == null) {
568             throw new ComponentException(null, "CocoonComponentManager already initialized");
569         }
570         // Set parents for parentAware components
571
Iterator JavaDoc iter = parentAwareComponents.iterator();
572         while (iter.hasNext()) {
573             String JavaDoc role = (String JavaDoc)iter.next();
574             getLogger().debug(".. "+role);
575             if ( parentManager != null && parentManager.hasComponent( role ) ) {
576                 // lookup new component
577
Component component = null;
578                 try {
579                     component = this.lookup( role );
580                     ((ParentAware)component).setParentLocator( new ComponentLocatorImpl(this.parentManager, role ));
581                 } catch (ComponentException ignore) {
582                     // we don't set the parent then
583
} finally {
584                     this.release( component );
585                 }
586             }
587         }
588         parentAwareComponents = null; // null to save memory, and catch logic bugs.
589
}
590
591     /**
592      * A runnable wrapper that inherits the environment stack of the thread it is
593      * created in.
594      * <p>
595      * It's defined as an abstract class here to use some internals of EnvironmentHelper, and
596      * should only be used through its public counterpart, {@link org.apache.cocoon.environment.CocoonRunnable}
597      */

598     public static abstract class AbstractCocoonRunnable implements Runnable JavaDoc {
599         private Object JavaDoc parentStack = null;
600
601         public AbstractCocoonRunnable() {
602             // Clone the environment stack of the calling thread.
603
// We'll use it in run() below
604
Object JavaDoc stack = CocoonComponentManager.environmentStack.get();
605             if (stack != null) {
606                 this.parentStack = ((EnvironmentStack)stack).clone();
607             }
608         }
609
610         /**
611          * Calls {@link #doRun()} within the environment context of the creating thread.
612          */

613         public final void run() {
614             // Install the stack from the parent thread and run the Runnable
615
Object JavaDoc oldStack = environmentStack.get();
616             CocoonComponentManager.environmentStack.set(this.parentStack);
617             try {
618                 doRun();
619             } finally {
620                 // Restore the previous stack
621
CocoonComponentManager.environmentStack.set(oldStack);
622             }
623             // FIXME: Check the lifetime of this run compared to the parent thread.
624
// A CocoonThread is meant to start and die within the execution period of the parent request,
625
// and it is an error if it lives longer as the parent environment is no more valid.
626
}
627
628         abstract protected void doRun();
629     }
630 }
631
632 final class EnvironmentDescription {
633
634     Environment environment;
635     Map JavaDoc objectModel;
636     Map JavaDoc requestLifecycleComponents;
637     List JavaDoc autoreleaseComponents = new ArrayList JavaDoc(4);
638
639     /**
640      * Constructor
641      */

642     EnvironmentDescription(Environment env) {
643         this.environment = env;
644         this.objectModel = env.getObjectModel();
645     }
646
647     Map JavaDoc getGlobalRequestLifcecycleComponents() {
648         Map JavaDoc m = (Map JavaDoc)environment.getAttribute(GlobalRequestLifecycleComponent.class.getName());
649         if ( m == null ) {
650             m = new HashMap JavaDoc();
651             environment.setAttribute(GlobalRequestLifecycleComponent.class.getName(), m);
652         }
653         return m;
654     }
655
656     /**
657      * Release all components of this environment
658      * All RequestLifecycleComponents and autoreleaseComponents are
659      * released.
660      */

661     synchronized void release() {
662         if ( this.requestLifecycleComponents != null ) {
663             final Iterator JavaDoc iter = this.requestLifecycleComponents.values().iterator();
664             while (iter.hasNext()) {
665                 final Object JavaDoc[] o = (Object JavaDoc[])iter.next();
666                 final Component component = (Component)o[0];
667                 ((CocoonComponentManager)o[1]).releaseRLComponent( component );
668             }
669             this.requestLifecycleComponents.clear();
670         }
671
672         for (int i = 0; i < autoreleaseComponents.size(); i++) {
673             final Object JavaDoc[] o = (Object JavaDoc[])autoreleaseComponents.get(i);
674             final Component component = (Component)o[0];
675             if (o[1] instanceof ComponentManager) {
676                 ((ComponentManager)o[1]).release( component );
677             } else {
678                 ((ComponentSelector) o[1]).release(component);
679                 if (o[2] != null) {
680                     ((ComponentManager) o[2]).release((Component) o[1]);
681                 }
682             }
683         }
684         this.autoreleaseComponents.clear();
685         this.environment = null;
686         this.objectModel = null;
687     }
688
689     /**
690      * Add a RequestLifecycleComponent to the environment
691      */

692     void addRequestLifecycleComponent(final String JavaDoc role,
693                                       final Component co,
694                                       final ComponentManager manager) {
695         if ( this.requestLifecycleComponents == null ) {
696             this.requestLifecycleComponents = new HashMap JavaDoc();
697         }
698         this.requestLifecycleComponents.put(role, new Object JavaDoc[] {co, manager});
699     }
700
701     /**
702      * Add a GlobalRequestLifecycleComponent to the environment
703      */

704     void addGlobalRequestLifecycleComponent(final String JavaDoc role,
705                                       final Component co,
706                                       final ComponentManager manager) {
707         this.getGlobalRequestLifcecycleComponents().put(role, new Object JavaDoc[] {co, manager});
708     }
709
710     /**
711      * Do we already have a request lifecycle component
712      */

713     boolean containsRequestLifecycleComponent(final String JavaDoc role) {
714         if ( this.requestLifecycleComponents == null ) {
715             return false;
716         }
717         return this.requestLifecycleComponents.containsKey( role );
718     }
719
720     /**
721      * Do we already have a global request lifecycle component
722      */

723     boolean containsGlobalRequestLifecycleComponent(final String JavaDoc role) {
724         return this.getGlobalRequestLifcecycleComponents().containsKey( role );
725     }
726
727     /**
728      * Search a RequestLifecycleComponent
729      */

730     Component getRequestLifecycleComponent(final String JavaDoc role) {
731         if ( this.requestLifecycleComponents == null ) {
732             return null;
733         }
734         final Object JavaDoc[] o = (Object JavaDoc[])this.requestLifecycleComponents.get(role);
735         if ( null != o ) {
736             return (Component)o[0];
737         }
738         return null;
739     }
740
741     /**
742      * Search a GlobalRequestLifecycleComponent
743      */

744     Component getGlobalRequestLifecycleComponent(final String JavaDoc role) {
745         final Object JavaDoc[] o = (Object JavaDoc[])this.getGlobalRequestLifcecycleComponents().get(role);
746         if ( null != o ) {
747             return (Component)o[0];
748         }
749         return null;
750     }
751
752     /**
753      * Add an automatically released component
754      */

755     synchronized void addToAutoRelease(final ComponentSelector selector,
756                                        final Component component,
757                                        final ComponentManager manager) {
758         this.autoreleaseComponents.add(new Object JavaDoc[] {component, selector, manager});
759     }
760
761     /**
762      * Add an automatically released component
763      */

764     synchronized void addToAutoRelease(final ComponentManager manager,
765                                        final Component component) {
766         this.autoreleaseComponents.add(new Object JavaDoc[] {component, manager});
767     }
768
769     /**
770      * Remove from automatically released components
771      */

772     synchronized void removeFromAutoRelease(final Component component)
773     throws ProcessingException {
774         int i = 0;
775         boolean found = false;
776         while (i < this.autoreleaseComponents.size() && !found) {
777             final Object JavaDoc[] o = (Object JavaDoc[])this.autoreleaseComponents.get(i);
778             if (o[0] == component) {
779                 found = true;
780                 if (o[1] instanceof ComponentManager) {
781                     ((ComponentManager)o[1]).release( component );
782                 } else {
783                     ((ComponentSelector)o[1]).release( component );
784                     if (o[2] != null) {
785                         ((ComponentManager)o[2]).release( (Component)o[1] );
786                     }
787                 }
788                 this.autoreleaseComponents.remove(i);
789             } else {
790                 i++;
791             }
792         }
793         if (!found) {
794             throw new ProcessingException("Unable to remove component from automatic release: component not found.");
795         }
796     }
797 }
798
Popular Tags