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/12/02 12:54:20 UTC

svn commit: r722434 - in /forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher: impl/helper/AXIOMXPathCreate.java transformation/DispatcherTransformer.java

Author: thorsten
Date: Tue Dec  2 03:54:20 2008
New Revision: 722434

URL: http://svn.apache.org/viewvc?rev=722434&view=rev
Log:
Adding more javadoc and inline comments to the classes

Modified:
    forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/AXIOMXPathCreate.java
    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/java/org/apache/forrest/dispatcher/impl/helper/AXIOMXPathCreate.java
URL: http://svn.apache.org/viewvc/forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/AXIOMXPathCreate.java?rev=722434&r1=722433&r2=722434&view=diff
==============================================================================
--- forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/AXIOMXPathCreate.java (original)
+++ forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/AXIOMXPathCreate.java Tue Dec  2 03:54:20 2008
@@ -31,7 +31,17 @@
 import org.jaxen.JaxenException;
 
 /**
- * Issue: WSCOMMONS-389
+ * 
+ * Return the Node from the rootNode using the XPath expression path.
+ * If the node does not exist, it is created and then returned. This is a very
+ * simple method for creating new nodes. If the XPath contains selectors ([,,,])
+ * or "*" it is of course not possible to create the new node. So if you use
+ * such XPaths the node must exist beforehand. An simple exception is if the
+ * expression contains attribute test to values (e.g. [@id = 'du' and @select = 'true'])
+ * 
+ * 
+ * Issue:
+ * WSCOMMONS-389
  * 
  * As soon the above issue is fixed we need to drop this implementation since
  * this class will be go into the axiom code base.

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=722434&r1=722433&r2=722434&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 Tue Dec  2 03:54:20 2008
@@ -214,7 +214,17 @@
   private OMFactory factory;
   private ContractFactory contractRep;
 
+  /*
+   * Housekeeping variables to indicate the state of processing. Remember SAX is
+   * a stream.
+   */
+  /**
+   * whether or not we need to process the properties
+   */
   private boolean insideProperties = false;
+  /**
+   * whether or not we need are in the requested structurer
+   */
   private boolean includeNodes = true;
   private OMElement root;
 
@@ -245,16 +255,22 @@
     // parameters here
     config = new WritableDispatcherBean();
     config.setStaxHelper(new StAX());
-    allowXml = configuration.getChild("allowXml").getValueAsBoolean(
-        false);
+    // are we allowing xml properties?
+    allowXml = configuration.getChild("allowXml").getValueAsBoolean(false);
     config.setAllowXmlProperties(allowXml);
+    // set the prefix for the contract resolving
     contractUriPrefix = configuration.getChild("contractUriPrefix").getValue(
         "cocoon://resolve.contract.");
+    // set the suffix for the contract
     config.setContractUriSufix(configuration.getChild("contractUriSufix")
         .getValue(""));
+    // what level of xpath support do we want to allow?
     xpathSupport = configuration.getChild("xpathSupport").getValue("basic");
+    // Do we want to shrink xml properties that have only a @value?
     boolean shrink = configuration.getChild("shrink").getValueAsBoolean(true);
     config.setShrink(shrink);
+    // request all factories to be created at this point since it is better to
+    // create them only once
     setNewTransformerFactory();
   }
 
@@ -273,31 +289,57 @@
     contractUriPrefix = config.getContractUriPrefix();
   }
 
+  /**
+   * Will prepare the factories that we need in further processing
+   * 
+   * @throws TransformerFactoryConfigurationError
+   */
   private void setNewTransformerFactory()
       throws TransformerFactoryConfigurationError {
     // Is this the best way to get an instance in cocoon?
     TransformerFactory tfactory = TransformerFactory.newInstance();
+    // set the uri resolver the same as this class
     tfactory.setURIResolver(this);
+    // we want to set the error handler here to make sure it is intitialized
     tfactory.setErrorListener(new TraxErrorHandler(getLogger()));
+    // add the factory to the config
     config.setTransFact(tfactory);
+    // get the OM factory
     this.factory = OMAbstractFactory.getOMFactory();
+    // get the contract factory
     this.contractRep = new ContractFactory(config);
   }
 
-  // we do all the heavy stuff later and only prepare the basics here,
-  // this enhance the response time while caching.
+  /*
+   * @see
+   * org.apache.cocoon.transformation.AbstractSAXTransformer#setup(org.apache
+   * .cocoon.environment.SourceResolver, java.util.Map, java.lang.String,
+   * org.apache.avalon.framework.parameters.Parameters)
+   */
   public void setup(SourceResolver resolver, Map objectModel, String src,
       Parameters par) throws ProcessingException, SAXException, IOException {
+    /*
+     * we do all the heavy stuff later and only prepare the basics here, this
+     * enhance the response time while caching.
+     */
+    // setup our super class
     super.setup(resolver, objectModel, src, par);
-
+    // get the id of this request
     this.requestId = parameters
         .getParameter(DISPATCHER_REQUEST_ATTRIBUTE, null);
+    // get the external cache key
     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.");
+    /*
+     * which is the file use to watch for changes (normally the structurer of
+     * the request). As long the file does not change we are using the cache
+     * object.
+     */
     this.validityFile = parameters.getParameter(VALIDITY_PARAMETER, null);
+    // do we want to force that is caching is turned off?
     this.validityChecking = parameters.getParameter(
         VALIDITY_OVERRIDE_PARAMETER, "");
     if (requestId == null) {
@@ -306,6 +348,7 @@
       getLogger().error(error);
       throw new ProcessingException(error);
     }
+    // which format we want to process?
     this.requestedFormat = parameters.getParameter(Captions.TYPE_ATT, null);
     /*
      * We need to change now the contract uri prefixes since in cocoon we need
@@ -319,11 +362,13 @@
       getLogger().error(error);
       throw new ProcessingException(error);
     }
+    // add the format to the cache key
     this.cacheKey += requestedFormat;
     if (null == m_resolver) {
       try {
         m_resolver = (org.apache.excalibur.source.SourceResolver) manager
             .lookup(SourceResolver.ROLE);
+        // add the resolver we use to the dispatcher
         resolverDispatcher = new CocoonResolver(m_resolver);
         config.setResolver(resolverDispatcher);
       } catch (ServiceException e) {
@@ -343,46 +388,68 @@
   public void startElement(String uri, String name, String raw, Attributes attr)
       throws SAXException {
     // Process start element event
-     if (Captions.NS.equals(uri)) {
+    // Are we inside of properties? If so we need to record the elements.
+    if (this.insideProperties && this.includeNodes) {
+      // just start the recording
+      startSerializedXMLRecording(null);
+    } else if (Captions.NS.equals(uri)) {
+      // we are in the dispatcher ns
       try {
         /*
          * We are in the dispatcher ns.
          */
         getLogger().debug("Starting dispatcher element: " + raw);
-        if (Captions.STRUCTURE_ELEMENT.equals(name)) {
+        if (Captions.STRUCTURER_ELEMENT.equals(name)) {
+          // we are in a structurer definition
           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);
+        }
+        if (this.includeNodes) {
+          if (Captions.HOOK_ELEMENT.equals(name)) {
+            // we are inside a hook element
+            hookProcessingStart(name, raw, attr);
+          } else if (Captions.CONTRACT_ELEMENT.equals(name)) {
+            // we are inside a contract element
+            contractProcessingStart(attr);
+          } else if (Captions.PROPERTY_ELEMENT.equals(name)) {
+            // we are inside a property element
+            this.insideProperties = true;
+            propertyProcessingStart(uri, name, raw, attr);
+          }
         }
       } catch (Exception e) {
         throw new SAXException(e);
       }
     } else {
-      if (!this.insideProperties && this.includeNodes ){
+      if (!this.insideProperties && this.includeNodes) {
         super.startElement(uri, name, raw, attr);
       }
     }
 
   }
-  
+
+  /*
+   * @see
+   * org.apache.cocoon.transformation.AbstractSAXTransformer#endElement(java
+   * .lang.String, java.lang.String, java.lang.String)
+   */
   public void endElement(String uri, String name, String raw)
-  throws SAXException {
+      throws SAXException {
     getLogger().debug("Ending element: " + raw);
-    if (Captions.NS.equals(uri)){
+    if (Captions.NS.equals(uri)) {
+      // we are in the dispatcher ns
       try {
-        if (Captions.STRUCTURE_ELEMENT.equals(name)){
+        if (Captions.STRUCTURE_ELEMENT.equals(name)) {
+          // we are in a structurer end element
           structurerProcessingEnd(raw);
         } else if (Captions.HOOK_ELEMENT.equals(name) && this.includeNodes) {
-          //TODO Implement
+          // we are inside a hook end element
+          // FIXME Implement
         } else if (Captions.CONTRACT_ELEMENT.equals(name) && this.includeNodes) {
+          // we are inside a contract end element
           contractProcessingEnd();
-        } else if (Captions.PROPERTY_ELEMENT.equals(name) && this.includeNodes){
-          if (allowXml){
+        } else if (Captions.PROPERTY_ELEMENT.equals(name) && this.includeNodes) {
+          // we are inside a property end element
+          if (allowXml) {
             String property = null;
             try {
               super.endElement(uri, name, raw);
@@ -390,33 +457,50 @@
             } catch (ProcessingException e) {
               throw new SAXException(e);
             }
-            if (null != property){
+            if (null != property) {
               localParams.put(currentProperty, property.getBytes());
             }
+          } else {
+            // FIXME Implement
           }
         }
       } catch (ContractException e) {
-        throw new SAXException (e);
+        throw new SAXException(e);
       } catch (IOException e) {
-        throw new SAXException (e);
+        throw new SAXException(e);
       } catch (JaxenException e) {
-        throw new SAXException (e);
+        throw new SAXException(e);
       } catch (XMLStreamException e) {
-        throw new SAXException (e);
+        throw new SAXException(e);
       }
-    }else if (!this.insideProperties && this.includeNodes){
+    } else if (!this.insideProperties && this.includeNodes) {
       super.endElement(uri, name, raw);
     }
   }
 
-  private void contractProcessingEnd() throws ContractException, IOException, JaxenException, XMLStreamException {
+  /**
+   * Will execute the contract and process the result.
+   * 
+   * @throws ContractException
+   * @throws IOException
+   * @throws JaxenException
+   * @throws XMLStreamException
+   */
+  private void contractProcessingEnd() throws ContractException, IOException,
+      JaxenException, XMLStreamException {
+    // get the result stream from contract by executing it
     InputStream resultStream = contract.execute(dataStream, localParams);
+    // close data stream
     StreamHelper.closeStream(dataStream);
+    // add the result of the contract to the overall result set
     processContractResult(resultStream, pathNode);
+    // close the result Stream
     StreamHelper.closeStream(resultStream);
   }
 
   /**
+   * Process the contract result to add it to the overall result set.
+   * 
    * @param resultStream
    * @param pathNode
    * @throws XMLStreamException
@@ -425,8 +509,12 @@
   @SuppressWarnings("unchecked")
   private void processContractResult(InputStream resultStream,
       OMElement pathNode) throws XMLStreamException, JaxenException {
-    XMLStreamReader contractResultReader = config.getStaxHelper().getReader(resultStream);
+    // get xml stream reader
+    XMLStreamReader contractResultReader = config.getStaxHelper().getReader(
+        resultStream);
+    // get Axiom builder
     StAXOMBuilder builder = new StAXOMBuilder(contractResultReader);
+    // get the document element
     OMElement content = builder.getDocumentElement();
     /*
      * For full blown ns support we need to get all ns from the result. This
@@ -438,28 +526,40 @@
       OMNamespace space = ns.next();
       spaces.add(space);
     }
+    // get the different parts of the contract
     Iterator<OMElement> parts = content.getChildrenWithName(qIt(
         Captions.NS_CONTRACTS, Captions.PART_ELEMENT));
     while (parts.hasNext()) {
+      // while we have more parts, get the next part
       OMElement part = parts.next();
+      // where do we need to inject it
       String xpath = part.getAttributeValue(qIt(Captions.RESULT_XPATH));
+      // get the children of a part. This children needs to be injected in
+      // the result
       Iterator<OMNode> children = part.getChildren();
       if (xpath == null) {
+        // when we do not have a xpath to inject we will inject it in the
+        // current loaction
         while (children.hasNext()) {
           OMNode child = (OMNode) children.next();
           pathNode.addChild(child);
         }
       } else {
+        // lookup the node where we want to inject the result part
         xpath = PATH_PREFIX + xpath;
         // we need to feed the xpathSelector with the ns we may have
         AXIOMXPathCreate xpathSelector = new AXIOMXPathCreate(xpath);
-
+        // add all namespaces that are known to the selector
         for (OMNamespace space : spaces) {
           xpathSelector
               .addNamespace(space.getPrefix(), space.getNamespaceURI());
         }
+        // request the final inject point (node which will be used to inject the
+        // result)
         OMElement injectionPoint = (OMElement) xpathSelector.selectSingleNode(
             root, true);
+        // now iterate through the children of the result part and append the
+        // content to the injection point
         while (children.hasNext()) {
           OMNode child = (OMNode) children.next();
           injectionPoint.addChild(child);
@@ -468,55 +568,88 @@
       }
     }
   }
+
   /**
+   * Helper method to create a qname
+   * 
    * @param name
-   * @return
+   *          the element name
+   * @return a qualified qname
    */
   private QName qIt(String name) {
     return new QName(name);
   }
+
   /**
+   * Helper method to create a qname
+   * 
    * @param name
+   *          the element name
    * @param uri
-   * @return
+   *          the ns
+   * @return a qualified qname
    */
-  private QName qIt(String uri,String name) {
-    return new QName(uri,name);
+  private QName qIt(String uri, String name) {
+    return new QName(uri, name);
   }
+
+  /**
+   * Finish the processing of the structurer
+   * 
+   * @param raw
+   */
   private void structurerProcessingEnd(String raw) {
-    if(includeNodes){
-      
+    if (includeNodes) {
+      // FIXME: implement
     }
-    
+
   }
 
+  /**
+   * Start the processing of the properties including setting the correct state
+   * for the next event round
+   * 
+   * @param uri
+   * @param name
+   * @param raw
+   * @param attr
+   * @throws SAXException
+   */
   private void propertyProcessingStart(String uri, String name, String raw,
       Attributes attr) throws SAXException {
-    
-    String id = null , value = null;
+    // determine the name and a possible value
+    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)){
+      if (Captions.NAME_ATT.equals(localName)) {
         id = localValue;
-      }else if(Captions.VALUE_ATT.equals(localName)){
+      } else if (Captions.VALUE_ATT.equals(localName)) {
         value = localValue;
       }
     }
-    
-    if (allowXml){
+    // if we allow xml properties we will just record them
+    if (allowXml) {
       // just start the recording
       startSerializedXMLRecording(null);
       super.startElement(uri, name, raw, attr);
       currentProperty = id;
-    }else{
-      if (id!=null && value!= null){
+    } else {
+      // if we do not allow xml we will use a simple key/value approach
+      if (id != null && value != null) {
         localParams.put(id, new String(value));
       }
     }
 
   }
 
+  /**
+   * Start the processing of the contract this includes to resolve the data
+   * stream and the actual contract.
+   * 
+   * @param attr
+   * @throws SAXException
+   */
   private void contractProcessingStart(Attributes attr) throws SAXException {
     String name = "", data = null;
     try {
@@ -524,18 +657,22 @@
         String localName = attr.getLocalName(i);
         String value = attr.getValue(i);
         if (Captions.NAME_ATT.equals(localName)) {
+          // get the name of the contract
           name = value;
         } else if (Captions.DATA_ATT.equals(localName)) {
+          // see whether we have a defined dataUri
           data = value;
         }
       }
       dataStream = null;
       if (null != data && !data.equals("")) {
+        // try resoolving the dataUri
         dataStream = resolverDispatcher.resolve(data);
       }
+      // get the contract
       contract = contractRep.resolve(name);
+      // prepare empty properties map
       localParams = new HashMap<String, Object>(map);
-
     } catch (Exception e) {
       String error = DispatcherException.ERROR_500 + "\n"
           + "component: ContractBean" + "\n"
@@ -547,6 +684,14 @@
 
   }
 
+  /**
+   * Start the processing of the hooks. Actually we just create a element in the
+   * result model with the same name and attributes as the incoming event.
+   * 
+   * @param name
+   * @param raw
+   * @param attr
+   */
   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++) {
@@ -572,9 +717,14 @@
     for (int i = 0; i < attr.getLength(); i++) {
       String localName = attr.getLocalName(i);
       String value = attr.getValue(i);
+      // determine what type (format) we have on the structurer
       if (localName.equals(Captions.TYPE_ATT)) {
         m_type = value;
       }
+      /*
+       * Determine whether we have a hooks path attribute. If so it determines
+       * the smallest common path (e.g. <code>/html/body</code>)
+       */
       if (localName.equals(Captions.HOOKS_ATT)) {
         // adding the default path
         boolean startsWithRoot = "/".equals(String.valueOf(value.charAt(0)));
@@ -586,20 +736,25 @@
         path += value;
       }
     }
+    // are we in the format that have been requested?
     if (requestedFormat.equals(m_type)) {
       try {
         // need to get the properties for this uri
         map = new HashMap<String, Object>();
+        /*
+         * the properties are provided by a match in cocoon and are generated
+         * individually for each request
+         */
         String propertyURI = "cocoon://" + requestId + ".props";
         // get the source representation of the propertyURI
         Source propsSource = m_resolver.resolveURI(propertyURI);
         if (propsSource != null) {
-          // get the stream
+          // get an input stream from the properties
           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.
+           * properties) or we need to process it: extracting the properties.
            */
           if (config.isAllowXmlProperties()) {
             // get the bytes from the stream
@@ -610,12 +765,13 @@
              */
             map.put(DEFAULT_VARIABLES, properties);
           } else {
-            // extract the properties of the in coming stream
+            // extract the properties of the incoming stream
             XMLProperties.parseProperties(stream, map);
           }
           // release source - you need to ALWAYS do this!
           release(propsSource);
         }
+        // creating in/out stream objects
         BufferedInputStream stream = null;
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         /*
@@ -623,10 +779,20 @@
          * need to strip the root element again.
          */
         OMDocument doc = factory.createOMDocument();
+        // creating the root node for the xml document
         root = factory.createOMElement(PATH_PREFIX, null);
+        // adding root element to the document (much like in DOM)
         doc.addChild(root);
-        AXIOMXPathCreate xpath = new AXIOMXPathCreate("/"+PATH_PREFIX + path);
+        /*
+         * request a axiom xpath resolver that will return a axiom element for a
+         * given xpath expression. If the node does not exist, it is created and
+         * then returned.
+         */
+        AXIOMXPathCreate xpath = new AXIOMXPathCreate("/" + PATH_PREFIX + path);
+        // get the node (if it does not exist, create it)
         pathNode = (OMElement) xpath.selectSingleNode(root, true);
+        // we need to set the status variable, indicating we need process the
+        // children.
         this.includeNodes = true;
       } catch (Exception e) {
         throw new DispatcherException(e);