KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > treeprocessor > sitemap > MountNode


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

16 package org.apache.cocoon.components.treeprocessor.sitemap;
17
18 import java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.apache.avalon.framework.activity.Disposable;
23 import org.apache.avalon.framework.component.ComponentException;
24 import org.apache.avalon.framework.component.ComponentManager;
25 import org.apache.avalon.framework.component.Composable;
26 import org.apache.cocoon.ProcessingException;
27 import org.apache.cocoon.components.pipeline.ProcessingPipeline;
28 import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
29 import org.apache.cocoon.components.treeprocessor.InvokeContext;
30 import org.apache.cocoon.components.treeprocessor.TreeProcessor;
31 import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
32 import org.apache.cocoon.environment.Environment;
33 import org.apache.commons.lang.BooleanUtils;
34
35 /**
36  *
37  * @author <a HREF="mailto:bluetkemeier@s-und-n.de">Bj&ouml;rn L&uuml;tkemeier</a>
38  * @author <a HREF="mailto:sylvain@apache.org">Sylvain Wallez</a>
39  * @version CVS $Id: MountNode.java 280344 2005-09-12 14:15:00Z cziegeler $
40  */

41 public class MountNode extends AbstractProcessingNode
42                        implements Composable, Disposable {
43
44     /** The key to get the pass_through value from the Environment */
45     public final static String JavaDoc COCOON_PASS_THROUGH = "COCOON_PASS_THROUGH";
46
47     /** The 'uri-prefix' attribute */
48     private final VariableResolver prefix;
49
50     /** The 'src' attribute */
51     private final VariableResolver source;
52
53     /** Processors for sources */
54     private Map JavaDoc processors = new HashMap JavaDoc();
55
56     /** The processor for this node */
57     private final TreeProcessor parentProcessor;
58
59     /** The value of the 'check-reload' attribute */
60     private final boolean checkReload;
61
62     /** The component manager to be used by the mounted processor */
63     private ComponentManager manager;
64
65     /** The value of the 'pass-through' attribute */
66     private final Boolean JavaDoc passThrough;
67
68     public MountNode(VariableResolver prefix,
69                      VariableResolver source,
70                      TreeProcessor parentProcessor,
71                      boolean checkReload,
72                      boolean passThrough) {
73         this.prefix = prefix;
74         this.source = source;
75         this.parentProcessor = parentProcessor;
76         this.checkReload = checkReload;
77         this.passThrough = BooleanUtils.toBooleanObject(passThrough);
78     }
79
80     public void compose(ComponentManager manager) throws ComponentException {
81         this.manager = manager;
82     }
83
84     public final boolean invoke(Environment env, InvokeContext context)
85       throws Exception JavaDoc {
86         final Map JavaDoc objectModel = env.getObjectModel();
87
88         String JavaDoc resolvedSource = this.source.resolve(context, objectModel);
89         String JavaDoc resolvedPrefix = this.prefix.resolve(context, objectModel);
90
91         if (resolvedSource.length() == 0) {
92             throw new ProcessingException("Source of mount statement is empty");
93         }
94         TreeProcessor processor = getProcessor(resolvedSource);
95
96         // Save context
97
String JavaDoc oldPrefix = env.getURIPrefix();
98         String JavaDoc oldURI = env.getURI();
99         String JavaDoc oldContext = env.getContext();
100         Object JavaDoc oldPassThrough = env.getAttribute(COCOON_PASS_THROUGH);
101         env.setAttribute(COCOON_PASS_THROUGH, this.passThrough);
102
103         boolean pipelineWasBuilt = false;
104
105         try {
106             env.changeContext(resolvedPrefix, resolvedSource);
107
108             if (context.isBuildingPipelineOnly()) {
109                 // Propagate pipelines
110
ProcessingPipeline pp = processor.buildPipeline(env);
111                 if (pp != null) {
112                     context.setProcessingPipeline( pp );
113                     pipelineWasBuilt = true;
114                 }
115             } else {
116                 // Processor will create its own pipelines
117
pipelineWasBuilt = processor.process(env);
118             }
119         } catch(Exception JavaDoc e) {
120             // Wrap with our location
121
throw ProcessingException.throwLocated("Sitemap: error when calling sub-sitemap", e, getLocation());
122
123         } finally {
124             // We restore the context only if no pipeline was built. This allows the pipeline
125
// environment to be left unchanged when we go back to ancestor processors.
126
// If no pipeline was built, we restore the context, so that the current processor
127
// continues executing the sitemap in the correct environment.
128
if (!pipelineWasBuilt) {
129                 env.setContext(oldPrefix, oldURI, oldContext);
130             }
131
132             if (oldPassThrough != null) {
133                 env.setAttribute(COCOON_PASS_THROUGH, oldPassThrough);
134             } else {
135                 env.removeAttribute(COCOON_PASS_THROUGH);
136             }
137
138             // Turning recomposing as a test, according to:
139
// http://marc.theaimsgroup.com/?t=106802211400005&r=1&w=2
140
// Recompose pipelines which may have been recomposed by subsitemap
141
// context.recompose(this.manager);
142
}
143
144         return pipelineWasBuilt;
145     }
146
147     private synchronized TreeProcessor getProcessor(String JavaDoc source)
148     throws Exception JavaDoc {
149
150         TreeProcessor processor = (TreeProcessor) processors.get(source);
151         if (processor == null) {
152             // Handle directory mounts
153
String JavaDoc actualSource;
154             if (source.charAt(source.length() - 1) == '/') {
155                 actualSource = source + "sitemap.xmap";
156             } else {
157                 actualSource = source;
158             }
159
160             processor = this.parentProcessor.createChildProcessor(this.manager, actualSource, this.checkReload);
161
162             // Associate to the original source
163
processors.put(source, processor);
164         }
165
166         return processor;
167     }
168
169     /**
170      *
171      */

172     public void dispose() {
173         Iterator JavaDoc iter = this.processors.values().iterator();
174         while(iter.hasNext()) {
175             ((TreeProcessor)iter.next()).dispose();
176         }
177     }
178 }
179
Popular Tags