Source Code Cross Referenced for CocoonComponentManager.java in  » Web-Framework » cocoon » 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 » Web Framework » cocoon » 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 433543 2006-08-22 06:22:54Z crossley $
057:         */
058:        public final class CocoonComponentManager extends
059:                ExcaliburComponentManager implements  SourceResolver {
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 (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:                            getLogger()
357:                                    .warn(
358:                                            "Trying to lookup SourceResolver on disposed CocoonComponentManager");
359:                        }
360:                        this .sourceResolver = (SourceResolver) super 
361:                                .lookup(role);
362:                    }
363:                    return this ;
364:                }
365:
366:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
367:                        .get();
368:                if (null != stack && !stack.isEmpty()) {
369:                    final EnvironmentStack.Item objects = stack.getCurrent();
370:                    final Map objectModel = objects.env.getObjectModel();
371:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
372:                            .get(PROCESS_KEY);
373:                    if (null != desc) {
374:                        Component component = desc
375:                                .getRequestLifecycleComponent(role);
376:                        if (null != component) {
377:                            return component;
378:                        }
379:                        component = desc
380:                                .getGlobalRequestLifecycleComponent(role);
381:                        if (null != component) {
382:                            return component;
383:                        }
384:                    }
385:                }
386:
387:                final Component component = super .lookup(role);
388:
389:                if (component != null
390:                        && component instanceof  RequestLifecycleComponent) {
391:                    if (stack == null || stack.isEmpty()) {
392:                        throw new ComponentException(role,
393:                                "ComponentManager has no Environment Stack.");
394:                    }
395:
396:                    final EnvironmentStack.Item objects = stack.getCurrent();
397:                    final Map objectModel = objects.env.getObjectModel();
398:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
399:                            .get(PROCESS_KEY);
400:                    if (null != desc) {
401:                        // first test if the parent CM has already initialized this component
402:                        if (!desc.containsRequestLifecycleComponent(role)) {
403:                            try {
404:                                if (component instanceof  Recomposable) {
405:                                    ((Recomposable) component).recompose(this );
406:                                }
407:                                ((RequestLifecycleComponent) component).setup(
408:                                        objects.env, objectModel);
409:                            } catch (Exception local) {
410:                                throw new ComponentException(
411:                                        role,
412:                                        "Exception during setup of RequestLifecycleComponent.",
413:                                        local);
414:                            }
415:                            desc.addRequestLifecycleComponent(role, component,
416:                                    this );
417:                        }
418:                    }
419:                }
420:
421:                if (component != null
422:                        && component instanceof  GlobalRequestLifecycleComponent) {
423:                    if (stack == null || stack.isEmpty()) {
424:                        throw new ComponentException(role,
425:                                "ComponentManager has no Environment Stack.");
426:                    }
427:
428:                    final EnvironmentStack.Item objects = stack.getCurrent();
429:                    final Map objectModel = objects.env.getObjectModel();
430:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
431:                            .get(PROCESS_KEY);
432:                    if (null != desc) {
433:                        // first test if the parent CM has already initialized this component
434:                        if (!desc.containsGlobalRequestLifecycleComponent(role)) {
435:                            try {
436:                                if (component instanceof  Recomposable) {
437:                                    ((Recomposable) component).recompose(this );
438:                                }
439:                                ((GlobalRequestLifecycleComponent) component)
440:                                        .setup(objects.env, objectModel);
441:                            } catch (Exception local) {
442:                                throw new ComponentException(
443:                                        role,
444:                                        "Exception during setup of RequestLifecycleComponent.",
445:                                        local);
446:                            }
447:                            desc.addGlobalRequestLifecycleComponent(role,
448:                                    component, this );
449:                        }
450:                    }
451:                }
452:
453:                if (component != null
454:                        && component instanceof  SitemapConfigurable) {
455:                    // FIXME: how can we prevent that this is called over and over again?
456:                    SitemapConfigurationHolder holder;
457:
458:                    holder = (SitemapConfigurationHolder) this .sitemapConfigurationHolders
459:                            .get(role);
460:                    if (null == holder) {
461:                        // create new holder
462:                        holder = new DefaultSitemapConfigurationHolder(role);
463:                        this .sitemapConfigurationHolders.put(role, holder);
464:                    }
465:
466:                    try {
467:                        ((SitemapConfigurable) component).configure(holder);
468:                    } catch (ConfigurationException ce) {
469:                        throw new ComponentException(
470:                                role,
471:                                "Exception during setup of SitemapConfigurable.",
472:                                ce);
473:                    }
474:                }
475:
476:                return component;
477:            }
478:
479:            /**
480:             * Release a Component.  This implementation makes sure it has a handle on the propper
481:             * ComponentHandler, and let's the ComponentHandler take care of the actual work.
482:             */
483:            public void release(final Component component) {
484:                if (null == component) {
485:                    return;
486:                }
487:
488:                if (component instanceof  RequestLifecycleComponent
489:                        || component instanceof  GlobalRequestLifecycleComponent) {
490:                    return;
491:                }
492:
493:                if (component == this ) {
494:                    return;
495:                }
496:
497:                super .release(component);
498:            }
499:
500:            /**
501:             * Release a RequestLifecycleComponent
502:             */
503:            protected void releaseRLComponent(final Component component) {
504:                super .release(component);
505:            }
506:
507:            /**
508:             * Add an automatically released component
509:             */
510:            public static void addComponentForAutomaticRelease(
511:                    final ComponentSelector selector,
512:                    final Component component, final ComponentManager manager)
513:                    throws ProcessingException {
514:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
515:                        .get();
516:                if (null != stack && !stack.isEmpty()) {
517:                    final EnvironmentStack.Item objects = (EnvironmentStack.Item) stack
518:                            .get(0);
519:                    final Map objectModel = objects.env.getObjectModel();
520:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
521:                            .get(PROCESS_KEY);
522:                    if (null != desc) {
523:                        desc.addToAutoRelease(selector, component, manager);
524:                    }
525:                } else {
526:                    throw new ProcessingException(
527:                            "Unable to add component for automatic release: no environment available.");
528:                }
529:            }
530:
531:            /**
532:             * Add an automatically released component
533:             */
534:            public static void addComponentForAutomaticRelease(
535:                    final ComponentManager manager, final Component component)
536:                    throws ProcessingException {
537:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
538:                        .get();
539:                if (null != stack && !stack.isEmpty()) {
540:                    final EnvironmentStack.Item objects = (EnvironmentStack.Item) stack
541:                            .get(0);
542:                    final Map objectModel = objects.env.getObjectModel();
543:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
544:                            .get(PROCESS_KEY);
545:                    if (null != desc) {
546:                        desc.addToAutoRelease(manager, component);
547:                    }
548:                } else {
549:                    throw new ProcessingException(
550:                            "Unable to add component for automatic release: no environment available.");
551:                }
552:            }
553:
554:            /**
555:             * Remove from automatically released components
556:             */
557:            public static void removeFromAutomaticRelease(
558:                    final Component component) throws ProcessingException {
559:                final EnvironmentStack stack = (EnvironmentStack) environmentStack
560:                        .get();
561:                if (null != stack && !stack.isEmpty()) {
562:                    final EnvironmentStack.Item objects = (EnvironmentStack.Item) stack
563:                            .get(0);
564:                    final Map objectModel = objects.env.getObjectModel();
565:                    EnvironmentDescription desc = (EnvironmentDescription) objectModel
566:                            .get(PROCESS_KEY);
567:                    if (null != desc) {
568:                        desc.removeFromAutoRelease(component);
569:                    }
570:                } else {
571:                    throw new ProcessingException(
572:                            "Unable to remove component from automatic release: no environment available.");
573:                }
574:            }
575:
576:            /**
577:             * Dispose
578:             */
579:            public void dispose() {
580:                if (getLogger().isDebugEnabled()) {
581:                    getLogger()
582:                            .debug("CocoonComponentManager.dispose() called");
583:                }
584:
585:                if (null != this .sourceResolver) {
586:                    super .release(this .sourceResolver);
587:                    // We cannot null out sourceResolver here yet as some other not
588:                    // disposed yet components might still have unreleased sources,
589:                    // and they will call {@link #release(Source)} during their
590:                    // dispose().
591:                }
592:
593:                super .dispose();
594:
595:                // All components now are released so sourceResolver should be not
596:                // needed anymore.
597:                this .sourceResolver = null;
598:
599:                // This is used to track bug 27249
600:                this .wasDisposed = true;
601:            }
602:
603:            /**
604:             * Get a <code>Source</code> object.
605:             */
606:            public Source resolveURI(final String location)
607:                    throws MalformedURLException, IOException, SourceException {
608:                return this .resolveURI(location, null, null);
609:            }
610:
611:            /**
612:             * Get a <code>Source</code> object.
613:             */
614:            public Source resolveURI(final String location, String baseURI,
615:                    final Map parameters) throws MalformedURLException,
616:                    IOException, SourceException {
617:                if (baseURI == null) {
618:                    final EnvironmentStack stack = (EnvironmentStack) environmentStack
619:                            .get();
620:                    if (null != stack && !stack.isEmpty()) {
621:                        final EnvironmentStack.Item objects = stack
622:                                .getCurrent();
623:                        baseURI = objects.env.getContext();
624:                    }
625:                }
626:                return this .sourceResolver.resolveURI(location, baseURI,
627:                        parameters);
628:            }
629:
630:            /**
631:             * Releases a resolved resource
632:             */
633:            public void release(final Source source) {
634:                this .sourceResolver.release(source);
635:            }
636:
637:            /* (non-Javadoc)
638:             * @see org.apache.avalon.excalibur.component.ExcaliburComponentManager#addComponent(java.lang.String, java.lang.Class, org.apache.avalon.framework.configuration.Configuration)
639:             */
640:            public void addComponent(String role, Class clazz,
641:                    Configuration conf) throws ComponentException {
642:                super .addComponent(role, clazz, conf);
643:                // Note that at this point, we're not initialized and cannot do
644:                // lookups, so defer parental introductions to initialize().
645:                if (ParentAware.class.isAssignableFrom(clazz)) {
646:                    parentAwareComponents.add(role);
647:                }
648:            }
649:
650:            public void initialize() throws Exception {
651:                super .initialize();
652:                if (parentAwareComponents == null) {
653:                    throw new ComponentException(null,
654:                            "CocoonComponentManager already initialized");
655:                }
656:                // Set parents for parentAware components
657:                Iterator iter = parentAwareComponents.iterator();
658:                while (iter.hasNext()) {
659:                    String role = (String) iter.next();
660:                    getLogger().debug(".. " + role);
661:                    if (parentManager != null
662:                            && parentManager.hasComponent(role)) {
663:                        // lookup new component
664:                        Component component = null;
665:                        try {
666:                            component = this .lookup(role);
667:                            ((ParentAware) component)
668:                                    .setParentLocator(new ComponentLocatorImpl(
669:                                            this .parentManager, role));
670:                        } catch (ComponentException ignore) {
671:                            // we don't set the parent then
672:                        } finally {
673:                            this .release(component);
674:                        }
675:                    }
676:                }
677:                parentAwareComponents = null; // null to save memory, and catch logic bugs.
678:            }
679:
680:            /**
681:             * A runnable wrapper that inherits the environment stack of the thread it is
682:             * created in.
683:             * <p>
684:             * It's defined as an abstract class here to use some internals of EnvironmentHelper, and
685:             * should only be used through its public counterpart, {@link org.apache.cocoon.environment.CocoonRunnable}
686:             */
687:            public static abstract class AbstractCocoonRunnable implements 
688:                    Runnable {
689:                private Object parentStack = null;
690:
691:                public AbstractCocoonRunnable() {
692:                    // Clone the environment stack of the calling thread.
693:                    // We'll use it in run() below
694:                    Object stack = CocoonComponentManager.environmentStack
695:                            .get();
696:                    if (stack != null) {
697:                        this .parentStack = ((EnvironmentStack) stack).clone();
698:                    }
699:                }
700:
701:                /**
702:                 * Calls {@link #doRun()} within the environment context of the creating thread.
703:                 */
704:                public final void run() {
705:                    // Install the stack from the parent thread and run the Runnable
706:                    Object oldStack = environmentStack.get();
707:                    CocoonComponentManager.environmentStack
708:                            .set(this .parentStack);
709:                    try {
710:                        doRun();
711:                    } finally {
712:                        // Restore the previous stack
713:                        CocoonComponentManager.environmentStack.set(oldStack);
714:                    }
715:                    // FIXME: Check the lifetime of this run compared to the parent thread.
716:                    // A CocoonThread is meant to start and die within the execution period of the parent request,
717:                    // and it is an error if it lives longer as the parent environment is no more valid.
718:                }
719:
720:                abstract protected void doRun();
721:            }
722:        }
723:
724:        final class EnvironmentDescription {
725:
726:            Environment environment;
727:            Map objectModel;
728:            Map requestLifecycleComponents;
729:            List autoreleaseComponents = new ArrayList(4);
730:
731:            /**
732:             * Constructor
733:             */
734:            EnvironmentDescription(Environment env) {
735:                this .environment = env;
736:                this .objectModel = env.getObjectModel();
737:            }
738:
739:            Map getGlobalRequestLifcecycleComponents() {
740:                Map m = (Map) environment
741:                        .getAttribute(GlobalRequestLifecycleComponent.class
742:                                .getName());
743:                if (m == null) {
744:                    m = new HashMap();
745:                    environment.setAttribute(
746:                            GlobalRequestLifecycleComponent.class.getName(), m);
747:                }
748:                return m;
749:            }
750:
751:            /**
752:             * Release all components of this environment
753:             * All RequestLifecycleComponents and autoreleaseComponents are
754:             * released.
755:             */
756:            synchronized void release() {
757:                if (this .requestLifecycleComponents != null) {
758:                    final Iterator iter = this .requestLifecycleComponents
759:                            .values().iterator();
760:                    while (iter.hasNext()) {
761:                        final Object[] o = (Object[]) iter.next();
762:                        final Component component = (Component) o[0];
763:                        ((CocoonComponentManager) o[1])
764:                                .releaseRLComponent(component);
765:                    }
766:                    this .requestLifecycleComponents.clear();
767:                }
768:
769:                for (int i = 0; i < autoreleaseComponents.size(); i++) {
770:                    final Object[] o = (Object[]) autoreleaseComponents.get(i);
771:                    final Component component = (Component) o[0];
772:                    if (o[1] instanceof  ComponentManager) {
773:                        ((ComponentManager) o[1]).release(component);
774:                    } else {
775:                        ((ComponentSelector) o[1]).release(component);
776:                        if (o[2] != null) {
777:                            ((ComponentManager) o[2]).release((Component) o[1]);
778:                        }
779:                    }
780:                }
781:                this .autoreleaseComponents.clear();
782:                this .environment = null;
783:                this .objectModel = null;
784:            }
785:
786:            /**
787:             * Add a RequestLifecycleComponent to the environment
788:             */
789:            void addRequestLifecycleComponent(final String role,
790:                    final Component co, final ComponentManager manager) {
791:                if (this .requestLifecycleComponents == null) {
792:                    this .requestLifecycleComponents = new HashMap();
793:                }
794:                this .requestLifecycleComponents.put(role, new Object[] { co,
795:                        manager });
796:            }
797:
798:            /**
799:             * Add a GlobalRequestLifecycleComponent to the environment
800:             */
801:            void addGlobalRequestLifecycleComponent(final String role,
802:                    final Component co, final ComponentManager manager) {
803:                this .getGlobalRequestLifcecycleComponents().put(role,
804:                        new Object[] { co, manager });
805:            }
806:
807:            /**
808:             * Do we already have a request lifecycle component
809:             */
810:            boolean containsRequestLifecycleComponent(final String role) {
811:                if (this .requestLifecycleComponents == null) {
812:                    return false;
813:                }
814:                return this .requestLifecycleComponents.containsKey(role);
815:            }
816:
817:            /**
818:             * Do we already have a global request lifecycle component
819:             */
820:            boolean containsGlobalRequestLifecycleComponent(final String role) {
821:                return this .getGlobalRequestLifcecycleComponents().containsKey(
822:                        role);
823:            }
824:
825:            /**
826:             * Search a RequestLifecycleComponent
827:             */
828:            Component getRequestLifecycleComponent(final String role) {
829:                if (this .requestLifecycleComponents == null) {
830:                    return null;
831:                }
832:                final Object[] o = (Object[]) this .requestLifecycleComponents
833:                        .get(role);
834:                if (null != o) {
835:                    return (Component) o[0];
836:                }
837:                return null;
838:            }
839:
840:            /**
841:             * Search a GlobalRequestLifecycleComponent
842:             */
843:            Component getGlobalRequestLifecycleComponent(final String role) {
844:                final Object[] o = (Object[]) this 
845:                        .getGlobalRequestLifcecycleComponents().get(role);
846:                if (null != o) {
847:                    return (Component) o[0];
848:                }
849:                return null;
850:            }
851:
852:            /**
853:             * Add an automatically released component
854:             */
855:            synchronized void addToAutoRelease(
856:                    final ComponentSelector selector,
857:                    final Component component, final ComponentManager manager) {
858:                this .autoreleaseComponents.add(new Object[] { component,
859:                        selector, manager });
860:            }
861:
862:            /**
863:             * Add an automatically released component
864:             */
865:            synchronized void addToAutoRelease(final ComponentManager manager,
866:                    final Component component) {
867:                this .autoreleaseComponents.add(new Object[] { component,
868:                        manager });
869:            }
870:
871:            /**
872:             * Remove from automatically released components
873:             */
874:            synchronized void removeFromAutoRelease(final Component component)
875:                    throws ProcessingException {
876:                int i = 0;
877:                boolean found = false;
878:                while (i < this .autoreleaseComponents.size() && !found) {
879:                    final Object[] o = (Object[]) this .autoreleaseComponents
880:                            .get(i);
881:                    if (o[0] == component) {
882:                        found = true;
883:                        if (o[1] instanceof  ComponentManager) {
884:                            ((ComponentManager) o[1]).release(component);
885:                        } else {
886:                            ((ComponentSelector) o[1]).release(component);
887:                            if (o[2] != null) {
888:                                ((ComponentManager) o[2])
889:                                        .release((Component) o[1]);
890:                            }
891:                        }
892:                        this .autoreleaseComponents.remove(i);
893:                    } else {
894:                        i++;
895:                    }
896:                }
897:                if (!found) {
898:                    throw new ProcessingException(
899:                            "Unable to remove component from automatic release: component not found.");
900:                }
901:            }
902:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.