Author: thorsten
Date: Thu Oct  9 04:11:07 2008
New Revision: 703133

URL: http://svn.apache.org/viewvc?rev=703133&view=rev
Log:
FOR-1127
Switching to use contract exception and enhancing the code around the exception 
handling in general. 

Further adding note about the possibility of enhancing the contract processing. 
It is possible to allow contracts to fail if they are not critical for the 
overall result. This is a nice possible future feature. One can imaging to use 
an @critical='true|false' to indicate whether to fail or not.

e.g.  
<forrest:contract 
    critical="false"
    name="siteinfo-meta-navigation" 
    dataURI="cocoon://#{$getRequest}.navigation.xml"/>

with this tag the dispatcher will not fail if the contact fails.

Fixing problem for non-xml output. Instead of assuming the existence of a root 
element we now check if there is one and if not we create one.

Further enhancing the usage of generics and annotations.

Modified:
    
forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/XMLStructurerAxiom.java

Modified: 
forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/XMLStructurerAxiom.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/XMLStructurerAxiom.java?rev=703133&r1=703132&r2=703133&view=diff
==============================================================================
--- 
forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/XMLStructurerAxiom.java
 (original)
+++ 
forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/XMLStructurerAxiom.java
 Thu Oct  9 04:11:07 2008
@@ -27,6 +27,7 @@
 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.exception.ContractException;
 import org.apache.forrest.dispatcher.exception.DispatcherException;
 import org.apache.forrest.dispatcher.factories.ContractFactory;
 import org.apache.forrest.dispatcher.impl.helper.AXIOMXPathCreate;
@@ -45,8 +46,6 @@
 
   private final ContractFactory contractRep;
 
-  private LinkedHashMap<String, LinkedHashSet<OMNode>> resultTree = new 
LinkedHashMap<String, LinkedHashSet<OMNode>>();
-
   private OMFactory factory;
 
   private OMElement root;
@@ -73,6 +72,7 @@
    * org.apache.forrest.dispatcher.impl.Structurer#execute(java.io.InputStream,
    * java.lang.String)
    */
+  @SuppressWarnings("unchecked")
   public InputStream execute(InputStream structurerStream, String format)
       throws DispatcherException {
     BufferedInputStream stream = null;
@@ -125,7 +125,12 @@
        * because the output of a structurer needs to be well-formed and there
        * should only be one child in any circumstance.
        */
-      root.getFirstElement().serialize(out);
+      OMElement firstElement = root.getFirstElement();
+      if (null!=firstElement){
+        firstElement.serialize(out);
+      }else{
+        root.serialize(out);
+      }
       // debug hook
       // next line will get the whole result document
       // root.serialize(out);
@@ -166,6 +171,7 @@
    * @throws IOException
    * @throws JaxenException
    */
+  @SuppressWarnings("unchecked")
   private void processStructure(OMElement structure, OMElement pathNode)
       throws XMLStreamException, DispatcherException, IOException,
       JaxenException {
@@ -211,6 +217,7 @@
    * @throws IOException
    * @throws JaxenException
    */
+  @SuppressWarnings("unchecked")
   private void processHook(OMElement component, OMElement pathNode)
       throws DispatcherException, XMLStreamException, IOException,
       JaxenException {
@@ -239,6 +246,7 @@
    * @throws IOException
    * @throws JaxenException
    */
+  @SuppressWarnings("unchecked")
   private void processContract(OMElement component, OMElement pathNode)
       throws DispatcherException, XMLStreamException, IOException,
       JaxenException {
@@ -259,10 +267,24 @@
         processProperty((OMElement) node, localParams);
       }
     }
-    InputStream resultStream = contract.execute(dataStream, localParams);
-    StreamHelper.closeStream(dataStream);
-    processContractResult(resultStream, pathNode);
-    StreamHelper.closeStream(resultStream);
+    try {
+      InputStream resultStream = contract.execute(dataStream, localParams);
+      StreamHelper.closeStream(dataStream);
+      processContractResult(resultStream, pathNode);
+      StreamHelper.closeStream(resultStream);
+    } catch (Exception e) {
+      /*
+       *  FOR-1127
+       *  Here we can inject custom handler for allowing that contracts can
+       *  throw exceptions but the overall structurer will not fail at whole.
+       *  
+       *  Imaging contract "xyz" will fail. Now we throw an exception and 
abort 
+       *  processing. However it may be desirable that the process continues
+       *  since the contract may not be critical for the overall result.
+       *  
+       */
+      throw new ContractException(name,"\n",e);
+    }
   }
 
   /**
@@ -271,6 +293,7 @@
    * @throws XMLStreamException
    * @throws JaxenException
    */
+  @SuppressWarnings("unchecked")
   private void processContractResult(InputStream resultStream,
       OMElement pathNode) throws XMLStreamException, JaxenException {
     XMLStreamReader contractResultReader = getReader(resultStream);
@@ -338,7 +361,7 @@
    * @param param
    * @throws XMLStreamException
    */
-  private void processProperty(OMElement properties, Map param)
+  private void processProperty(OMElement properties, Map<String, Object> param)
       throws XMLStreamException {
     String propertyName = null, propertyValue = null;
     propertyName = properties.getAttributeValue(qIt(Captions.NAME_ATT));