Save This Page
Home » cocoon-2.1.11-src » org.apache » cocoon » components » treeprocessor » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.cocoon.components.treeprocessor;
   18   
   19   import org.apache.avalon.framework.activity.Disposable;
   20   import org.apache.avalon.framework.component.ComponentException;
   21   import org.apache.avalon.framework.component.ComponentManager;
   22   import org.apache.avalon.framework.component.ComponentSelector;
   23   import org.apache.avalon.framework.component.Recomposable;
   24   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   25   import org.apache.cocoon.components.CocoonComponentManager;
   26   import org.apache.cocoon.components.pipeline.ProcessingPipeline;
   27   import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
   28   import org.apache.cocoon.environment.Redirector;
   29   import org.apache.cocoon.sitemap.SitemapErrorHandler;
   30   
   31   import java.util.ArrayList;
   32   import java.util.HashMap;
   33   import java.util.Iterator;
   34   import java.util.List;
   35   import java.util.Map;
   36   
   37   /**
   38    * The invocation context of <code>ProcessingNode</code>s.
   39    *
   40    * <p>This class serves two purposes:
   41    * <ul>
   42    *   <li>Avoid explicit enumeration of all needed parameters in
   43    *       {@link ProcessingNode#invoke(org.apache.cocoon.environment.Environment, InvokeContext)},
   44    *       thus allowing easier addition of new parameters,</li>
   45    *   <li>Hold pipelines, and provide "just in time" lookup for them.</li>
   46    * </ul>
   47    *
   48    * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
   49    * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
   50    * @author <a href="mailto:tcurdt@apache.org">Torsten Curdt</a>
   51    * @version $Id: InvokeContext.java 433543 2006-08-22 06:22:54Z crossley $
   52    */
   53   public class InvokeContext extends AbstractLogEnabled
   54                              implements Recomposable, Disposable {
   55   
   56       private List mapStack = new ArrayList();
   57       private HashMap nameToMap = new HashMap();
   58       private HashMap mapToName = new HashMap();
   59   
   60       /** True if building pipeline only, not processing it. */
   61       private boolean isBuildingPipelineOnly;
   62   
   63       /** The redirector */
   64       protected Redirector redirector;
   65   
   66   
   67       /** The current component manager, as set by the last call to compose() or recompose() */
   68       private ComponentManager currentManager;
   69   
   70       /** The component manager that was used to get the pipelines */
   71       private ComponentManager pipelinesManager;
   72   
   73       /** The name of the processing pipeline component */
   74       protected String processingPipelineName;
   75   
   76       /** The parameters for the processing pipeline */
   77       protected Map processingPipelineParameters;
   78   
   79       /** The object model used to resolve processingPipelineParameters */
   80       protected Map processingPipelineObjectModel;
   81   
   82       /** The Selector for the processing pipeline */
   83       protected ComponentSelector pipelineSelector;
   84   
   85       /** The ProcessingPipeline used */
   86       protected ProcessingPipeline processingPipeline;
   87   
   88       /** The error handler for the pipeline. */
   89       protected SitemapErrorHandler errorHandler;
   90   
   91       /**
   92        * Create an <code>InvokeContext</code> without existing pipelines. This also means
   93        * the current request is external.
   94        */
   95       public InvokeContext() {
   96           this.isBuildingPipelineOnly = false;
   97       }
   98   
   99       /**
  100        * Determines if the Pipeline been set for this context
  101        */
  102       public boolean pipelineIsSet() {
  103   	    return (this.processingPipeline != null);
  104       }
  105   
  106       /**
  107        * Create an <code>InvokeContext</code>
  108        */
  109       public InvokeContext(boolean isBuildingPipelineOnly) {
  110           this.isBuildingPipelineOnly = isBuildingPipelineOnly;
  111       }
  112   
  113       /**
  114        * Composable Interface
  115        */
  116       public void compose(ComponentManager manager) throws ComponentException {
  117           this.currentManager = manager;
  118       }
  119   
  120       /**
  121        * Recomposable interface
  122        */
  123       public void recompose(ComponentManager manager) throws ComponentException {
  124           this.currentManager = manager;
  125           if (this.processingPipeline != null) {
  126               this.processingPipeline.recompose(manager);
  127           }
  128       }
  129   
  130       /**
  131        * Informs the context about a new pipeline section
  132        */
  133       public void inform(String pipelineName,
  134                          Map    parameters,
  135                          Map    objectModel) {
  136           this.processingPipelineName = pipelineName;
  137           this.processingPipelineParameters = parameters;
  138           this.processingPipelineObjectModel = objectModel;
  139       }
  140   
  141       /**
  142        * Get the current <code>ProcessingPipeline</code>
  143        */
  144       public ProcessingPipeline getProcessingPipeline()
  145       throws Exception {
  146           if (this.processingPipeline == null) {
  147               // Keep current manager for proper release
  148               this.pipelinesManager = this.currentManager;
  149   
  150               this.pipelineSelector = (ComponentSelector)this.pipelinesManager.lookup(ProcessingPipeline.ROLE+"Selector");
  151               this.processingPipeline = (ProcessingPipeline)this.pipelineSelector.select(this.processingPipelineName);
  152               this.processingPipeline.recompose( this.pipelinesManager );
  153               this.processingPipeline.setup(
  154                     VariableResolver.buildParameters(this.processingPipelineParameters,
  155                                                      this,
  156                                                      this.processingPipelineObjectModel)
  157               );
  158               if (this.isBuildingPipelineOnly) {
  159                   CocoonComponentManager.addComponentForAutomaticRelease(this.pipelineSelector,
  160                                                                          this.processingPipeline,
  161                                                                          this.pipelinesManager);
  162               }
  163               this.processingPipeline.setErrorHandler(this.errorHandler);
  164           }
  165           return this.processingPipeline;
  166       }
  167   
  168       /**
  169        * Set the processing pipeline for sub-sitemaps
  170        */
  171       public void setProcessingPipeline(ProcessingPipeline pipeline) {
  172           this.processingPipeline = pipeline;
  173       }
  174   
  175       /**
  176        * Are we building a pipeline (and not executing it) ?
  177        */
  178       public final boolean isBuildingPipelineOnly() {
  179           return this.isBuildingPipelineOnly;
  180       }
  181   
  182       /**
  183        * Get the current Map stack used to resolve expressions.
  184        */
  185       public final List getMapStack() {
  186           return this.mapStack;
  187       }
  188   
  189       /**
  190        * Get the result Map by anchor name
  191        */
  192       public final Map getMapByAnchor(String anchor) {
  193           return (Map) this.nameToMap.get(anchor);
  194       }
  195   
  196       /**
  197        * Push a Map on top of the current Map stack.
  198        */
  199       public final void pushMap(String anchorName, Map map) {
  200           this.mapStack.add(map);
  201   
  202           if (getLogger().isDebugEnabled()) {
  203               dumpParameters();
  204           }
  205   
  206           if (anchorName != null) {
  207               if (!this.nameToMap.containsKey(anchorName)) {
  208                   this.nameToMap.put(anchorName,map);
  209                   this.mapToName.put(map,anchorName);
  210               } else {
  211                   if (getLogger().isErrorEnabled()) {
  212                       getLogger().error("name [" + anchorName + "] clashes");
  213                   }
  214               }
  215           }
  216       }
  217   
  218       /**
  219        * Dumps all sitemap parameters to log
  220        */
  221       protected void dumpParameters() {
  222           if (!this.mapStack.isEmpty()) {
  223               StringBuffer sb = new StringBuffer();
  224   
  225               sb.append("\nCurrent Sitemap Parameters:\n");
  226               String path = "";
  227   
  228               for (int i = this.mapStack.size() - 1; i >= 0; i--) {
  229                   Map map = (Map) this.mapStack.get(i);
  230                   sb.append("LEVEL ").append(i+1);
  231                   if (this.mapToName.containsKey(map)) {
  232                       sb.append(" is named '").append(String.valueOf(this.mapToName.get(map))).append("'");
  233                   }
  234                   sb.append("\n");
  235   
  236                   for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
  237                       final Map.Entry me = (Map.Entry)iter.next();
  238                       final Object key = me.getKey();
  239                       sb.append("PARAM: '").append(path).append(key).append("' ");
  240                       sb.append("VALUE: '").append(me.getValue()).append("'\n");
  241                   }
  242                   path = "../" + path;
  243               }
  244   
  245               getLogger().debug(sb.toString());
  246           }
  247       }
  248   
  249       /**
  250        * Pop the topmost element of the current Map stack.
  251        */
  252       public final void popMap() {
  253           Object map = this.mapStack.remove(this.mapStack.size() - 1);
  254           Object name = this.mapToName.get(map);
  255           this.mapToName.remove(map);
  256           this.nameToMap.remove(name);
  257       }
  258   
  259       /**
  260        * Set the redirector to be used by nodes that need it.
  261        *
  262        * @param redirector the redirector
  263        */
  264       public void setRedirector(Redirector redirector) {
  265           this.redirector = redirector;
  266       }
  267   
  268       /**
  269        * Get the redirector to be used by nodes that need it.
  270        *
  271        * @return the redirector
  272        */
  273       public Redirector getRedirector() {
  274           return this.redirector;
  275       }
  276   
  277       /**
  278        * Release the pipelines, if any, if they were looked up by this context.
  279        */
  280       public void dispose() {
  281           if (!this.isBuildingPipelineOnly && this.pipelinesManager != null) {
  282               if (this.pipelineSelector != null) {
  283                   this.pipelineSelector.release(this.processingPipeline);
  284                   this.processingPipeline = null;
  285                   this.pipelinesManager.release(this.pipelineSelector);
  286                   this.pipelineSelector = null;
  287               }
  288               this.pipelinesManager = null;
  289   
  290               this.processingPipelineName = null;
  291               this.processingPipelineParameters = null;
  292               this.processingPipelineObjectModel = null;
  293   
  294               this.errorHandler = null;
  295           }
  296       }
  297   
  298       /**
  299        * Set the error handler for the pipeline.
  300        */
  301       public void setErrorHandler(SitemapErrorHandler handler) {
  302           this.errorHandler = handler;
  303       }
  304   }

Save This Page
Home » cocoon-2.1.11-src » org.apache » cocoon » components » treeprocessor » [javadoc | source]