Source Code Cross Referenced for CocoonComponentManager.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » components » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » apache lenya 2.0 » org.apache.cocoon.components 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.components;
018:
019:        import java.io.IOException;
020:        import java.net.MalformedURLException;
021:        import java.util.ArrayList;
022:        import java.util.HashMap;
023:        import java.util.Iterator;
024:        import java.util.List;
025:        import java.util.Map;
026:
027:        import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
028:        import org.apache.avalon.framework.component.Component;
029:        import org.apache.avalon.framework.component.ComponentException;
030:        import org.apache.avalon.framework.component.ComponentManager;
031:        import org.apache.avalon.framework.component.ComponentSelector;
032:        import org.apache.avalon.framework.component.Recomposable;
033:        import org.apache.avalon.framework.configuration.Configuration;
034:        import org.apache.avalon.framework.configuration.ConfigurationException;
035:        import org.apache.avalon.framework.logger.Logger;
036:        import org.apache.cocoon.ProcessingException;
037:        import org.apache.cocoon.Processor;
038:        import org.apache.cocoon.environment.Environment;
039:        import org.apache.cocoon.xml.XMLConsumer;
040:        import org.apache.excalibur.instrument.InstrumentManager;
041:        import org.apache.excalibur.source.Source;
042:        import org.apache.excalibur.source.SourceException;
043:        import org.apache.excalibur.source.SourceResolver;
044:
045:        /**
046:         * Cocoon Component Manager.
047:         * This manager extends the {@link ExcaliburComponentManager}
048:         * by a special lifecycle handling for a {@link RequestLifecycleComponent}
049:         * and by handling the lookup of the {@link SourceResolver}.
050:         * WARNING: This is a "private" Cocoon core class - do NOT use this class
051:         * directly - and do not assume that a {@link ComponentManager} you get
052:         * via the compose() method is an instance of CocoonComponentManager.
053:         *
054:         * @author <a href="mailto:bluetkemeier@s-und-n.de">Bj&ouml;rn L&uuml;tkemeier</a>
055:         * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
056:         * @version CVS $Id: CocoonComponentManager.java 540711 2007-05-22 19:36:07Z cziegeler $
057:         */
058:        public final class CocoonComponentManager extends
059:                ExcaliburComponentManager implements  SourceResolver, Component {
060:
061:            /** The key used to store the current process environment */
062:            private static final String PROCESS_KEY = CocoonComponentManager.class
063:                    .getName();
064:
065:            /** The environment attribute used to keep track of the actual environment in which the pipeline was built. */
066:            private static final String PROCESSOR_ATTR = "CocoonComponentManager.processor";
067:
068:            /** The environment information */
069:            protected static final ThreadLocal environmentStack = new ThreadLocal();
070:
071:            /** The configured {@link SourceResolver} */
072:            private SourceResolver sourceResolver;
073:
074:            /** The {@link SitemapConfigurationHolder}s */
075:            private Map sitemapConfigurationHolders = new HashMap(15);
076:
077:            /** The parent component manager for implementing parent aware components */
078:            private ComponentManager parentManager;
079:
080:            /** Temporary list of parent-aware components.  Will be null for most of
081:             * our lifecycle. */
082:            private ArrayList parentAwareComponents = new ArrayList();
083:
084:            /** has this been disposed? */
085:            private boolean wasDisposed;
086:
087:            /** The instrument manager (if any). */
088:            private InstrumentManager instrumentManager;
089:
090:            /** Create the ComponentManager */
091:            public CocoonComponentManager() {
092:                super (null, Thread.currentThread().getContextClassLoader());
093:            }
094:
095:            /** Create the ComponentManager with a Classloader */
096:            public CocoonComponentManager(final ClassLoader loader) {
097:                super (null, loader);
098:            }
099:
100:            /** Create the ComponentManager with a Classloader and parent ComponentManager */
101:            public CocoonComponentManager(final ComponentManager manager,
102:                    final ClassLoader loader) {
103:                super (manager, loader);
104:                this .setParentManager(manager);
105:            }
106:
107:            /** Create the ComponentManager with a parent ComponentManager */
108:            public CocoonComponentManager(final ComponentManager manager) {
109:                super (manager);
110:                this .setParentManager(manager);
111:            }
112:
113:            protected void setParentManager(final ComponentManager manager) {
114:                this .parentManager = manager;
115:                if (manager instanceof  CocoonComponentManager) {
116:                    this 
117:                            .setInstrumentManager(((CocoonComponentManager) manager).instrumentManager);
118:                }
119:            }
120:
121:            /**
122:             * @see org.apache.avalon.excalibur.component.ExcaliburComponentManager#setInstrumentManager(org.apache.excalibur.instrument.InstrumentManager)
123:             */
124:            public void setInstrumentManager(InstrumentManager iManager) {
125:                this .instrumentManager = iManager;
126:                super .setInstrumentManager(iManager);
127:            }
128:
129:            /**
130:             * This hook must be called by the sitemap each time a sitemap is entered
131:             * This method should never raise an exception, except when the
132:             * parameters are not set!
133:             */
134:            public static void enterEnvironment(Environment env,
135:                    ComponentManager manager, Processor processor) {
136:                if (null == env || null == manager || null == processor) {
137:                    throw new RuntimeException(
138:                            "CocoonComponentManager.enterEnvironment: "
139:                                    + "All parameters must be set: " + env
140:                                    + " - " + manager + " - " + processor);
141:                }
142:
143:                EnvironmentStack stack = (EnvironmentStack) environmentStack
144:                        .get();
145:                if (stack == null) {
146:                    stack = new EnvironmentStack();
147:                    environmentStack.set(stack);
148:                }
149:                stack.push(new EnvironmentStack.Item(env, processor, manager,
150:                        stack.getOffset()));
151:                stack.setOffset(stack.size() - 1);
152:
153:                env.setAttribute(PROCESSOR_ATTR, processor);
154:            }
155:
156:            /**
157:             * This hook must be called by the sitemap each time a sitemap is left.
158:             * It's the counterpart to {@link #enterEnvironment(Environment, ComponentManager, Processor)}.
159:             */
160:            public static void leaveEnvironment() {
161:                // Calling with true will avoid any change on the active processor
162:                leaveEnvironment(true);
163:            }
164:
165:            /**
166:             * This hook must be called by the sitemap each time a sitemap is left.
167:             * It's the counterpart to {@link #enterEnvironment(Environment, ComponentManager, Processor)}.
168:             *
169:             * @param success indicates if the request was successfully handled by the environment that's being left
170:             */
171:            public static void leaveEnvironment(boolean success) {
172:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
173:                        .get();
174:                final EnvironmentStack.Item objs = (EnvironmentStack.Item) stack
175:                        .pop();
176:                stack.setOffset(objs.offset);
177:
178:                if (stack.isEmpty()) {
179:                    final Environment env = objs.env;
180:                    final Map globalComponents = (Map) env
181:                            .getAttribute(GlobalRequestLifecycleComponent.class
182:                                    .getName());
183:                    if (globalComponents != null) {
184:
185:                        final Iterator iter = globalComponents.values()
186:                                .iterator();
187:                        while (iter.hasNext()) {
188:                            final Object[] o = (Object[]) iter.next();
189:                            final Component c = (Component) o[0];
190:                            ((CocoonComponentManager) o[1])
191:                                    .releaseRLComponent(c);
192:                        }
193:                    }
194:                    env.removeAttribute(GlobalRequestLifecycleComponent.class
195:                            .getName());
196:
197:                    // Setting this ThreadLocal to null allows it to be garbage collected
198:                    CocoonComponentManager.environmentStack.set(null);
199:                } else {
200:                    if (!success) {
201:                        // Restore the current processor as being the active one
202:                        getCurrentEnvironment().setAttribute(PROCESSOR_ATTR,
203:                                getCurrentProcessor());
204:                    }
205:                }
206:            }
207:
208:            /**
209:             * INTERNAL METHOD. Do not use, can be removed without warning or deprecation cycle.
210:             */
211:            public static int markEnvironment() {
212:                // TODO (CZ): This is only for testing - remove it later on. See also Cocoon.java.
213:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
214:                        .get();
215:                if (stack != null) {
216:                    return stack.size();
217:                }
218:
219:                return 0;
220:            }
221:
222:            /**
223:             * INTERNAL METHOD. Do not use, can be removed without warning or deprecation cycle.
224:             */
225:            public static void checkEnvironment(int depth, Logger logger)
226:                    throws Exception {
227:                // TODO (CZ): This is only for testing - remove it later on. See also Cocoon.java.
228:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
229:                        .get();
230:                int currentDepth = stack != null ? stack.size() : 0;
231:                if (currentDepth != depth) {
232:                    logger
233:                            .error("ENVIRONMENT STACK HAS NOT BEEN CLEANED PROPERLY!");
234:                    throw new ProcessingException(
235:                            "Environment stack has not been cleaned up properly. "
236:                                    + "Please report this (and if possible, together with a test case) "
237:                                    + "to the Cocoon developers.");
238:                }
239:            }
240:
241:            /**
242:             * Create an environment aware xml consumer for the cocoon
243:             * protocol
244:             */
245:            public static XMLConsumer createEnvironmentAwareConsumer(
246:                    XMLConsumer consumer) {
247:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
248:                        .get();
249:                final EnvironmentStack.Item objs = stack.getCurrent();
250:                return stack.getEnvironmentAwareConsumerWrapper(consumer,
251:                        objs.offset);
252:            }
253:
254:            /**
255:             * This hook has to be called before a request is processed.
256:             * The hook is called by the Cocoon component and by the
257:             * cocoon protocol implementation.
258:             * This method should never raise an exception, except when
259:             * the environment is not set.
260:             *
261:             * @return A unique key within this thread.
262:             */
263:            public static Object startProcessing(Environment env) {
264:                if (null == env) {
265:                    throw new RuntimeException(
266:                            "CocoonComponentManager.startProcessing: environment must be set.");
267:                }
268:                final EnvironmentDescription desc = new EnvironmentDescription(
269:                        env);
270:                env.getObjectModel().put(PROCESS_KEY, desc);
271:                env.startingProcessing();
272:                return desc;
273:            }
274:
275:            /**
276:             * This hook has to be called before a request is processed.
277:             * The hook is called by the Cocoon component and by the
278:             * cocoon protocol implementation.
279:             * @param key A unique key within this thread return by
280:             *         {@link #startProcessing(Environment)}.
281:             */
282:            public static void endProcessing(Environment env, Object key) {
283:                env.finishingProcessing();
284:                final EnvironmentDescription desc = (EnvironmentDescription) key;
285:                desc.release();
286:                env.getObjectModel().remove(PROCESS_KEY);
287:            }
288:
289:            /**
290:             * Return the current environment (for the cocoon: protocol)
291:             */
292:            public static Environment getCurrentEnvironment() {
293:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
294:                        .get();
295:                if (null != stack && !stack.isEmpty()) {
296:                    return stack.getCurrent().env;
297:                }
298:                return null;
299:            }
300:
301:            /**
302:             * Return the current processor (for the cocoon: protocol)
303:             */
304:            public static Processor getCurrentProcessor() {
305:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
306:                        .get();
307:                if (null != stack && !stack.isEmpty()) {
308:                    return stack.getCurrent().processor;
309:                }
310:                return null;
311:            }
312:
313:            /**
314:             * Return the processor that has actually processed the request
315:             */
316:            public static Processor getActiveProcessor(Environment env) {
317:                return (Processor) env.getAttribute(PROCESSOR_ATTR);
318:            }
319:
320:            /**
321:             * Get the current sitemap component manager.
322:             * This method return the current sitemap component manager. This
323:             * is the manager that holds all the components of the currently
324:             * processed (sub)sitemap.
325:             */
326:            static public ComponentManager getSitemapComponentManager() {
327:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
328:                        .get();
329:                if (null != stack && !stack.isEmpty()) {
330:                    EnvironmentStack.Item o = (EnvironmentStack.Item) stack
331:                            .peek();
332:                    return o.manager;
333:                }
334:
335:                // If we don't have an environment yet, just return null
336:                return null;
337:            }
338:
339:            /**
340:             * Return an instance of a component based on a Role.  The Role is usually the Interface's
341:             * Fully Qualified Name(FQN)--unless there are multiple Components for the same Role.  In that
342:             * case, the Role's FQN is appended with "Selector", and we return a ComponentSelector.
343:             */
344:            public Component lookup(final String role)
345:                    throws ComponentException {
346:                if (null == role) {
347:                    final String message = "ComponentLocator Attempted to retrieve component with null role.";
348:                    throw new ComponentException(role, message);
349:                }
350:
351:                if (role.equals(SourceResolver.ROLE)) {
352:                    if (null == this .sourceResolver) {
353:                        if (this .wasDisposed) {
354:                            // (BD) working on bug 27249: I think we could throw an Exception here, as
355:                            // the following call fails anyway, but I'm not sure enough ;-)
356:                            this 
357:                                    .getLogger()
358:                                    .warn(
359:                                            "Trying to lookup SourceResolver on disposed CocoonComponentManager");
360:                        }
361:                        this .sourceResolver = (SourceResolver) super 
362:                                .lookup(role);
363:                    }
364:                    return this ;
365:                }
366:
367:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
368:                        .get();
369:                if (null != stack && !stack.isEmpty()) {
370:                    final EnvironmentStack.Item objects = stack.getCurrent();
371:                    final Map objectModel = objects.env.getObjectModel();
372:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
373:                            .get(PROCESS_KEY);
374:                    if (null != desc) {
375:                        Component component = desc
376:                                .getRequestLifecycleComponent(role);
377:                        if (null != component) {
378:                            return component;
379:                        }
380:                        component = desc
381:                                .getGlobalRequestLifecycleComponent(role);
382:                        if (null != component) {
383:                            return component;
384:                        }
385:                    }
386:                }
387:
388:                final Component component = super .lookup(role);
389:
390:                if (component != null
391:                        && component instanceof  RequestLifecycleComponent) {
392:                    if (stack == null || stack.isEmpty()) {
393:                        throw new ComponentException(role,
394:                                "ComponentManager has no Environment Stack.");
395:                    }
396:
397:                    final EnvironmentStack.Item objects = stack.getCurrent();
398:                    final Map objectModel = objects.env.getObjectModel();
399:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
400:                            .get(PROCESS_KEY);
401:                    if (null != desc) {
402:                        // first test if the parent CM has already initialized this component
403:                        if (!desc.containsRequestLifecycleComponent(role)) {
404:                            try {
405:                                if (component instanceof  Recomposable) {
406:                                    ((Recomposable) component).recompose(this );
407:                                }
408:                                ((RequestLifecycleComponent) component).setup(
409:                                        objects.env, objectModel);
410:                            } catch (Exception local) {
411:                                throw new ComponentException(
412:                                        role,
413:                                        "Exception during setup of RequestLifecycleComponent.",
414:                                        local);
415:                            }
416:                            desc.addRequestLifecycleComponent(role, component,
417:                                    this );
418:                        }
419:                    }
420:                }
421:
422:                if (component != null
423:                        && component instanceof  GlobalRequestLifecycleComponent) {
424:                    if (stack == null || stack.isEmpty()) {
425:                        throw new ComponentException(role,
426:                                "ComponentManager has no Environment Stack.");
427:                    }
428:
429:                    final EnvironmentStack.Item objects = stack.getCurrent();
430:                    final Map objectModel = objects.env.getObjectModel();
431:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
432:                            .get(PROCESS_KEY);
433:                    if (null != desc) {
434:                        // first test if the parent CM has already initialized this component
435:                        if (!desc.containsGlobalRequestLifecycleComponent(role)) {
436:                            try {
437:                                if (component instanceof  Recomposable) {
438:                                    ((Recomposable) component).recompose(this );
439:                                }
440:                                ((GlobalRequestLifecycleComponent) component)
441:                                        .setup(objects.env, objectModel);
442:                            } catch (Exception local) {
443:                                throw new ComponentException(
444:                                        role,
445:                                        "Exception during setup of RequestLifecycleComponent.",
446:                                        local);
447:                            }
448:                            desc.addGlobalRequestLifecycleComponent(role,
449:                                    component, this );
450:                        }
451:                    }
452:                }
453:
454:                if (component != null
455:                        && component instanceof  SitemapConfigurable) {
456:                    // FIXME: how can we prevent that this is called over and over again?
457:                    SitemapConfigurationHolder holder;
458:
459:                    holder = (SitemapConfigurationHolder) this .sitemapConfigurationHolders
460:                            .get(role);
461:                    if (null == holder) {
462:                        // create new holder
463:                        holder = new DefaultSitemapConfigurationHolder(role);
464:                        this .sitemapConfigurationHolders.put(role, holder);
465:                    }
466:
467:                    try {
468:                        ((SitemapConfigurable) component).configure(holder);
469:                    } catch (ConfigurationException ce) {
470:                        throw new ComponentException(
471:                                role,
472:                                "Exception during setup of SitemapConfigurable.",
473:                                ce);
474:                    }
475:                }
476:
477:                return component;
478:            }
479:
480:            /**
481:             * Release a Component.  This implementation makes sure it has a handle on the propper
482:             * ComponentHandler, and let's the ComponentHandler take care of the actual work.
483:             */
484:            public void release(final Component component) {
485:                if (null == component) {
486:                    return;
487:                }
488:
489:                if (component instanceof  RequestLifecycleComponent
490:                        || component instanceof  GlobalRequestLifecycleComponent) {
491:                    return;
492:                }
493:
494:                if (component == this ) {
495:                    return;
496:                }
497:
498:                super .release(component);
499:            }
500:
501:            /**
502:             * Release a RequestLifecycleComponent
503:             */
504:            protected void releaseRLComponent(final Component component) {
505:                super .release(component);
506:            }
507:
508:            /**
509:             * Add an automatically released component
510:             */
511:            public static void addComponentForAutomaticRelease(
512:                    final ComponentSelector selector,
513:                    final Component component, final ComponentManager manager)
514:                    throws ProcessingException {
515:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
516:                        .get();
517:                if (null != stack && !stack.isEmpty()) {
518:                    final EnvironmentStack.Item objects = (EnvironmentStack.Item) stack
519:                            .get(0);
520:                    final Map objectModel = objects.env.getObjectModel();
521:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
522:                            .get(PROCESS_KEY);
523:                    if (null != desc) {
524:                        desc.addToAutoRelease(selector, component, manager);
525:                    }
526:                } else {
527:                    throw new ProcessingException(
528:                            "Unable to add component for automatic release: no environment available.");
529:                }
530:            }
531:
532:            /**
533:             * Add an automatically released component
534:             */
535:            public static void addComponentForAutomaticRelease(
536:                    final ComponentManager manager, final Component component)
537:                    throws ProcessingException {
538:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
539:                        .get();
540:                if (null != stack && !stack.isEmpty()) {
541:                    final EnvironmentStack.Item objects = (EnvironmentStack.Item) stack
542:                            .get(0);
543:                    final Map objectModel = objects.env.getObjectModel();
544:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
545:                            .get(PROCESS_KEY);
546:                    if (null != desc) {
547:                        desc.addToAutoRelease(manager, component);
548:                    }
549:                } else {
550:                    throw new ProcessingException(
551:                            "Unable to add component for automatic release: no environment available.");
552:                }
553:            }
554:
555:            /**
556:             * Remove from automatically released components
557:             */
558:            public static void removeFromAutomaticRelease(
559:                    final Component component) throws ProcessingException {
560:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
561:                        .get();
562:                if (null != stack && !stack.isEmpty()) {
563:                    final EnvironmentStack.Item objects = (EnvironmentStack.Item) stack
564:                            .get(0);
565:                    final Map objectModel = objects.env.getObjectModel();
566:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
567:                            .get(PROCESS_KEY);
568:                    if (null != desc) {
569:                        desc.removeFromAutoRelease(component);
570:                    }
571:                } else {
572:                    throw new ProcessingException(
573:                            "Unable to remove component from automatic release: no environment available.");
574:                }
575:            }
576:
577:            /**
578:             * Dispose
579:             */
580:            public void dispose() {
581:                if (this .getLogger().isDebugEnabled()) {
582:                    this .getLogger().debug(
583:                            "CocoonComponentManager.dispose() called");
584:                }
585:
586:                if (null != this .sourceResolver) {
587:                    super .release((Component) this .sourceResolver);
588:                    // We cannot null out sourceResolver here yet as some other not
589:                    // disposed yet components might still have unreleased sources,
590:                    // and they will call {@link #release(Source)} during their
591:                    // dispose().
592:                }
593:
594:                super .dispose();
595:
596:                // All components now are released so sourceResolver should be not
597:                // needed anymore.
598:                this .sourceResolver = null;
599:
600:                // This is used to track bug 27249
601:                this .wasDisposed = true;
602:            }
603:
604:            /**
605:             * Get a <code>Source</code> object.
606:             */
607:            public Source resolveURI(final String location)
608:                    throws MalformedURLException, IOException, SourceException {
609:                return this .resolveURI(location, null, null);
610:            }
611:
612:            /**
613:             * Get a <code>Source</code> object.
614:             */
615:            public Source resolveURI(final String location, String baseURI,
616:                    final Map parameters) throws MalformedURLException,
617:                    IOException, SourceException {
618:                if (baseURI == null) {
619:                    final EnvironmentStack stack = (EnvironmentStack) environmentStack
620:                            .get();
621:                    if (null != stack && !stack.isEmpty()) {
622:                        final EnvironmentStack.Item objects = stack
623:                                .getCurrent();
624:                        baseURI = objects.env.getContext();
625:                    }
626:                }
627:                return this .sourceResolver.resolveURI(location, baseURI,
628:                        parameters);
629:            }
630:
631:            /**
632:             * Releases a resolved resource
633:             */
634:            public void release(final Source source) {
635:                this .sourceResolver.release(source);
636:            }
637:
638:            /* (non-Javadoc)
639:             * @see org.apache.avalon.excalibur.component.ExcaliburComponentManager#addComponent(java.lang.String, java.lang.Class, org.apache.avalon.framework.configuration.Configuration)
640:             */
641:            public void addComponent(String role, Class clazz,
642:                    Configuration conf) throws ComponentException {
643:                super .addComponent(role, clazz, conf);
644:                // Note that at this point, we're not initialized and cannot do
645:                // lookups, so defer parental introductions to initialize().
646:                if (ParentAware.class.isAssignableFrom(clazz)) {
647:                    this .parentAwareComponents.add(role);
648:                }
649:            }
650:
651:            public void initialize() throws Exception {
652:                super .initialize();
653:                if (this .parentAwareComponents == null) {
654:                    throw new ComponentException(null,
655:                            "CocoonComponentManager already initialized");
656:                }
657:                // Set parents for parentAware components
658:                Iterator iter = this .parentAwareComponents.iterator();
659:                while (iter.hasNext()) {
660:                    String role = (String) iter.next();
661:                    this .getLogger().debug(".. " + role);
662:                    if (this .parentManager != null
663:                            && this .parentManager.hasComponent(role)) {
664:                        // lookup new component
665:                        Component component = null;
666:                        try {
667:                            component = this .lookup(role);
668:                            ((ParentAware) component)
669:                                    .setParentLocator(new ComponentLocatorImpl(
670:                                            this .parentManager, role));
671:                        } catch (ComponentException ignore) {
672:                            // we don't set the parent then
673:                        } finally {
674:                            this .release(component);
675:                        }
676:                    }
677:                }
678:                this .parentAwareComponents = null; // null to save memory, and catch logic bugs.
679:            }
680:
681:            /**
682:             * A runnable wrapper that inherits the environment stack of the thread it is
683:             * created in.
684:             * <p>
685:             * It's defined as an abstract class here to use some internals of EnvironmentHelper, and
686:             * should only be used through its public counterpart, {@link org.apache.cocoon.environment.CocoonRunnable}
687:             */
688:            public static abstract class AbstractCocoonRunnable implements 
689:                    Runnable {
690:                private Object parentStack = null;
691:
692:                public AbstractCocoonRunnable() {
693:                    // Clone the environment stack of the calling thread.
694:                    // We'll use it in run() below
695:                    Object stack = CocoonComponentManager.environmentStack
696:                            .get();
697:                    if (stack != null) {
698:                        this .parentStack = ((EnvironmentStack) stack).clone();
699:                    }
700:                }
701:
702:                /**
703:                 * Calls {@link #doRun()} within the environment context of the creating thread.
704:                 */
705:                public final void run() {
706:                    // Install the stack from the parent thread and run the Runnable
707:                    Object oldStack = environmentStack.get();
708:                    CocoonComponentManager.environmentStack
709:                            .set(this .parentStack);
710:                    try {
711:                        this .doRun();
712:                    } finally {
713:                        // Restore the previous stack
714:                        CocoonComponentManager.environmentStack.set(oldStack);
715:                    }
716:                    // FIXME: Check the lifetime of this run compared to the parent thread.
717:                    // A CocoonThread is meant to start and die within the execution period of the parent request,
718:                    // and it is an error if it lives longer as the parent environment is no more valid.
719:                }
720:
721:                abstract protected void doRun();
722:            }
723:        }
724:
725:        final class EnvironmentDescription {
726:
727:            Environment environment;
728:            Map objectModel;
729:            Map requestLifecycleComponents;
730:            List autoreleaseComponents = new ArrayList(4);
731:
732:            /**
733:             * Constructor
734:             */
735:            EnvironmentDescription(Environment env) {
736:                this .environment = env;
737:                this .objectModel = env.getObjectModel();
738:            }
739:
740:            Map getGlobalRequestLifcecycleComponents() {
741:                Map m = (Map) this .environment
742:                        .getAttribute(GlobalRequestLifecycleComponent.class
743:                                .getName());
744:                if (m == null) {
745:                    m = new HashMap();
746:                    this .environment.setAttribute(
747:                            GlobalRequestLifecycleComponent.class.getName(), m);
748:                }
749:                return m;
750:            }
751:
752:            /**
753:             * Release all components of this environment
754:             * All RequestLifecycleComponents and autoreleaseComponents are
755:             * released.
756:             */
757:            synchronized void release() {
758:                if (this .requestLifecycleComponents != null) {
759:                    final Iterator iter = this .requestLifecycleComponents
760:                            .values().iterator();
761:                    while (iter.hasNext()) {
762:                        final Object[] o = (Object[]) iter.next();
763:                        final Component component = (Component) o[0];
764:                        ((CocoonComponentManager) o[1])
765:                                .releaseRLComponent(component);
766:                    }
767:                    this .requestLifecycleComponents.clear();
768:                }
769:
770:                for (int i = 0; i < this .autoreleaseComponents.size(); i++) {
771:                    final Object[] o = (Object[]) this .autoreleaseComponents
772:                            .get(i);
773:                    final Component component = (Component) o[0];
774:                    if (o[1] instanceof  ComponentManager) {
775:                        ((ComponentManager) o[1]).release(component);
776:                    } else {
777:                        ((ComponentSelector) o[1]).release(component);
778:                        if (o[2] != null) {
779:                            ((ComponentManager) o[2]).release((Component) o[1]);
780:                        }
781:                    }
782:                }
783:                this .autoreleaseComponents.clear();
784:                this .environment = null;
785:                this .objectModel = null;
786:            }
787:
788:            /**
789:             * Add a RequestLifecycleComponent to the environment
790:             */
791:            void addRequestLifecycleComponent(final String role,
792:                    final Component co, final ComponentManager manager) {
793:                if (this .requestLifecycleComponents == null) {
794:                    this .requestLifecycleComponents = new HashMap();
795:                }
796:                this .requestLifecycleComponents.put(role, new Object[] { co,
797:                        manager });
798:            }
799:
800:            /**
801:             * Add a GlobalRequestLifecycleComponent to the environment
802:             */
803:            void addGlobalRequestLifecycleComponent(final String role,
804:                    final Component co, final ComponentManager manager) {
805:                this .getGlobalRequestLifcecycleComponents().put(role,
806:                        new Object[] { co, manager });
807:            }
808:
809:            /**
810:             * Do we already have a request lifecycle component
811:             */
812:            boolean containsRequestLifecycleComponent(final String role) {
813:                if (this .requestLifecycleComponents == null) {
814:                    return false;
815:                }
816:                return this .requestLifecycleComponents.containsKey(role);
817:            }
818:
819:            /**
820:             * Do we already have a global request lifecycle component
821:             */
822:            boolean containsGlobalRequestLifecycleComponent(final String role) {
823:                return this .getGlobalRequestLifcecycleComponents().containsKey(
824:                        role);
825:            }
826:
827:            /**
828:             * Search a RequestLifecycleComponent
829:             */
830:            Component getRequestLifecycleComponent(final String role) {
831:                if (this .requestLifecycleComponents == null) {
832:                    return null;
833:                }
834:                final Object[] o = (Object[]) this .requestLifecycleComponents
835:                        .get(role);
836:                if (null != o) {
837:                    return (Component) o[0];
838:                }
839:                return null;
840:            }
841:
842:            /**
843:             * Search a GlobalRequestLifecycleComponent
844:             */
845:            Component getGlobalRequestLifecycleComponent(final String role) {
846:                final Object[] o = (Object[]) this 
847:                        .getGlobalRequestLifcecycleComponents().get(role);
848:                if (null != o) {
849:                    return (Component) o[0];
850:                }
851:                return null;
852:            }
853:
854:            /**
855:             * Add an automatically released component
856:             */
857:            synchronized void addToAutoRelease(
858:                    final ComponentSelector selector,
859:                    final Component component, final ComponentManager manager) {
860:                this .autoreleaseComponents.add(new Object[] { component,
861:                        selector, manager });
862:            }
863:
864:            /**
865:             * Add an automatically released component
866:             */
867:            synchronized void addToAutoRelease(final ComponentManager manager,
868:                    final Component component) {
869:                this .autoreleaseComponents.add(new Object[] { component,
870:                        manager });
871:            }
872:
873:            /**
874:             * Remove from automatically released components
875:             */
876:            synchronized void removeFromAutoRelease(final Component component)
877:                    throws ProcessingException {
878:                int i = 0;
879:                boolean found = false;
880:                while (i < this .autoreleaseComponents.size() && !found) {
881:                    final Object[] o = (Object[]) this .autoreleaseComponents
882:                            .get(i);
883:                    if (o[0] == component) {
884:                        found = true;
885:                        if (o[1] instanceof  ComponentManager) {
886:                            ((ComponentManager) o[1]).release(component);
887:                        } else {
888:                            ((ComponentSelector) o[1]).release(component);
889:                            if (o[2] != null) {
890:                                ((ComponentManager) o[2])
891:                                        .release((Component) o[1]);
892:                            }
893:                        }
894:                        this .autoreleaseComponents.remove(i);
895:                    } else {
896:                        i++;
897:                    }
898:                }
899:                if (!found) {
900:                    throw new ProcessingException(
901:                            "Unable to remove component from automatic release: component not found.");
902:                }
903:            }
904:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.