You are viewing a plain text version of this content. The canonical link for it is here.
Posted to svn@forrest.apache.org by th...@apache.org on 2008/10/31 15:01:37 UTC

svn commit: r709421 - in /forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src: cocoon-2.2-block/src/main/resources/META-INF/cocoon/spring/ java/org/apache/forrest/dispatcher/transformation/

Author: thorsten
Date: Fri Oct 31 07:01:37 2008
New Revision: 709421

URL: http://svn.apache.org/viewvc?rev=709421&view=rev
Log:
Adding a sax implementation again since both other are slower then the former version. The sax version needs still some attention

Added:
    forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherWrapperTransformer.java
      - copied, changed from r708186, forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java
Modified:
    forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/cocoon-2.2-block/src/main/resources/META-INF/cocoon/spring/dispatcher-context.xml
    forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java

Modified: forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/cocoon-2.2-block/src/main/resources/META-INF/cocoon/spring/dispatcher-context.xml
URL: http://svn.apache.org/viewvc/forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/cocoon-2.2-block/src/main/resources/META-INF/cocoon/spring/dispatcher-context.xml?rev=709421&r1=709420&r2=709421&view=diff
==============================================================================
--- forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/cocoon-2.2-block/src/main/resources/META-INF/cocoon/spring/dispatcher-context.xml (original)
+++ forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/cocoon-2.2-block/src/main/resources/META-INF/cocoon/spring/dispatcher-context.xml Fri Oct 31 07:01:37 2008
@@ -18,21 +18,28 @@
   limitations under the License.
 -->
 <beans>
-  <bean id="dispatcher"
+  <bean id="dispatcher" scope="prototype"
     name="org.apache.cocoon.transformation.Transformer/dispatcher"
     class="org.apache.forrest.dispatcher.transformation.DispatcherTransformer">
     <property name="manager" ref="org.apache.avalon.framework.service.ServiceManager"/>
     <property name="config" ref="config"/>
-    <property name="xpathSupport" value="enhanced"/>
+    <property name="xpathSupport" value="basic"/>
   </bean>
-  <bean id="dispatcherEnhanced"
-    name="org.apache.cocoon.transformation.Transformer/dispatcherEnhanced"
-    class="org.apache.forrest.dispatcher.transformation.DispatcherTransformer">
+  <bean id="dispatcherWrapper" scope="prototype"
+    name="org.apache.cocoon.transformation.Transformer/dispatcherWrapper"
+    class="org.apache.forrest.dispatcher.transformation.DispatcherWrapperTransformer">
+    <property name="manager" ref="org.apache.avalon.framework.service.ServiceManager"/>
+    <property name="config" ref="config"/>
+    <property name="xpathSupport" value="basic"/>
+  </bean>
+  <bean id="dispatcherWrapperEnhanced" scope="prototype"
+    name="org.apache.cocoon.transformation.Transformer/dispatcherWrapperEnhanced"
+    class="org.apache.forrest.dispatcher.transformation.DispatcherWrapperTransformer">
     <property name="manager" ref="org.apache.avalon.framework.service.ServiceManager"/>
     <property name="config" ref="config"/>
     <property name="xpathSupport" value="enhanced"/>
   </bean>
-  <bean id="config"
+  <bean id="config" scope="prototype"
     class="org.apache.forrest.dispatcher.config.WritableDispatcherBean">
     <property name="allowXmlProperties" value="true"/>
     <property name="shrink" value="false"/>

Modified: forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java
URL: http://svn.apache.org/viewvc/forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java?rev=709421&r1=709420&r2=709421&view=diff
==============================================================================
--- forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java (original)
+++ forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java Fri Oct 31 07:01:37 2008
@@ -23,8 +23,13 @@
 import java.io.InputStream;
 import java.io.Serializable;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
 
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.TransformerFactoryConfigurationError;
@@ -38,6 +43,15 @@
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.axiom.attachments.utils.IOUtils;
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.cocoon.ProcessingException;
 import org.apache.cocoon.caching.CacheableProcessingComponent;
 import org.apache.cocoon.environment.SourceResolver;
@@ -47,32 +61,33 @@
 import org.apache.excalibur.source.SourceException;
 import org.apache.excalibur.source.SourceValidity;
 import org.apache.excalibur.xml.sax.SAXParser;
+import org.apache.forrest.dispatcher.api.Contract;
+import org.apache.forrest.dispatcher.api.Resolver;
 import org.apache.forrest.dispatcher.api.Structurer;
 import org.apache.forrest.dispatcher.config.DispatcherBean;
 import org.apache.forrest.dispatcher.config.WritableDispatcherBean;
+import org.apache.forrest.dispatcher.exception.ContractException;
 import org.apache.forrest.dispatcher.exception.DispatcherException;
+import org.apache.forrest.dispatcher.factories.ContractFactory;
 import org.apache.forrest.dispatcher.impl.CocoonResolver;
 import org.apache.forrest.dispatcher.impl.XMLStructurer;
 import org.apache.forrest.dispatcher.impl.XMLStructurerAxiom;
+import org.apache.forrest.dispatcher.impl.helper.AXIOMXPathCreate;
 import org.apache.forrest.dispatcher.impl.helper.Captions;
 import org.apache.forrest.dispatcher.impl.helper.StAX;
+import org.apache.forrest.dispatcher.impl.helper.StreamHelper;
 import org.apache.forrest.dispatcher.impl.helper.XMLProperties;
+import org.jaxen.JaxenException;
+import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 /**
- * A cocoon transformer wrapper class for the dispatcher.
+ * A cocoon transformer class for the dispatcher.
  * 
- * The actual work will be done in the core code of the dispatcher which is
- * based on StAX and AXIOM.
- * 
- * <li>In this transformer we doing principal configuration to adopt the
- * dispatcher to the cocoon environment ({@link #configure(Configuration)} and (
- * {@link #setup(SourceResolver, Map, String, Parameters)} <li>We reusing cocoon
- * caching mechanism ({@link #getKey()} and {@link #getValidity()} to cache the
- * dispatcher. <li>We record the SAX events ({@link #startDocument()} to later
- * {@link #endDocument()} passing them as Stream to the Structurer
- * implementation we have chosen.
+ * Unlike the wrapper this class will do the actual work and only reuse the
+ * contract handling from the core. This class is nearly the same as we had
+ * before just switching DOM for StAX/AXIOM.
  * 
  * @version 1.0
  * 
@@ -80,6 +95,8 @@
 public class DispatcherTransformer extends AbstractSAXTransformer implements
     Disposable, CacheableProcessingComponent, URIResolver {
 
+  private static final String PATH_PREFIX = "result";
+
   /**
    * The requested format.
    * <p>
@@ -137,17 +154,21 @@
   /**
    * Main configuration bean of the dispatcher.
    * <p>
-   * This config will control things like <li>contract prefixes/suffixes <li>
+   * This config will control things like
+   * <li>contract prefixes/suffixes
+   * <li>
    * resolver to use
    */
   private WritableDispatcherBean config;
 
   /**
-   * Cocoon 2.2 compatible method.
-   * Allow that the ServiceManager is be set via e.g. spring
-   * @param manager manger to use in the context
+   * Cocoon 2.2 compatible method. Allow that the ServiceManager is be set via
+   * e.g. spring
+   * 
+   * @param manager
+   *          manger to use in the context
    */
-  public void setManager(ServiceManager manager){
+  public void setManager(ServiceManager manager) {
     this.manager = manager;
   }
 
@@ -162,7 +183,8 @@
   private String xpathSupport;
 
   /**
-   * @param xpathSupport the xpathSupport to set
+   * @param xpathSupport
+   *          the xpathSupport to set
    */
   public synchronized void setXpathSupport(String xpathSupport) {
     this.xpathSupport = xpathSupport;
@@ -184,6 +206,34 @@
    */
   private static final String DEFAULT_VARIABLES = "defaultVariables";
 
+  /**
+   * preparing the parser that will pick up the result and pass it to the
+   * consumer again.
+   */
+  private SAXParser parser = null;
+  private OMFactory factory;
+  private ContractFactory contractRep;
+
+  private boolean insideProperties = false;
+  private boolean includeNodes = true;
+  private OMElement root;
+
+  private OMElement pathNode;
+
+  private Resolver resolverDispatcher;
+
+  private Contract contract;
+
+  private HashMap<String, Object> map;
+
+  private HashMap<String, Object> localParams;
+
+  private boolean allowXml;
+
+  private String currentProperty;
+
+  private InputStream dataStream;
+
   /*
    * @see
    * org.apache.cocoon.transformation.AbstractSAXTransformer#configure(org.apache
@@ -195,37 +245,43 @@
     // parameters here
     config = new WritableDispatcherBean();
     config.setStaxHelper(new StAX());
-    boolean allowXml = configuration.getChild("allowXml").getValueAsBoolean(
+    allowXml = configuration.getChild("allowXml").getValueAsBoolean(
         false);
     config.setAllowXmlProperties(allowXml);
     contractUriPrefix = configuration.getChild("contractUriPrefix").getValue(
         "cocoon://resolve.contract.");
-    config.setContractUriSufix(configuration.getChild("contractUriSufix").getValue(""));
+    config.setContractUriSufix(configuration.getChild("contractUriSufix")
+        .getValue(""));
     xpathSupport = configuration.getChild("xpathSupport").getValue("basic");
     boolean shrink = configuration.getChild("shrink").getValueAsBoolean(true);
     config.setShrink(shrink);
     setNewTransformerFactory();
   }
-  
+
   /**
-   * Cocoon 2.2 compatible method.
-   * Allow that the WritableDispatcherBean is be set via e.g. spring
-   * @param config the configuration to use.
+   * Cocoon 2.2 compatible method. Allow that the WritableDispatcherBean is be
+   * set via e.g. spring
+   * 
+   * @param config
+   *          the configuration to use.
    */
   public void setConfig(WritableDispatcherBean config) {
     this.config = config;
-    if(config.getTransFact()==null){
+    if (config.getTransFact() == null) {
       setNewTransformerFactory();
     }
     contractUriPrefix = config.getContractUriPrefix();
   }
+
   private void setNewTransformerFactory()
       throws TransformerFactoryConfigurationError {
-    // FIXME: is this the best way to get an instance in cocoon?
+    // Is this the best way to get an instance in cocoon?
     TransformerFactory tfactory = TransformerFactory.newInstance();
     tfactory.setURIResolver(this);
     tfactory.setErrorListener(new TraxErrorHandler(getLogger()));
     config.setTransFact(tfactory);
+    this.factory = OMAbstractFactory.getOMFactory();
+    this.contractRep = new ContractFactory(config);
   }
 
   // we do all the heavy stuff later and only prepare the basics here,
@@ -238,8 +294,9 @@
         .getParameter(DISPATCHER_REQUEST_ATTRIBUTE, null);
     this.cacheKey = parameters.getParameter(CACHE_PARAMETER, null);
     if (null == this.cacheKey)
-      getLogger().warn("Caching not activated! Declare the CACHE_KEY_PARAMETER="
-          + CACHE_PARAMETER + " in your sitemap.");
+      getLogger().warn(
+          "Caching not activated! Declare the CACHE_KEY_PARAMETER="
+              + CACHE_PARAMETER + " in your sitemap.");
     this.validityFile = parameters.getParameter(VALIDITY_PARAMETER, null);
     this.validityChecking = parameters.getParameter(
         VALIDITY_OVERRIDE_PARAMETER, "");
@@ -263,48 +320,331 @@
       throw new ProcessingException(error);
     }
     this.cacheKey += requestedFormat;
-    if (null == m_resolver){
+    if (null == m_resolver) {
       try {
         m_resolver = (org.apache.excalibur.source.SourceResolver) manager
             .lookup(SourceResolver.ROLE);
-        config.setResolver(new CocoonResolver(m_resolver));
+        resolverDispatcher = new CocoonResolver(m_resolver);
+        config.setResolver(resolverDispatcher);
       } catch (ServiceException e) {
         throw new ProcessingException(e);
       }
     }
   }
+
+  /*
+   * old transformer link @see
+   * http://svn.apache.org/viewvc?view=rev&revision=694101
+   * 
+   * @see
+   * org.apache.cocoon.transformation.AbstractSAXTransformer#startElement(String
+   * uri, String name, String raw, Attributes attr)
+   */
+  public void startElement(String uri, String name, String raw, Attributes attr)
+      throws SAXException {
+    // Process start element event
+     if (Captions.NS.equals(uri)) {
+      try {
+        /*
+         * We are in the dispatcher ns.
+         */
+        getLogger().debug("Starting dispatcher element: " + raw);
+        if (Captions.STRUCTURE_ELEMENT.equals(name)) {
+          structurerProcessingStart(attr);
+        } else if (Captions.HOOK_ELEMENT.equals(name) && this.includeNodes) {
+          hookProcessingStart(name, raw, attr);
+        } else if (Captions.CONTRACT_ELEMENT.equals(name) && this.includeNodes) {
+          contractProcessingStart(attr);
+        } else if (Captions.PROPERTY_ELEMENT.equals(name) && this.includeNodes) {
+          this.insideProperties = true;
+          propertyProcessingStart(uri, name, raw, attr);
+        }
+      } catch (Exception e) {
+        throw new SAXException(e);
+      }
+    } else {
+      if (!this.insideProperties && this.includeNodes ){
+        super.startElement(uri, name, raw, attr);
+      }
+    }
+
+  }
   
-/*
- * Here we just start recording to use them later on.
- * 
- * In the future we may want to implement a sax based 
- * structurer implementation again.
- * 
- * old transformer link @see
- * http://svn.apache.org/viewvc?view=rev&revision=694101
- * 
- * @see org.apache.cocoon.transformation.AbstractSAXTransformer#startDocument()
- */
-  public void startDocument() throws SAXException {
-    // just start the recording
-    startSerializedXMLRecording(null);
+  public void endElement(String uri, String name, String raw)
+  throws SAXException {
+    getLogger().debug("Ending element: " + raw);
+    if (Captions.NS.equals(uri)){
+      try {
+        if (Captions.STRUCTURE_ELEMENT.equals(name)){
+          structurerProcessingEnd(raw);
+        } else if (Captions.HOOK_ELEMENT.equals(name) && this.includeNodes) {
+          //TODO Implement
+        } else if (Captions.CONTRACT_ELEMENT.equals(name) && this.includeNodes) {
+          contractProcessingEnd();
+        } else if (Captions.PROPERTY_ELEMENT.equals(name) && this.includeNodes){
+          if (allowXml){
+            String property = null;
+            try {
+              super.endElement(uri, name, raw);
+              property = super.endSerializedXMLRecording();
+            } catch (ProcessingException e) {
+              throw new SAXException(e);
+            }
+            if (null != property){
+              localParams.put(currentProperty, property.getBytes());
+            }
+          }
+        }
+      } catch (ContractException e) {
+        throw new SAXException (e);
+      } catch (IOException e) {
+        throw new SAXException (e);
+      } catch (JaxenException e) {
+        throw new SAXException (e);
+      } catch (XMLStreamException e) {
+        throw new SAXException (e);
+      }
+    }else if (!this.insideProperties && this.includeNodes){
+      super.endElement(uri, name, raw);
+    }
+  }
+
+  private void contractProcessingEnd() throws ContractException, IOException, JaxenException, XMLStreamException {
+    InputStream resultStream = contract.execute(dataStream, localParams);
+    StreamHelper.closeStream(dataStream);
+    processContractResult(resultStream, pathNode);
+    StreamHelper.closeStream(resultStream);
+  }
+
+  /**
+   * @param resultStream
+   * @param pathNode
+   * @throws XMLStreamException
+   * @throws JaxenException
+   */
+  @SuppressWarnings("unchecked")
+  private void processContractResult(InputStream resultStream,
+      OMElement pathNode) throws XMLStreamException, JaxenException {
+    XMLStreamReader contractResultReader = config.getStaxHelper().getReader(resultStream);
+    StAXOMBuilder builder = new StAXOMBuilder(contractResultReader);
+    OMElement content = builder.getDocumentElement();
+    /*
+     * For full blown ns support we need to get all ns from the result. This
+     * will be passed later to the XPath processor.
+     */
+    Iterator<OMNamespace> ns = content.getAllDeclaredNamespaces();
+    HashSet<OMNamespace> spaces = new HashSet<OMNamespace>();
+    while (ns.hasNext()) {
+      OMNamespace space = ns.next();
+      spaces.add(space);
+    }
+    Iterator<OMElement> parts = content.getChildrenWithName(qIt(
+        Captions.NS_CONTRACTS, Captions.PART_ELEMENT));
+    while (parts.hasNext()) {
+      OMElement part = parts.next();
+      String xpath = part.getAttributeValue(qIt(Captions.RESULT_XPATH));
+      Iterator<OMNode> children = part.getChildren();
+      if (xpath == null) {
+        while (children.hasNext()) {
+          OMNode child = (OMNode) children.next();
+          pathNode.addChild(child);
+        }
+      } else {
+        xpath = PATH_PREFIX + xpath;
+        // we need to feed the xpathSelector with the ns we may have
+        AXIOMXPathCreate xpathSelector = new AXIOMXPathCreate(xpath);
+
+        for (OMNamespace space : spaces) {
+          xpathSelector
+              .addNamespace(space.getPrefix(), space.getNamespaceURI());
+        }
+        OMElement injectionPoint = (OMElement) xpathSelector.selectSingleNode(
+            root, true);
+        while (children.hasNext()) {
+          OMNode child = (OMNode) children.next();
+          injectionPoint.addChild(child);
+        }
+
+      }
+    }
+  }
+  /**
+   * @param name
+   * @return
+   */
+  private QName qIt(String name) {
+    return new QName(name);
+  }
+  /**
+   * @param name
+   * @param uri
+   * @return
+   */
+  private QName qIt(String uri,String name) {
+    return new QName(uri,name);
+  }
+  private void structurerProcessingEnd(String raw) {
+    if(includeNodes){
+      
+    }
+    
+  }
+
+  private void propertyProcessingStart(String uri, String name, String raw,
+      Attributes attr) throws SAXException {
+    
+    String id = null , value = null;
+    for (int i = 0; i < attr.getLength(); i++) {
+      String localName = attr.getLocalName(i);
+      String localValue = attr.getValue(i);
+      if (Captions.NAME_ATT.equals(localName)){
+        id = localValue;
+      }else if(Captions.VALUE_ATT.equals(localName)){
+        value = localValue;
+      }
+    }
+    
+    if (allowXml){
+      // just start the recording
+      startSerializedXMLRecording(null);
+      super.startElement(uri, name, raw, attr);
+      currentProperty = id;
+    }else{
+      if (id!=null && value!= null){
+        localParams.put(id, new String(value));
+      }
+    }
+
+  }
+
+  private void contractProcessingStart(Attributes attr) throws SAXException {
+    String name = "", data = null;
+    try {
+      for (int i = 0; i < attr.getLength(); i++) {
+        String localName = attr.getLocalName(i);
+        String value = attr.getValue(i);
+        if (Captions.NAME_ATT.equals(localName)) {
+          name = value;
+        } else if (Captions.DATA_ATT.equals(localName)) {
+          data = value;
+        }
+      }
+      dataStream = null;
+      if (null != data && !data.equals("")) {
+        dataStream = resolverDispatcher.resolve(data);
+      }
+      contract = contractRep.resolve(name);
+      localParams = new HashMap<String, Object>(map);
+
+    } catch (Exception e) {
+      String error = DispatcherException.ERROR_500 + "\n"
+          + "component: ContractBean" + "\n"
+          + "message: Could not setup contractBean." + "\n" + "\n\n"
+          + "dispatcherErrorStack:\n" + e;
+      getLogger().error(error);
+      throw new SAXException(error);
+    }
+
+  }
+
+  private void hookProcessingStart(String name, String raw, Attributes attr) {
+    OMElement element = factory.createOMElement(name, Captions.NS, "forrest");
+    for (int i = 0; i < attr.getLength(); i++) {
+      String localName = attr.getLocalName(i);
+      String value = attr.getValue(i);
+      OMAttribute attribute = factory.createOMAttribute(localName, null, value);
+      element.addAttribute(attribute);
+    }
+    pathNode.addChild(element);
+  }
+
+  /**
+   * view type="?" Here we check which format we have in the view. That should
+   * be extended to matching the requested format
+   * 
+   * @param attr
+   * @throws JaxenException
+   * @throws SAXException
+   */
+  private void structurerProcessingStart(Attributes attr)
+      throws DispatcherException {
+    String m_type = "", path = "";
+    for (int i = 0; i < attr.getLength(); i++) {
+      String localName = attr.getLocalName(i);
+      String value = attr.getValue(i);
+      if (localName.equals(Captions.TYPE_ATT)) {
+        m_type = value;
+      }
+      if (localName.equals(Captions.HOOKS_ATT)) {
+        // adding the default path
+        boolean startsWithRoot = "/".equals(String.valueOf(value.charAt(0)));
+        if (!startsWithRoot) {
+          value = "/" + value;
+        } else if (value.length() == 1 && startsWithRoot) {
+          value = "";
+        }
+        path += value;
+      }
+    }
+    if (requestedFormat.equals(m_type)) {
+      try {
+        // need to get the properties for this uri
+        map = new HashMap<String, Object>();
+        String propertyURI = "cocoon://" + requestId + ".props";
+        // get the source representation of the propertyURI
+        Source propsSource = m_resolver.resolveURI(propertyURI);
+        if (propsSource != null) {
+          // get the stream
+          InputStream stream = new BufferedInputStream(propsSource
+              .getInputStream());
+          /*
+           * we need either just the bytes of the stream (if we allow xml
+           * properties) or we need to process it extracting the properties.
+           */
+          if (config.isAllowXmlProperties()) {
+            // get the bytes from the stream
+            byte[] properties = IOUtils.getStreamAsByteArray(stream);
+            /*
+             * add the bytes to the properties map later on they will be picked
+             * up and parsed to a dom node.
+             */
+            map.put(DEFAULT_VARIABLES, properties);
+          } else {
+            // extract the properties of the in coming stream
+            XMLProperties.parseProperties(stream, map);
+          }
+          // release source - you need to ALWAYS do this!
+          release(propsSource);
+        }
+        BufferedInputStream stream = null;
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        /*
+         * Preparing the model by creating a root document/element. Afterward we
+         * need to strip the root element again.
+         */
+        OMDocument doc = factory.createOMDocument();
+        root = factory.createOMElement(PATH_PREFIX, null);
+        doc.addChild(root);
+        AXIOMXPathCreate xpath = new AXIOMXPathCreate("/"+PATH_PREFIX + path);
+        pathNode = (OMElement) xpath.selectSingleNode(root, true);
+        this.includeNodes = true;
+      } catch (Exception e) {
+        throw new DispatcherException(e);
+      }
+    } else {
+      pathNode = null; // unset path because we do not process the node
+      this.includeNodes = false;
+    }
+
   }
 
   /*
-   * Here we pick up the recoreder result and start the
-   * processing on it.
+   * Here we pick up the recoreder result and start the processing on it.
    * 
    * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endDocument()
    */
   public void endDocument() throws SAXException {
-    // the recorded document we just streamed
-    String document = null;
-    try {
-      // request the information from the recorder
-      document = super.endSerializedXMLRecording();
-    } catch (ProcessingException e) {
-      throw new SAXException(e);
-    }
+
     // start structurer routine
     Structurer structurer = null;
     // need to get the properties for this uri
@@ -314,28 +654,26 @@
       // get the source representation of the propertyURI
       Source propsSource = m_resolver.resolveURI(propertyURI);
       if (propsSource != null) {
-        // get the stream 
+        // get the stream
         InputStream stream = new BufferedInputStream(propsSource
             .getInputStream());
         /*
-         * we need either just the bytes of the stream (if we allow
-         * xml properties) or we need to process it extracting the 
-         * properties.  
+         * we need either just the bytes of the stream (if we allow xml
+         * properties) or we need to process it extracting the properties.
          */
         if (config.isAllowXmlProperties()) {
           // get the bytes from the stream
           byte[] properties = IOUtils.getStreamAsByteArray(stream);
           /*
-           *  add the bytes to the properties map
-           *  later on they will be picked up and
-           *  parsed to a dom node.
+           * add the bytes to the properties map later on they will be picked up
+           * and parsed to a dom node.
            */
           map.put(DEFAULT_VARIABLES, properties);
         } else {
           // extract the properties of the in coming stream
           XMLProperties.parseProperties(stream, map);
         }
-        // release source - you need to ALWAYS do this! 
+        // release source - you need to ALWAYS do this!
         release(propsSource);
       }
     } catch (Exception e) {
@@ -344,26 +682,29 @@
     // which implementation do we want
     if (xpathSupport.equals("enhanced")) {
       /*
-       * The axiom implementation is an object model
-       * approach to StAX. It allows you a dom like navigation
-       * (allocate xpath nodes), adding of child elements in
-       * this xpath statement and many more. 
+       * The axiom implementation is an object model approach to StAX. It allows
+       * you a dom like navigation (allocate xpath nodes), adding of child
+       * elements in this xpath statement and many more.
        */
-      structurer = new XMLStructurerAxiom((DispatcherBean)config, map);
+      structurer = new XMLStructurerAxiom((DispatcherBean) config, map);
     } else {
       /*
-       * The stax implementationis 100% StAX even the generation 
-       * of the resulting document is done with StAX.
-       * However it does not offer real support of xpath expressions.
+       * The stax implementationis 100% StAX even the generation of the
+       * resulting document is done with StAX. However it does not offer real
+       * support of xpath expressions.
        */
-      structurer = new XMLStructurer((DispatcherBean)config, map);
+      structurer = new XMLStructurer((DispatcherBean) config, map);
     }
-    /*
-     * preparing the parser that will pick up the result and
-     * pass it to the consumer again. 
-     */
-    SAXParser parser = null;
+
     try {
+      // the recorded document we just streamed
+      String document = null;
+      try {
+        // request the information from the recorder
+        document = super.endSerializedXMLRecording();
+      } catch (ProcessingException e) {
+        throw new SAXException(e);
+      }
       // get the result of the structurer as stream
       InputStream result = structurer.execute(new BufferedInputStream(
           new ByteArrayInputStream(document.getBytes())), requestedFormat);
@@ -377,7 +718,7 @@
       throw new SAXException(e);
     } finally {
       if (null != parser) {
-     // release parser - you need to ALWAYS do this! 
+        // release parser - you need to ALWAYS do this!
         manager.release(parser);
       }
     }
@@ -456,9 +797,11 @@
 
   }
 
-  /* 
+  /*
    * From URIResolver, copied from TraxProcessor
-   * @see javax.xml.transform.URIResolver#resolve(java.lang.String, java.lang.String)
+   * 
+   * @see javax.xml.transform.URIResolver#resolve(java.lang.String,
+   * java.lang.String)
    */
   public javax.xml.transform.Source resolve(String href, String base)
       throws TransformerException {

Copied: forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherWrapperTransformer.java (from r708186, forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java)
URL: http://svn.apache.org/viewvc/forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherWrapperTransformer.java?p2=forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherWrapperTransformer.java&p1=forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java&r1=708186&r2=709421&rev=709421&view=diff
==============================================================================
--- forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java (original)
+++ forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherWrapperTransformer.java Fri Oct 31 07:01:37 2008
@@ -77,7 +77,7 @@
  * @version 1.0
  * 
  */
-public class DispatcherTransformer extends AbstractSAXTransformer implements
+public class DispatcherWrapperTransformer extends AbstractSAXTransformer implements
     Disposable, CacheableProcessingComponent, URIResolver {
 
   /**
@@ -184,6 +184,11 @@
    */
   private static final String DEFAULT_VARIABLES = "defaultVariables";
 
+  /**
+   * preparing the parser that will pick up the result and
+   * pass it to the consumer again. 
+   */
+  SAXParser parser = null;
   /*
    * @see
    * org.apache.cocoon.transformation.AbstractSAXTransformer#configure(org.apache
@@ -297,14 +302,7 @@
    * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endDocument()
    */
   public void endDocument() throws SAXException {
-    // the recorded document we just streamed
-    String document = null;
-    try {
-      // request the information from the recorder
-      document = super.endSerializedXMLRecording();
-    } catch (ProcessingException e) {
-      throw new SAXException(e);
-    }
+    
     // start structurer routine
     Structurer structurer = null;
     // need to get the properties for this uri
@@ -358,19 +356,23 @@
        */
       structurer = new XMLStructurer((DispatcherBean)config, map);
     }
-    /*
-     * preparing the parser that will pick up the result and
-     * pass it to the consumer again. 
-     */
-    SAXParser parser = null;
+    
     try {
-      // get the result of the structurer as stream
-      InputStream result = structurer.execute(new BufferedInputStream(
-          new ByteArrayInputStream(document.getBytes())), requestedFormat);
-      // requesting a parser
-      parser = (SAXParser) manager.lookup(SAXParser.ROLE);
-      // adding the result to the consumer
-      parser.parse(new InputSource(result), super.xmlConsumer);
+     // the recorded document we just streamed
+        String document = null;
+        try {
+          // request the information from the recorder
+          document = super.endSerializedXMLRecording();
+        } catch (ProcessingException e) {
+          throw new SAXException(e);
+        }
+        // get the result of the structurer as stream
+        InputStream result = structurer.execute(new BufferedInputStream(
+            new ByteArrayInputStream(document.getBytes())), requestedFormat);
+     // requesting a parser
+        parser = (SAXParser) manager.lookup(SAXParser.ROLE);
+        // adding the result to the consumer
+        parser.parse(new InputSource(result), super.xmlConsumer); 
     } catch (DispatcherException e) {
       throw new SAXException(e);
     } catch (Exception e) {