1 16 package org.apache.cocoon.components.treeprocessor; 17 18 import java.io.IOException ; 19 import java.net.MalformedURLException ; 20 import java.util.Collections ; 21 import java.util.HashMap ; 22 import java.util.List ; 23 import java.util.Map ; 24 25 import org.apache.avalon.framework.activity.Disposable; 26 import org.apache.avalon.framework.component.ComponentManager; 27 import org.apache.avalon.framework.configuration.Configuration; 28 import org.apache.avalon.framework.logger.AbstractLogEnabled; 29 import org.apache.avalon.framework.logger.Logger; 30 import org.apache.cocoon.ProcessingException; 31 import org.apache.cocoon.Processor; 32 import org.apache.cocoon.components.ChainedConfiguration; 33 import org.apache.cocoon.components.CocoonComponentManager; 34 import org.apache.cocoon.components.pipeline.ProcessingPipeline; 35 import org.apache.cocoon.environment.Environment; 36 import org.apache.cocoon.environment.ForwardRedirector; 37 import org.apache.cocoon.environment.Redirector; 38 import org.apache.cocoon.environment.wrapper.EnvironmentWrapper; 39 import org.apache.cocoon.environment.wrapper.MutableEnvironmentFacade; 40 41 47 public class ConcreteTreeProcessor extends AbstractLogEnabled 48 implements Processor, Disposable { 49 50 51 private TreeProcessor wrappingProcessor; 52 53 54 ComponentManager sitemapComponentManager; 55 56 57 private List disposableNodes; 58 59 60 private ProcessingNode rootNode; 61 62 private Map sitemapComponentConfigurations; 63 64 private Configuration componentConfigurations; 65 66 67 private int requestCount; 68 69 70 public ConcreteTreeProcessor(TreeProcessor wrappingProcessor) { 71 this.wrappingProcessor = wrappingProcessor; 72 } 73 74 75 public void setProcessorData(ComponentManager manager, ProcessingNode rootNode, List disposableNodes) { 76 if (this.sitemapComponentManager != null) { 77 throw new IllegalStateException ("setProcessorData() can only be called once"); 78 } 79 80 this.sitemapComponentManager = manager; 81 this.rootNode = rootNode; 82 this.disposableNodes = disposableNodes; 83 } 84 85 86 public void setComponentConfigurations(Configuration componentConfigurations) { 87 this.componentConfigurations = componentConfigurations; 88 this.sitemapComponentConfigurations = null; 89 } 90 91 95 public Map getComponentConfigurations() { 96 if ( null == this.sitemapComponentConfigurations ) { 98 99 synchronized (this) { 100 101 if ( this.sitemapComponentConfigurations == null ) { 102 final Configuration[] childs = (this.componentConfigurations == null 104 ? null 105 : this.componentConfigurations.getChildren()); 106 107 if ( null != childs ) { 108 109 if ( null == this.wrappingProcessor.parent ) { 110 this.sitemapComponentConfigurations = new HashMap (12); 111 } else { 112 this.sitemapComponentConfigurations = new HashMap ( 114 this.wrappingProcessor.parent.getComponentConfigurations()); 115 } 116 117 for(int m = 0; m < childs.length; m++) { 119 120 final String r = this.wrappingProcessor.roleManager.getRoleForName(childs[m].getName()); 121 this.sitemapComponentConfigurations.put(r, new ChainedConfiguration(childs[m], 122 (ChainedConfiguration)this.sitemapComponentConfigurations.get(r))); 123 } 124 } else { 125 if ( null == this.wrappingProcessor.parent ) { 127 this.sitemapComponentConfigurations = Collections.EMPTY_MAP; 128 } else { 129 this.sitemapComponentConfigurations = this.wrappingProcessor.parent.getComponentConfigurations(); 131 } 132 } 133 } 134 } 135 } 136 return this.sitemapComponentConfigurations; } 137 138 142 public void markForDisposal() { 143 synchronized(this) { 145 this.requestCount--; 146 } 147 148 if (this.requestCount < 0) { 149 dispose(); 151 } 152 } 153 154 public TreeProcessor getWrappingProcessor() { 155 return this.wrappingProcessor; 156 } 157 158 public Processor getRootProcessor() { 159 return this.wrappingProcessor.getRootProcessor(); 160 } 161 162 172 public boolean process(Environment environment) throws Exception { 173 InvokeContext context = new InvokeContext(); 174 context.enableLogging(getLogger()); 175 try { 176 return process(environment, context); 177 } finally { 178 context.dispose(); 179 } 180 } 181 182 187 public ProcessingPipeline buildPipeline(Environment environment) 188 throws Exception { 189 InvokeContext context = new InvokeContext(true); 190 context.enableLogging(getLogger()); 191 try { 192 if (process(environment, context)) { 193 return context.getProcessingPipeline(); 194 } else { 195 return null; 196 } 197 } finally { 198 context.dispose(); 199 } 200 } 201 202 209 protected boolean process(Environment environment, InvokeContext context) 210 throws Exception { 211 212 synchronized(this) { 214 requestCount++; 215 } 216 217 try { 218 CocoonComponentManager.enterEnvironment(environment, this.sitemapComponentManager, this); 220 221 Map objectModel = environment.getObjectModel(); 222 223 Object oldResolver = objectModel.get(ProcessingNode.OBJECT_SOURCE_RESOLVER); 224 final Redirector oldRedirector = context.getRedirector(); 225 226 TreeProcessorRedirector redirector = new TreeProcessorRedirector(environment, context); 228 setupLogger(redirector); 229 context.setRedirector(redirector); 230 231 objectModel.put(ProcessingNode.OBJECT_SOURCE_RESOLVER, environment); 232 boolean success = false; 233 try { 234 success = this.rootNode.invoke(environment, context); 235 236 return success; 237 238 } finally { 239 CocoonComponentManager.leaveEnvironment(success); 240 context.setRedirector(oldRedirector); 242 objectModel.put(ProcessingNode.OBJECT_SOURCE_RESOLVER, oldResolver); 243 } 244 245 } finally { 246 247 synchronized(this) { 249 requestCount--; 250 } 251 252 if(requestCount < 0) { 253 dispose(); 255 } 256 } 257 } 258 259 private boolean handleCocoonRedirect(String uri, Environment environment, InvokeContext context) throws Exception { 260 261 265 MutableEnvironmentFacade facade = environment instanceof MutableEnvironmentFacade ? 266 ((MutableEnvironmentFacade)environment) : null; 267 268 if (facade != null) { 269 environment = facade.getDelegate(); 271 } 272 273 boolean isRedirect = (environment.getObjectModel().remove("cocoon:forward") == null); 275 Environment newEnv = new ForwardEnvironmentWrapper(environment, this.sitemapComponentManager, uri, getLogger()); 276 if ( isRedirect ) { 277 ((ForwardEnvironmentWrapper)newEnv).setInternalRedirect(true); 278 } 279 280 if (facade != null) { 281 facade.setDelegate((EnvironmentWrapper)newEnv); 283 newEnv = facade; 284 } 285 286 ConcreteTreeProcessor processor; 288 if (newEnv.getRootContext().equals(newEnv.getContext())) { 289 processor = ((TreeProcessor)getRootProcessor()).concreteProcessor; 290 } else { 291 processor = this; 292 } 293 294 final boolean result = processor.process(newEnv, context); 299 if ( facade != null ) { 300 newEnv = facade.getDelegate(); 301 } 302 if ( ((ForwardEnvironmentWrapper)newEnv).getRedirectURL() != null ) { 303 environment.redirect( false, ((ForwardEnvironmentWrapper)newEnv).getRedirectURL() ); 304 } 305 return result; 306 } 307 308 311 public void dispose() { 312 if (this.disposableNodes != null) { 313 for(int i=this.disposableNodes.size()-1; i>-1; i--) { 316 ((Disposable)disposableNodes.get(i)).dispose(); 317 } 318 this.disposableNodes = null; 319 } 320 321 this.rootNode = null; 323 } 324 325 public String toString() { 326 return "ConcreteTreeProcessor - " + wrappingProcessor.source.getURI(); 327 } 328 329 private class TreeProcessorRedirector extends ForwardRedirector { 330 331 private InvokeContext context; 332 public TreeProcessorRedirector(Environment env, InvokeContext context) { 333 super(env); 334 this.context = context; 335 } 336 337 protected void cocoonRedirect(String uri) throws IOException , ProcessingException { 338 try { 339 ConcreteTreeProcessor.this.handleCocoonRedirect(uri, this.env, this.context); 340 } catch(IOException ioe) { 341 throw ioe; 342 } catch(ProcessingException pe) { 343 throw pe; 344 } catch(RuntimeException re) { 345 throw re; 346 } catch(Exception ex) { 347 throw new ProcessingException(ex); 348 } 349 } 350 } 351 352 356 private static final class ForwardEnvironmentWrapper extends EnvironmentWrapper { 357 358 public ForwardEnvironmentWrapper(Environment env, 359 ComponentManager manager, String uri, Logger logger) 360 throws MalformedURLException { 361 super(env, manager, uri, logger, false); 362 } 363 364 public void setStatus(int statusCode) { 365 environment.setStatus(statusCode); 366 } 367 368 public void setContentLength(int length) { 369 environment.setContentLength(length); 370 } 371 372 public void setContentType(String contentType) { 373 environment.setContentType(contentType); 374 } 375 376 public String getContentType() { 377 return environment.getContentType(); 378 } 379 380 public boolean isResponseModified(long lastModified) { 381 return environment.isResponseModified(lastModified); 382 } 383 384 public void setResponseIsNotModified() { 385 environment.setResponseIsNotModified(); 386 } 387 } 388 } 389 | Popular Tags |