You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by rw...@apache.org on 2012/02/01 12:59:38 UTC

svn commit: r1239097 [2/2] - in /incubator/stanbol/trunk: enhancer/chain/list/src/main/java/org/apache/stanbol/enhancer/chain/list/impl/ enhancer/chain/list/src/main/resources/OSGI-INF/metatype/ enhancer/generic/servicesapi/src/main/java/org/apache/sta...

Modified: incubator/stanbol/trunk/enhancer/jersey/src/main/java/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/java/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/java/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource.java (original)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/java/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource.java Wed Feb  1 11:59:37 2012
@@ -25,12 +25,16 @@ import static org.apache.stanbol.commons
 import static org.apache.stanbol.commons.web.base.CorsHelper.enableCORS;
 import static org.apache.stanbol.commons.web.base.utils.MediaTypeUtil.SUPPORTED_RDF_TYPES;
 import static org.apache.stanbol.commons.web.base.utils.MediaTypeUtil.isAcceptableMediaType;
+import static org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper.getReference;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.getExecutionNode;
 import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.isOptional;
 import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan.EXECUTION_NODE;
 import static org.apache.stanbol.enhancer.servicesapi.rdf.Properties.RDF_TYPE;
 
 import java.io.IOException;
+import java.net.URI;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -58,6 +62,8 @@ import org.apache.clerezza.rdf.core.Grap
 import org.apache.clerezza.rdf.core.MGraph;
 import org.apache.clerezza.rdf.core.NonLiteral;
 import org.apache.clerezza.rdf.core.Triple;
+import org.apache.clerezza.rdf.core.TripleCollection;
+import org.apache.clerezza.rdf.core.UriRef;
 import org.apache.clerezza.rdf.core.access.TcManager;
 import org.apache.clerezza.rdf.core.impl.PlainLiteralImpl;
 import org.apache.clerezza.rdf.core.serializedform.Serializer;
@@ -74,8 +80,12 @@ import org.apache.stanbol.enhancer.servi
 import org.apache.stanbol.enhancer.servicesapi.EnhancementEngineManager;
 import org.apache.stanbol.enhancer.servicesapi.EnhancementException;
 import org.apache.stanbol.enhancer.servicesapi.EnhancementJobManager;
+import org.apache.stanbol.enhancer.servicesapi.NoSuchPartException;
+import org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper;
+import org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper;
 import org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper;
 import org.apache.stanbol.enhancer.servicesapi.helper.InMemoryContentItem;
+import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata;
 import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan;
 import org.apache.stanbol.enhancer.servicesapi.rdf.Properties;
 import org.slf4j.Logger;
@@ -121,6 +131,10 @@ public class EnhancerRootResource extend
         chain = chainManager.getDefault();
     }
     
+    public URI getServiceUrl(){
+        return uriInfo.getAbsolutePath();
+    }
+    
     @OPTIONS
     public Response handleCorsPreflight(@Context HttpHeaders headers){
         ResponseBuilder res = Response.ok();
@@ -251,7 +265,7 @@ public class EnhancerRootResource extend
                                     @Context HttpHeaders headers) throws EnhancementException, IOException {
         log.info("enhance from From: " + content);
         ContentItem ci = new InMemoryContentItem(content.getBytes("UTF-8"), TEXT_PLAIN);
-        return enhanceAndBuildResponse(format, headers, ci, buildAjaxview);
+        return enhanceAndBuildResponse(format, headers, ci, false ,buildAjaxview);
     }
 
     /**
@@ -269,6 +283,7 @@ public class EnhancerRootResource extend
     @Consumes(WILDCARD)
     public Response enhanceFromData(byte[] data,
                                     @QueryParam(value = "uri") String uri,
+                                    @QueryParam(value = "executionmetadata") boolean inclExecMetadata,
                                     @Context HttpHeaders headers) throws EnhancementException, IOException {
         String format = TEXT_PLAIN;
         if (headers.getMediaType() != null) {
@@ -279,12 +294,13 @@ public class EnhancerRootResource extend
             uri = null;
         }
         ContentItem ci = new InMemoryContentItem(uri, data, format);
-        return enhanceAndBuildResponse(null, headers, ci, false);
+        return enhanceAndBuildResponse(null, headers, ci, inclExecMetadata, false);
     }
 
     protected Response enhanceAndBuildResponse(String format,
                                                HttpHeaders headers,
                                                ContentItem ci,
+                                               boolean inclExecMetadata ,
                                                boolean buildAjaxview) throws EnhancementException, IOException {
         if (jobManager != null) {
             jobManager.enhanceContent(ci,chain);
@@ -302,6 +318,13 @@ public class EnhancerRootResource extend
         }
         
         MGraph graph = ci.getMetadata();
+        if(inclExecMetadata){
+            try {
+                graph.addAll(ci.getPart(ExecutionMetadata.CHAIN_EXECUTION, MGraph.class));
+            } catch (NoSuchPartException e) {
+                // no executionMetadata available
+            }
+        }
         ResponseBuilder rb = Response.ok(graph);
         List<String> accepted = headers.getRequestHeader(HttpHeaders.ACCEPT);
         MediaType mediaType = MediaTypeUtil.getAcceptableMediaType(headers,null);
@@ -321,11 +344,11 @@ public class EnhancerRootResource extend
     public class ExecutionNode {
         
         private final NonLiteral node;
-        private final Graph ep;
+        private final TripleCollection ep;
         private final boolean optional;
         private final String engineName;
         
-        public ExecutionNode(Graph executionPlan, NonLiteral node) {
+        public ExecutionNode(TripleCollection executionPlan, NonLiteral node) {
             this.node = node;
             this.ep = executionPlan;
             this.optional = ExecutionPlanHelper.isOptional(ep, node);
@@ -354,4 +377,5 @@ public class EnhancerRootResource extend
             return o instanceof ExecutionNode && ((ExecutionNode)o).node.equals(node);
         }
     }
+
 }

Modified: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/ajax/contentitem.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/ajax/contentitem.ftl?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/ajax/contentitem.ftl (original)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/ajax/contentitem.ftl Wed Feb  1 11:59:37 2012
@@ -15,8 +15,11 @@
   limitations under the License.
 -->
 <#import "/imports/contentitem.ftl" as contentitem>
+<#import "/imports/executionmetadata.ftl" as executionmetadata>
 <#escape x as x?html>
 
+<@executionmetadata.view />
+
 <@contentitem.view />
 
 <h3>Raw RDF output</h3>

Added: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/imports/executionmetadata.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/imports/executionmetadata.ftl?rev=1239097&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/imports/executionmetadata.ftl (added)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/imports/executionmetadata.ftl Wed Feb  1 11:59:37 2012
@@ -0,0 +1,78 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<#macro view>
+
+<h3>Enhancement Process Metadata</h3>
+<div id="executionmetadata" class="enginelisting">
+  <script>
+    $("#executionmetadata p").click(function () {
+      $(this).parents("div").toggleClass("collapsed");
+    });    
+  </script>
+  <#if !it.chainExecution??>
+    <p> No metadata available <small>
+    (This indicates that the used EnhancementJobManager
+    does not support this feature)</small><p>
+  <#else>
+    <#if it.chainExecution.failed>
+      <div>
+    <#else>
+    <div class="collapsed">
+    </#if>
+    <p class="collapseheader"> Execution of Chain 
+      <#if it.chainExecution.completed>
+        <span style="color:#006600">
+      <#elseif it.chainExecution.failed>
+        <span style="color:#660000">
+      <#else>
+         <span>
+      </#if>
+      <strong>${it.chainExecution.chainName}</strong> 
+      ${it.chainExecution.statusText} </span>
+      in <strong>${it.chainExecution.durationText}</strong>.
+    </p>
+    <div class="collapsable">
+    <ul>
+      <#list it.engineExecutions as node>
+        <li><#if node.offsetText??>${node.offsetText}<#else>${node.startTime}</#if>:
+        <#if node.completed>
+          <span style="color:#006600">
+        <#elseif node.failed && node.executionNode.optional>
+          <span style="color:#666666">
+        <#elseif node.failed && !node.executionNode.optional>
+          <span style="color:#660000">
+        <#else>
+           <span>
+        </#if>
+          <b>${node.statusText}</b></span> 
+          in ${node.durationText} :
+          <b>${node.executionNode.engineName}</b>
+          <small>(
+          <#if node.executionNode.optional> optional <#else> required </#if>, 
+          start: ${node.startTime}, completion: ${node.completionTime})
+          </small>
+          </span>
+          </li>
+      </#list>
+    </ul>
+    </div>
+  </div>
+  </#if>
+</div>
+
+
+</#macro>

Added: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/ChainsRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/ChainsRootResource/index.ftl?rev=1239097&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/ChainsRootResource/index.ftl (added)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/ChainsRootResource/index.ftl Wed Feb  1 11:59:37 2012
@@ -0,0 +1,62 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<#import "/imports/common.ftl" as common>
+<#escape x as x?html>
+<@common.page title="Enhancement Chains" hasrestapi=true>
+
+
+<div class="panel" id="webview">
+<p> Enhancement Chains define a set of Enhancement Engines as well as the 
+execution oder of those used to enhance content parsed to the Stanbol Enhancer.<p>
+Currently the following Chains are available:
+<ul>
+  <#list it.chains as chain>
+    <#assign name = chain.name >
+    <li> <a href="${it.publicBaseUri}enhancer/chain/${name}">${name}</a>
+    (<#if it.isDefault(name)><b>default</b>,</#if>
+    id: ${it.getServiceId(name)}, ranking: ${it.getServiceRanking(name)},
+    impl: ${chain.class.simpleName}
+    )<#if it.getServicePid(name)??>: 
+    <a href="/system/console/configMgr/${it.getServicePid(name)}">configure</a></#if>
+  </#list>
+</ul>
+<p>Enhancement Request for the <a href="${it.publicBaseUri}enhancer">
+/enhancer</a> and <a href="${it.publicBaseUri}engines">
+/engines</a> endpoints are processed by using the default chain - the engine
+in the above list marked as <b>default</b>. </p><p>
+The default Chain is defined as (1) the Chain with the name "default" 
+and the highest <code>service.ranking</code> or (2) if no Chain has the name 
+"default" is active than the Chain with the highest <code>service.ranking</code> 
+(regardless of the name).<p>
+
+<p class="note">
+You can configure Chains by using the the <a href="/system/console/configMgr">
+Configuration Tab</a> of the OSGi console.</p>
+
+</div>
+
+<div class="panel" id="restapi" style="display: none;">
+<h3>Enhancement Chains RESTful API</h3>
+
+<p>This stateless interface allows the caller to query all available
+Enhancement Chains</p>
+
+</div>
+
+
+</...@common.page>
+</#escape>

Added: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEngineResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEngineResource/index.ftl?rev=1239097&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEngineResource/index.ftl (added)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEngineResource/index.ftl Wed Feb  1 11:59:37 2012
@@ -0,0 +1,58 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<#import "/imports/common.ftl" as common>
+<#escape x as x?html>
+<@common.page title="Enhancement Engine ${it.name}" hasrestapi=true>
+
+
+<div class="panel" id="webview">
+<p> Enhancement Engine Details: <ul>
+<li> name: ${it.name}
+<li> class: ${it.engine.class}
+<li> ordering: ${it.ordering}
+<li> service.id : ${it.id}
+<li> service.ranking: ${it.ranking}
+</ul>
+<p class="note"> You can <a href="/system/console/configMgr/${it.pid}">
+configure this engine</a> by using the the Configuration Tab of the OSGi console.</p>
+
+<#--
+<p> This is the list of all active Enhancement Engines active for 
+the name ${it.name}:
+<ul>
+  <#list it.engines as engine>
+    <li> <a href="${it.publicBaseUri}enhancer/engine/${engine.name}">${engine.name}</a>
+      (impl: ${engine.class.simpleName})
+  </#list>
+</ul>
+<p>
+
+-->
+</div>
+
+<div class="panel" id="restapi" style="display: none;">
+<h3>Enhancement Engines RESTful API</h3>
+
+<p>This stateless interface allows the caller to query all available
+Enhancement Engines</p>
+
+
+</div>
+
+
+</...@common.page>
+</#escape>

Added: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEnginesRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEnginesRootResource/index.ftl?rev=1239097&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEnginesRootResource/index.ftl (added)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEnginesRootResource/index.ftl Wed Feb  1 11:59:37 2012
@@ -0,0 +1,54 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<#import "/imports/common.ftl" as common>
+<#escape x as x?html>
+<@common.page title="Enhancement Engines" hasrestapi=true>
+
+
+<div class="panel" id="webview">
+
+<p> This is the list of all active Enhancement Engines.
+<ul>
+  <#list it.engines as engine>
+    <#assign name = engine.name >
+    <li> <a href="${it.publicBaseUri}enhancer/engine/${name}">${name}</a>
+    (id: ${it.getServiceId(name)}, ranking: ${it.getServiceRanking(name)}, 
+    impl: ${engine.class.simpleName}
+    )<#if it.getServicePid(name)??>: 
+    <a href="/system/console/configMgr/${it.getServicePid(name)}">configure</a></#if>
+  </#list>
+</ul>
+<p>
+EnhancementEngines are used to define <a href="${it.publicBaseUri}enhancer/chain">
+Enhancement Chains</a> that can than be used to enhance content parsed to the
+Stanbol Enhancer.</p>
+<p class="note"> You can configure Chains by using the the
+<a href="/system/console/configMgr">Configuration Tab</a> of the OSGi console.</p>
+</div>
+
+<div class="panel" id="restapi" style="display: none;">
+<h3>Enhancement Engines RESTful API</h3>
+
+<p>This stateless interface allows the caller to query all available
+Enhancement Engines</p>
+
+
+</div>
+
+
+</...@common.page>
+</#escape>

Modified: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource/index.ftl?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource/index.ftl (original)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource/index.ftl Wed Feb  1 11:59:37 2012
@@ -16,7 +16,7 @@
 -->
 <#import "/imports/common.ftl" as common>
 <#escape x as x?html>
-<@common.page title="Enhancement Engines" hasrestapi=true>
+<@common.page title="Apache Stanbol Enhancer" hasrestapi=true>
 
 
 <div class="panel" id="webview">
@@ -36,16 +36,20 @@
   <#else>
     <div>
   </#if>
-  <p class="collapseheader">There are currently 
-    <#if it.activeNodes?size < it.executionNodes?size>
-      <strong>${it.activeNodes?size}/</strong><#else>all </#if><strong>${it.executionNodes?size}</strong>
-    engines available for enhancement chain 
+  <p class="collapseheader">Enhancement Chain: 
     <#if it.chainAvailable>
       <span style="color:#006600">
     <#else>
       <span style="color:#660000">
     </#if>
-    <strong>${it.chain.name}</strong></span></p>
+    <strong>${it.chain.name}</strong></span> 
+    <#if it.activeNodes?size &lt; it.executionNodes?size>
+      <strong>${it.activeNodes?size}/</strong><#else> all </#if><strong>${it.executionNodes?size}</strong>
+    engines available 
+      <span style="float: right; margin-right: 25px;">
+        &lt; List of <a href="#">Enhancement Chains</a> &gt;
+      </span>
+    </p>
     <div class="collapsable">
     <ul>
       <#list executionNodes as node>
@@ -78,10 +82,17 @@
 <script>
 $(".enginelisting p").click(function () {
   $(this).parents("div").toggleClass("collapsed");
-});    
+})
+.find("a").click(function(e){
+    e.stopPropagation();
+    //link to all active Enhancement Chains
+    window.location = "${it.publicBaseUri}enhancer/chain";
+    return false;
+});     
 </script>
-
-  <p>Paste some text below and submit the form to let the active engines enhance it:</p>
+</#if>
+<#if it.chainAvailable>
+  <p>Paste some text below and submit the form to let the Enhancement Chain ${it.chain.name} enhance it:</p>
   <form id="enginesInput" method="POST" accept-charset="utf-8">
     <p><textarea rows="15" name="content"></textarea></p>
     <p class="submitButtons">Output format:
@@ -150,7 +161,7 @@ in the format specified in the <code>Acc
    
 <pre>
 curl -X POST -H "Accept: text/turtle" -H "Content-type: text/plain" \
-     --data "John Smith was born in London." ${it.publicBaseUri}engines
+     --data "John Smith was born in London." ${it.serviceUrl}
 </pre> 
 
 <p>The list of mimetypes accepted as inputs depends on the deployed engines. By default only
@@ -165,16 +176,28 @@ curl -X POST -H "Accept: text/turtle" -H
 <li><code>text/rdf+nt</code> (N-TRIPLES)</li>
 </ul> 
 
-<p>By default the URI of the content item being enhanced is a local, non
-de-referencable URI automatically built out of a hash digest of the binary
-content. Sometimes it might be helpful to provide the URI of the content-item
-to be used in the enhancements RDF graph. This can be achieved by passing a
-<code>uri</code> request parameter as follows:</p>
+<p> Additional supported QueryParameters:<ul>
+<li><code>uri={content-item-uri}</code>: By default the URI of the content 
+    item being enhanced is a local, non de-referencable URI automatically built 
+    out of a hash digest of the binary content. Sometimes it might be helpful 
+    to provide the URI of the content-item to be used in the enhancements RDF 
+    graph.
+<code>uri</code> request parameter
+<li><code>executionmetadata=true/false</code>: 
+    Allows the include of execution metadata in the response. Such data include
+    the ExecutionPlan as provided by the enhancement chain as well as
+    information about the actual execution of that plan. The default value
+    is <code>false</code>.</li>
+</ul>
+
+<p>The following example shows how to send an enhancement request with a
+custom content item URI that will include the execution metadata in the
+response.</p>
 
 <pre>
 curl -X POST -H "Accept: text/turtle" -H "Content-type: text/plain" \
      --data "John Smith was born in London." \
-     "${it.publicBaseUri}engines?uri=urn:fise-example-content-item"
+     "${it.serviceUrl}?uri=urn:fise-example-content-item&executionmetadata=true"
 </pre> 
 
 </div>

Propchange: incubator/stanbol/trunk/enhancer/jobmanager/event/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Feb  1 11:59:37 2012
@@ -3,3 +3,5 @@
 .classpath
 
 target
+
+.settings

Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/pom.xml?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/pom.xml (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/pom.xml Wed Feb  1 11:59:37 2012
@@ -84,10 +84,10 @@
 			<groupId>org.apache.clerezza</groupId>
 			<artifactId>rdf.core</artifactId>
 		</dependency>
-<!-- 		<dependency>
-			<groupId>commons-io</groupId>
-			<artifactId>commons-io</artifactId>
-		</dependency>  -->
+        <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+        </dependency>
 		<!-- for tests -->
 		<dependency>
 			<groupId>junit</groupId>

Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/Constants.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/Constants.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/Constants.java (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/Constants.java Wed Feb  1 11:59:37 2012
@@ -2,6 +2,7 @@ package org.apache.stanbol.enhancer.jobm
 
 import org.apache.clerezza.rdf.core.NonLiteral;
 import org.apache.stanbol.enhancer.jobmanager.event.impl.EnhancementJob;
+import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventConstants;
 
@@ -24,8 +25,9 @@ public interface Constants {
      */
     String PROPERTY_JOB_MANAGER = "stanbol.enhancer.jobmanager.event.job";
     /**
-     * Property used to provide the {@link NonLiteral} node to execute
+     * Property used to provide the {@link NonLiteral} describing the
+     * {@link ExecutionMetadata#EXECUTION} instance
      */
-    String PROPERTY_NODE = "stanbol.enhancer.jobmanager.event.node";
+    String PROPERTY_EXECUTION = "stanbol.enhancer.jobmanager.event.execution";
 
 }

Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJob.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJob.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJob.java (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJob.java Wed Feb  1 11:59:37 2012
@@ -1,25 +1,60 @@
 package org.apache.stanbol.enhancer.jobmanager.event.impl;
 
+import static org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper.getReference;
+import static org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper.getString;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.createChainExecutionNode;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.getChainExecution;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.getExecutionPlanNode;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.initExecutionMetadata;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.initExecutionMetadataContentPart;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.isExecutionFailed;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.setExecutionCompleted;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.setExecutionFaild;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.setExecutionInProgress;
 import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.getDependend;
 import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.getEngine;
 import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.isOptional;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.CHAIN_EXECUTION;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.ENHANCED_BY;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.ENHANCES;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS_IN_PROGRESS;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan.CHAIN;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 
 import org.apache.clerezza.rdf.core.Graph;
+import org.apache.clerezza.rdf.core.MGraph;
 import org.apache.clerezza.rdf.core.NonLiteral;
+import org.apache.clerezza.rdf.core.Triple;
+import org.apache.clerezza.rdf.core.TripleCollection;
+import org.apache.clerezza.rdf.core.UriRef;
+import org.apache.clerezza.rdf.core.access.LockableMGraph;
+import org.apache.clerezza.rdf.core.access.LockableMGraphWrapper;
+import org.apache.clerezza.rdf.core.impl.PlainLiteralImpl;
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph;
+import org.apache.commons.collections.BidiMap;
+import org.apache.commons.collections.bidimap.DualHashBidiMap;
 import org.apache.stanbol.enhancer.servicesapi.Chain;
 import org.apache.stanbol.enhancer.servicesapi.ContentItem;
 import org.apache.stanbol.enhancer.servicesapi.EnhancementEngine;
 import org.apache.stanbol.enhancer.servicesapi.EnhancementJobManager;
+import org.apache.stanbol.enhancer.servicesapi.NoSuchPartException;
+import org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper;
+import org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper;
 import org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper;
+import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata;
+import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -48,36 +83,201 @@ public class EnhancementJob {
 
     private final Lock readLock;
     private final Lock writeLock;
+    /**
+     * The read only executionPlan
+     */
     private final Graph executionPlan;
+    /**
+     * The read/write able execution metadata. Also accessible via
+     * {@link ContentItem#getPart(UriRef, Class)} with the URI
+     * {@link ExecutionMetadata#CHAIN_EXECUTION}
+     */
+    private final MGraph executionMetadata;
+    /**
+     * Map with the em:Execution nodes of the em:ChainExecution for this
+     * ContentItem. Values are are ep:ExecutionNodes of the ep:ExecutionPlan
+     */
+    private final BidiMap executionsMap;
+    /**
+     * The em:ChainExecution for this {@link ContentItem}
+     */
+    private final NonLiteral chainExecutionNode;
+    /**
+     * The ep:ExecutionPlan for this {@link ContentItem}
+     */
+    private final NonLiteral executionPlanNode;
+    /**
+     * The name of the {@link Chain} used to enhance this {@link ContentItem}.
+     */
     private final String chain;
+    /**
+     * The ContentItem
+     */
     private final ContentItem contentItem;
 
-    private final Set<NonLiteral> completed;
-    private final Set<NonLiteral> unmodCompleted;
-    private final Set<NonLiteral> running;
-    private final Set<NonLiteral> unmodRunning;
+    /**
+     * The completed ep:ExecutionPlan nodes. <p>
+     * NOTE: This contains ep:ExecutionNodes and NOT em:Exetution instances!
+     */
+    private final Set<NonLiteral> completed = new HashSet<NonLiteral>();
+    /**
+     * Unmodifiable and final set of completed executables. Replaced by a new
+     * instance every time {@link #completed} changes
+     */
+    private Set<NonLiteral> completedExec = Collections.emptySet();
+    /**
+     * The running ep:ExecutionPlan nodes <p>
+     * NOTE: This contains ep:ExecutionNodes and NOT em:Exetution instances!
+     */
+    private final Set<NonLiteral> running = new HashSet<NonLiteral>();
+    /**
+     * Unmodifiable and final set of running executables. Replaced by a new
+     * instance every time {@link #running} changes.
+     */
+    private Set<NonLiteral> runningExec = Collections.emptySet();
 
+    /**
+     * Unmodifiable and final set of executable em:Execution nodes. 
+     * Replaced by a new instance every time {@link #running} or 
+     * {@link #completed} changes.
+     */
     private Set<NonLiteral> executable;
-    private boolean failed = false;
-    private List<String> errormessages = new ArrayList<String>();
+    /**
+     * Used to store any {@link Exception} parsed with the call to
+     * {@link #setFailed(NonLiteral, EnhancementEngine, Exception)} causing the
+     * enhancement process to fail. This Exception is typically re-thrown by the
+     * {@link EnhancementJobManager#enhanceContent(ContentItem, Chain)} method.
+     * @see #getError()
+     */
     private Exception error = null;
-
-    public EnhancementJob(ContentItem contentItem, String chainName, Graph executionPlan) {
+    /**
+     * Constructor used to create and initialise a new enhancement job. This
+     * will create the initial set of ExecutionMetadata and add them as
+     * ContentPart with the URI {@link ExecutionMetadata#CHAIN_EXECUTION} to the
+     * ContentItem.
+     * @param contentItem
+     * @param chainName
+     * @param executionPlan
+     * @param isDefaultChain
+     */
+    public EnhancementJob(ContentItem contentItem, String chainName, Graph executionPlan, boolean isDefaultChain) {
         if (contentItem == null || chainName == null || executionPlan == null) {
             throw new IllegalArgumentException("The parsed contentItem and executionPlan MUST NOT be NULL");
         }
-        this.contentItem = contentItem;
         this.readLock = contentItem.getLock().readLock();
         this.writeLock = contentItem.getLock().writeLock();
+        executionMetadata = initExecutionMetadataContentPart(contentItem);
+        if(executionMetadata.isEmpty()){
+            //if we init from scratch 
+            this.executionsMap = new DualHashBidiMap(initExecutionMetadata(executionMetadata, executionPlan, 
+                contentItem.getUri(), chainName, isDefaultChain));
+            chainExecutionNode = getChainExecution(executionMetadata, contentItem.getUri());
+            executionPlanNode = getExecutionPlanNode(executionMetadata, chainExecutionNode);
+            executionMetadata.addAll(executionPlan);
+        } else {
+            throw new IllegalArgumentException("Unable to create EnhancementJob for "
+                    + "a parsed execution plan if the ContentItem already contains "
+                    + "some Execution Metadata!");
+        }
+        this.contentItem = contentItem;
         this.executionPlan = executionPlan;
         this.chain = chainName;
-        completed = new HashSet<NonLiteral>();
-        unmodCompleted = Collections.unmodifiableSet(completed);
-        running = new HashSet<NonLiteral>();
-        unmodRunning = Collections.unmodifiableSet(running);
         //check the first engines to execute
         checkExecutable();
     }
+    /**
+     * Creates an EnhancemenJob based on already existing execution metadata present
+     * for a ContentItem.
+     * @param contentItem the ContentItem with an already existing content part
+     * containing an {@link MGraph} with all required execution metadata and the 
+     * execution plan.
+     * @throws IllegalArgumentException if the parsed {@link ContentItem} does
+     * not provide the required data to (re)initialise the EnhancementJob.
+     */
+    public EnhancementJob(ContentItem contentItem){
+        if (contentItem == null){
+            throw new IllegalArgumentException("The parsed ContentItem MUST NOT be NULL!");
+        }
+        this.contentItem = contentItem;
+        this.readLock = contentItem.getLock().readLock();
+        this.writeLock = contentItem.getLock().writeLock();
+        try {
+            contentItem.getPart(ExecutionMetadata.CHAIN_EXECUTION, MGraph.class);
+        } catch (NoSuchPartException e) {
+            throw new IllegalArgumentException("Cannot (re)initialise an EnhancementJob" +
+                    "without existing execution metadata content part!",e);
+        }
+        executionMetadata = initExecutionMetadataContentPart(contentItem);
+        this.executionPlan = executionMetadata.getGraph();
+        chainExecutionNode = getChainExecution(executionMetadata, contentItem.getUri());
+        if(chainExecutionNode == null){
+            throw new IllegalArgumentException("Cannot (re)initialise an EnhancementJob" +
+                    "because the ExecutionMetadata do not contain an em:ChainExecution" +
+                    "for the given ContentItem '"+contentItem.getUri()+"'!");
+        }
+        executionPlanNode = getExecutionPlanNode(executionMetadata, chainExecutionNode);
+        if(executionPlanNode == null){
+            throw new IllegalArgumentException("Cannot (re)initialise an EnhancementJob" +
+                    "because the ExecutionMetadata do not contain an ep:ExecutionPlan" +
+                    "for the given ContentItem '"+contentItem.getUri()+"'!");
+        }
+        this.chain = getString(executionPlan, executionPlanNode, CHAIN);
+        if(chain == null || chain.isEmpty()){
+            throw new IllegalArgumentException("Cannot (re)initialise an EnhancementJob " +
+                    "because the ExecutionMetadata do not define a valid chain name for " +
+                    "the ep:ExecutionPlan node '" + executionPlanNode+"' as used to " +
+                    "enhance  ContentItem '"+contentItem.getUri()+"'!");
+        }
+        //the executionPlan is part of the execution metadata
+        Map<NonLiteral,NonLiteral> executionsMap = initExecutionMetadata(executionMetadata, 
+            executionPlan, contentItem.getUri(), null, null);
+        for(Entry<NonLiteral,NonLiteral> executionEntry : executionsMap.entrySet()){
+            UriRef status = getReference(executionMetadata, executionEntry.getKey(), STATUS);
+            if(status == null){
+                throw new IllegalArgumentException("The ex:Execution '"
+                        + executionEntry.getKey()+"' of the ex:ChainExecution for ContentItme '"
+                        + contentItem.getUri()+"' is missing a required value for the property '"
+                        + STATUS+"'!");
+            }
+            if(status.equals(STATUS_IN_PROGRESS)){
+                //re-schedule unfinished enhancement jobs
+                ExecutionMetadataHelper.setExecutionScheduled(executionMetadata, executionEntry.getKey());
+            } else if(status.equals(ExecutionMetadata.STATUS_COMPLETED) ||
+                    status.equals(ExecutionMetadata.STATUS_FAILED)){
+               completed.add(executionEntry.getValue());
+            }
+        }
+        this.executionsMap = new DualHashBidiMap(executionsMap);
+        //check the first engines to execute after continuation
+        checkExecutable();
+    }
+
+    /**
+     * Getter for the ep:ExecutionNode linked to a em:Execution
+     * @return the ep:ExecutionNode instance
+     * @throws IllegalArgumentException if the parsed em:Execution is not
+     * part of the execution metadata of this enhancement job
+     */
+    public NonLiteral getExecutionNode(NonLiteral execution){
+        NonLiteral node = (NonLiteral)executionsMap.get(execution);
+        if(node == null){
+            throw new IllegalArgumentException("Unknown sp:ExecutionNode instance "+node);
+        }
+        return node;
+    }
+    /**
+     * Getter for the em:Execution linked to a ep:ExecutionNode
+     * @return the em:Execution instance 
+     * @throws IllegalArgumentException if the parsed ep:ExecutionNode is not
+     * part of the execution plan of this enhancement job
+     */
+    public NonLiteral getExecution(NonLiteral executionNode){
+        NonLiteral execution = (NonLiteral)executionsMap.getKey(executionNode);
+        if(execution == null){
+            throw new IllegalArgumentException("Unknown em:Execution instance "+executionNode);
+        }
+        return execution;
+    }
 
     /**
      * The used execution plan for processing the {@link ContentItem}
@@ -132,7 +332,7 @@ public class EnhancementJob {
         readLock.lock();
         try {
             log.debug(">> r: {}","getRunning");
-            return unmodRunning;
+            return runningExec;
         } finally {
             log.debug("<< r: {}","getRunning");
             readLock.unlock();
@@ -149,7 +349,7 @@ public class EnhancementJob {
         readLock.lock();
         try {
             log.debug(">> r: {}","getCompleted");
-            return unmodCompleted;
+            return completedExec;
         } finally {
             log.debug("<< r: {}","getCompleted");
             readLock.unlock();
@@ -161,151 +361,207 @@ public class EnhancementJob {
      * confirms to the ExectionPlan (e.g. if all nodes the parsed node depends on are also marked as
      * completed).
      * 
-     * @param executionNode
-     *            the exectionNode to be marked as running
+     * @param execution
+     *            the exection to be marked as running
      * @throws IllegalArgumentException
      *             if <code>null</code> is parsed as execution node
      * @throws IllegalStateException
      *             if the parsed execution node can not be marked as completed because some of its
      *             depended nodes are not yet marked as completed.
      */
-    public void setCompleted(NonLiteral executionNode) {
-        if (executionNode != null) {
-            String engine = getEngine(executionPlan, executionNode);
-            boolean optional = isOptional(executionPlan, executionNode);
-            Set<NonLiteral> dependsOn = getDependend(executionPlan, executionNode);
-            log.debug("++ w: {}: {}","setCompleted",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
-            writeLock.lock();
-            try {
-                log.debug(">> w: {}: {}","setCompleted",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
-                if (completed.contains(executionNode)) {
-                    log.warn("Execution of Engine '{}' for ContentItem {} already "
-                             + "marked as completed(chain: {}, node: {}, optional {})."
-                             + " -> call ignored", 
-                             new Object[] {engine, contentItem.getUri().getUnicodeString(),
-                                           chain, executionNode, optional});
-                    return;
-                }
-                if (!completed.containsAll(dependsOn)) {
-                    // TODO maybe define an own Exception for such cases
-                    throw new IllegalStateException(
-                            "Unable to set state of ExectionNode '"
-                                    + executionNode+ "' (chain '"+ chain
-                                    + "' | contentItem '"+ contentItem.getUri()
-                                    + "') to completed, because some of its depended "
-                                    + "nodes are not marked completed yet. This indicates an Bug in the "
-                                    + "implementation of the JobManager used to execute the ExecutionPlan. "
-                                    + "(this.dependsOn=" + dependsOn + "| chain.completed " + completed
-                                    + " | chain.running " + running + ")!");
-                }
-                if (running.remove(executionNode)) {
-                    log.info(
-                        "Execution of '{}' for ContentItem {} completed "
-                        + "(chain: {}, node: {}, optional {})",
-                        new Object[] {engine, contentItem.getUri().getUnicodeString(), 
-                                      chain, executionNode, optional});
-                }
-                completed.add(executionNode);
-                // update the executables ... this will also recognise if finished 
-                checkExecutable();
-            } finally {
-                log.debug("<< w: {}: {}","setCompleted",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
-                writeLock.unlock();
-            }
+    public void setCompleted(NonLiteral execution) {
+        if(execution == null) {
+            throw new IllegalArgumentException("The parsed em:Execution instance MUST NOT be NULL!");
+        }
+        writeLock.lock();
+        log.debug("++ w: {}: {}","setCompleted",getEngine(executionPlan, execution));
+        try {
+            log.debug(">> w: {}: {}","setCompleted",getEngine(executionPlan, execution));
+            setNodeCompleted(getExecutionNode(execution));
+            setExecutionCompleted(executionMetadata, execution, null);
+        } finally {
+            log.debug("<< w: {}: {}","setCompleted",getEngine(executionPlan, execution));
+            writeLock.unlock();
         }
     }
+    /**
+     * Internally used to update the state kept in {@link #completed} and
+     * {@link #running} and {@link #executable} after an execution was set to
+     * {@link #setCompleted(NonLiteral) completed} or 
+     * {@link #setFailed(NonLiteral, EnhancementEngine, Exception) failed}.<p>
+     * This method expects to be called within an active {@link #writeLock}.
+     * @param executionNode the ep:ExecutionNode linked to the em:Execution that
+     * finished. 
+     */
+    private void setNodeCompleted(NonLiteral executionNode) {
+        String engine = getEngine(executionPlan, executionNode);
+        boolean optional = isOptional(executionPlan, executionNode);
+        Set<NonLiteral> dependsOn = getDependend(executionPlan, executionNode);
+        if (completed.contains(executionNode)) {
+            log.warn("Execution of Engine '{}' for ContentItem {} already "
+                     + "marked as completed(chain: {}, node: {}, optional {})."
+                     + " -> call ignored", 
+                     new Object[] {engine, contentItem.getUri().getUnicodeString(),
+                                   chain, executionNode, optional});
+            return;
+        }
+        if (!completed.containsAll(dependsOn)) {
+            // TODO maybe define an own Exception for such cases
+            throw new IllegalStateException("Unable to set state of ExectionNode '"
+                    + executionNode+ "' (chain '"+ chain
+                    + "' | contentItem '"+ contentItem.getUri()
+                    + "') to completed, because some of its depended "
+                    + "nodes are not marked completed yet. This indicates an Bug in the "
+                    + "implementation of the JobManager used to execute the ExecutionPlan. "
+                    + "(this.dependsOn=" + dependsOn + "| chain.completed " + completed
+                    + " | chain.running " + running + ")!");
+        }
+        if (running.remove(executionNode)) {
+            log.info(
+                "Execution of '{}' for ContentItem {} completed "
+                + "(chain: {}, node: {}, optional {})",
+                new Object[] {engine, contentItem.getUri().getUnicodeString(), 
+                              chain, executionNode, optional});
+        }
+        completed.add(executionNode);
+        //update the set with the completed and running executables
+        updateCompletedExec();
+        updateRunningExec();
+        // update the executables ... this will also recognise if finished 
+        checkExecutable();
+    }
 
     /**
-     * Sets the state of the parsed executionNode to running. This also validates if the new state
+     * Sets the state of the parsed execution to running. This also validates if the new state
      * confirms to the ExectionPlan (e.g. if all nodes the parsed node depends on are already marked as
      * completed).
      * 
-     * @param executionNode
-     *            the exectionNode to be marked as running
+     * @param execution
+     *            the execution to be marked as running
      * @throws IllegalArgumentException
      *             if <code>null</code> is parsed as execution node
      * @throws IllegalStateException
      *             if the parsed execution node can not be marked as running because some of its depended
      *             nodes are not yet marked as completed.
      */
-    public void setRunning(NonLiteral executionNode) {
-        if (executionNode != null) {
-            String engine = getEngine(executionPlan, executionNode);
-            boolean optional = isOptional(executionPlan, executionNode);
-            Set<NonLiteral> dependsOn = getDependend(executionPlan, executionNode);
-            log.debug("++ w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
-            writeLock.lock();
-            try {
-                log.debug(">> w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
-                if (completed.contains(executionNode)) {
-                    throw new IllegalStateException(
-                            "Unable to set state of ExectionNode '"+ executionNode
-                            + "'(chain '"+chain+ "' | contentItem '"
-                            + contentItem.getUri()+"') to running, because"
-                            + "it is already marked as completed. This indicates "
-                            + "an Bug in the implementation of the JobManager "
-                            + "used to execute the ExecutionPlan (chain state: "
-                            +"completed " + completed + " | running " + running
-                            + ")!");
-                }
-                if (!completed.containsAll(dependsOn)) {
-                    // TODO maybe define an own Exception for such cases
-                    throw new IllegalStateException(
-                            "Unable to set state of ExectionNode '"+ executionNode
-                            + "' (chain '"+chain+ "' | contentItem '"
-                            + contentItem.getUri()+"') to running, because "
-                            + "some of its depended nodes are not marked "
-                            + "completed yet. This indicates an Bug in the "
-                            + "implementation of the JobManager used to execute "
-                            + "the ExecutionPlan (this.dependsOn=" + dependsOn 
-                            + "| chain.completed " + completed
-                            + " | chain.running " + running + ")!");
-                }
-                if (!running.add(executionNode)) {
-                    log.warn("Execution of Engine '{}' for ContentItem {} already "
-                             + "marked as running(chain: {}, node: {}, optional {})."
-                             + " -> call ignored", 
-                             new Object[] {engine, contentItem.getUri().getUnicodeString(),
-                                           chain, executionNode, optional});
-                    return;
-                } else {
-                    log.info("Started Execution of '{}' for ContentItem {} "
-                             + "(chain: {}, node: {}, optional {})",
-                        new Object[] {engine, contentItem.getUri().getUnicodeString(), chain,
-                                      executionNode, optional});
-                    // update the executables ... this will also recognise if finished 
-                    checkExecutable();
-                }
-            } finally {
-                log.debug("<< w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
-                writeLock.unlock();
+    public void setRunning(NonLiteral execution) {
+        if(execution == null) {
+            throw new IllegalArgumentException("The parsed em:Execution instance MUST NOT be NULL!");
+        }
+        NonLiteral executionNode = getExecutionNode(execution);
+        String engine = getEngine(executionPlan, executionNode);
+        boolean optional = isOptional(executionPlan, executionNode);
+        Set<NonLiteral> dependsOn = getDependend(executionPlan, executionNode);
+        log.debug("++ w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
+        writeLock.lock();
+        try {
+            log.debug(">> w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
+            if (completed.contains(executionNode)) {
+                throw new IllegalStateException(
+                        "Unable to set state of ExectionNode '"+ executionNode
+                        + "'(chain '"+chain+ "' | contentItem '"
+                        + contentItem.getUri()+"') to running, because"
+                        + "it is already marked as completed. This indicates "
+                        + "an Bug in the implementation of the JobManager "
+                        + "used to execute the ExecutionPlan (chain state: "
+                        +"completed " + completed + " | running " + running
+                        + ")!");
             }
-        } else {
-            throw new IllegalArgumentException("The parsed ExecutionNode MUST NOT be NULL!");
+            if (!completed.containsAll(dependsOn)) {
+                // TODO maybe define an own Exception for such cases
+                throw new IllegalStateException(
+                        "Unable to set state of ExectionNode '"+ executionNode
+                        + "' (chain '"+chain+ "' | contentItem '"
+                        + contentItem.getUri()+"') to running, because "
+                        + "some of its depended nodes are not marked "
+                        + "completed yet. This indicates an Bug in the "
+                        + "implementation of the JobManager used to execute "
+                        + "the ExecutionPlan (this.dependsOn=" + dependsOn 
+                        + "| chain.completed " + completed
+                        + " | chain.running " + running + ")!");
+            }
+            if (!running.add(executionNode)) {
+                log.warn("Execution of Engine '{}' for ContentItem {} already "
+                         + "marked as running(chain: {}, node: {}, optional {})."
+                         + " -> call ignored", 
+                         new Object[] {engine, contentItem.getUri().getUnicodeString(),
+                                       chain, executionNode, optional});
+                return;
+            } else { //added an engine to running
+                log.info("Started Execution of '{}' for ContentItem {} "
+                         + "(chain: {}, node: {}, optional {})",
+                    new Object[] {engine, contentItem.getUri().getUnicodeString(), chain,
+                                  executionNode, optional});
+                //set the status of the execution to be in progress
+                ExecutionMetadataHelper.setExecutionInProgress(executionMetadata, execution);
+                // update the executables ... this will also recognise if finished
+                updateRunningExec();
+                //update executables
+                checkExecutable();
+            }
+        } finally {
+            log.debug("<< w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
+            writeLock.unlock();
+        }
+    }
+    /**
+     * updates the {@link #runningExec} based on {@link #running}
+     */
+    private void updateRunningExec() {
+        Set<NonLiteral> runningExec = new HashSet<NonLiteral>(running.size());
+        for(NonLiteral node : running){
+            runningExec.add(getExecution(node));
+        }
+        this.runningExec = Collections.unmodifiableSet(runningExec);
+    }
+    /**
+     * updates the {@link #runningExec} based on {@link #running}
+     */
+    private void updateCompletedExec() {
+        Set<NonLiteral> completedExec = new HashSet<NonLiteral>(completed.size());
+        for(NonLiteral node : completed){
+            completedExec.add(getExecution(node));
         }
+        this.completedExec = Collections.unmodifiableSet(completedExec);
     }
     /**
      * updated the {@link #executable} and also checks for {@link #finished}<p>
      * Assumed to be called within a write lock!
      */
     private void checkExecutable(){
-        Set<NonLiteral> executeable = 
+        Set<NonLiteral> executeableNodes = 
                 ExecutionPlanHelper.getExecutable(executionPlan, completed);
         //a Chain finishes if no engine is running and no more nodes are executable
-        if(!failed) { 
-            executeable.removeAll(running);
-            if(log.isInfoEnabled()){
-                Collection<String> engines = new ArrayList<String>(executeable.size());
-                for(NonLiteral node : executeable){
+        if(!ExecutionMetadata.STATUS_FAILED.equals(
+                getReference(executionMetadata, chainExecutionNode, STATUS))) { 
+            executeableNodes.removeAll(running);
+            if(log.isDebugEnabled()){
+                Collection<String> engines = new ArrayList<String>(executeableNodes.size());
+                for(NonLiteral node : executeableNodes){
                     engines.add(getEngine(executionPlan, node));
                 }
-                log.info("MARK {} as executeable",engines);
+                log.debug("MARK {} as executeable",engines);
+            }
+            //we need to get the em:Executables for the ep:ExecutionNodes ...
+            if(executeableNodes.isEmpty()){
+                this.executable = Collections.emptySet();
+            } else if( executeableNodes.size() == 1){
+                this.executable = Collections.singleton(getExecution(executeableNodes.iterator().next()));
+            } else {
+                Set<NonLiteral> executable = new HashSet<NonLiteral>(executeableNodes.size());
+                for(NonLiteral exeutableNode : executeableNodes){
+                    executable.add(getExecution(exeutableNode));
+                }
+                this.executable = Collections.unmodifiableSet(executable);
             }
-            this.executable = Collections.unmodifiableSet(executeable);
         } else {
             //do not mark engines as executeable if chain already failed
             this.executable = Collections.emptySet();
         }
+        if(isFinished() && !isFailed()){
+            //mark the execution process as completed
+            setExecutionCompleted(executionMetadata, chainExecutionNode, null);
+        }
     }
     /**
      * Getter for the executable nodes.
@@ -332,34 +588,28 @@ public class EnhancementJob {
         readLock.lock();
         try {
             log.debug(">> r: {}","isFinished");
-            return this.executable.isEmpty() && running.isEmpty();
+            return executable.isEmpty() && running.isEmpty();
         } finally {
             log.debug("<< r: {}","isFinished");
             readLock.unlock();
         }
     }
 
-    public void setFailed(NonLiteral node, EnhancementEngine engine, Exception exception) {
-        final boolean optional = isOptional(executionPlan, node);
-        final String engineName = getEngine(executionPlan, node);
-        log.debug("++ w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, node));
+    public void setFailed(NonLiteral execution, EnhancementEngine engine, Exception exception) {
+        if(execution == null) {
+            throw new IllegalArgumentException("The parsed em:Execution instance MUST NOT be NULL!");
+        }
+        NonLiteral executionNode = getExecutionNode(execution);
+        final boolean optional = isOptional(executionPlan, executionNode);
+        final String engineName = getEngine(executionPlan, executionNode);
+        log.debug("++ w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
         writeLock.lock();
         try {
-            log.debug(">> w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, node));
-            if(!optional && !failed){ //the first errors for this chain
-                failed = true;
-                error = exception;
-            }
+            log.debug(">> w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
             StringBuilder message = new StringBuilder();
-            if(optional){
-                message.append(String.format("Optional Engine '%s' of enhancement " +
-                		"Chain '%s' skiped for ContentItem %s because the Engine",
-                		engineName,chain,contentItem.getUri()));
-            } else {
-                message.append(String.format("Failed to enhance ContentItem '%s' by using " +
-                		"enhancement chain '%s' because the required Enhancement Engine %s ",
-                		contentItem.getUri(),chain, engineName));
-            }
+            message.append(String.format("Unable to process ContentItem '%s' with " +
+            		"Enhancement Engine %s because the engine ", 
+            		contentItem.getUri(), engineName));
             if(engine == null){
                 message.append("is currently not active");
             } else {
@@ -367,17 +617,24 @@ public class EnhancementJob {
                 		"(Engine class: %s)",engine.getClass().getName()));
             }
             if(exception != null){
-                message.append("(reason:").append(exception.getMessage()).append(')');
+                message.append("(Reason: ").append(exception.getMessage()).append(')');
             }
             message.append('!');
-            if(optional){
-                log.info(message.toString(),exception);
-            } else {
-                errormessages.add(message.toString());
+            setNodeCompleted(executionNode); //update the internal state
+            //set this execution to failed
+            setExecutionFaild(executionMetadata, execution, message.toString());
+            //if not optional and the chain is not yet failed
+            if(!optional && !isExecutionFailed(executionMetadata, chainExecutionNode)){
+                //set also the whole chain to faild!
+                String chainMessage = String.format(
+                    "Enhancement Chain failed because of required Engine '%s' failed" +
+                    "with Message: %s", engineName, message);
+                setExecutionFaild(executionMetadata, execution, chainMessage);
+                error = exception; //this member stores the exception to allow
+                //re-throwing by the EnhancementJobManager.
             }
-            setCompleted(node); //we are done with that node!
         } finally {
-            log.debug("<< w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, node));
+            log.debug("<< w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
             writeLock.unlock();
         }
 
@@ -392,7 +649,7 @@ public class EnhancementJob {
         readLock.lock();
         try {
             log.debug(">> r: {}","isFailed");
-            return failed;
+            return isExecutionFailed(executionMetadata, chainExecutionNode);
         } finally {
             log.debug("<< r: {}","isFailed");
             readLock.unlock();
@@ -412,14 +669,7 @@ public class EnhancementJob {
     public String toString() {
         return "EnhancementJob for ContentItem "+contentItem.getUri();
     }
-    /**
-     * If {@link #isFailed()} this can be used to retrieve the message of the
-     * occurred error.
-     * @return the message of the error that caused the enhancement job to fail.
-     */
-    public String getErrorMessage(){
-        return errormessages == null || errormessages.isEmpty() ? null : errormessages.get(0);
-    }
+
     /**
      * if {@link #isFailed()} this may contain the {@link Exception} that caused
      * the enhancement job to fail. 
@@ -428,4 +678,34 @@ public class EnhancementJob {
     public Exception getError(){
         return error;
     }
+    public String getErrorMessage() {
+        readLock.lock();
+        try {
+            return getString(executionMetadata, executionPlanNode, ExecutionMetadata.STATUS_MESSAGE);
+        } finally {
+            readLock.unlock();
+        }
+    }
+    /**
+     * Getter for the ExecutionMetadata.
+     * @return the execution metadata.
+     */
+    public MGraph getExecutionMetadata() {
+        return executionMetadata;
+    }
+    /**
+     * Marks the execution of the enhancement process as started. In other
+     * words this sets the status of the 'em:ChainExecution' instance that
+     * 'em:enhances' the {@link ContentItem} to 
+     * {@link ExecutionMetadata#STATUS_IN_PROGRESS}
+     */
+    public void startProcessing() {
+        writeLock.lock();
+        try {
+            setExecutionInProgress(executionMetadata, chainExecutionNode);
+        } finally {
+            writeLock.unlock();
+        }
+        
+    }
 }

Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJobHandler.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJobHandler.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJobHandler.java (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJobHandler.java Wed Feb  1 11:59:37 2012
@@ -1,7 +1,7 @@
 package org.apache.stanbol.enhancer.jobmanager.event.impl;
 
 import static org.apache.stanbol.enhancer.jobmanager.event.Constants.PROPERTY_JOB_MANAGER;
-import static org.apache.stanbol.enhancer.jobmanager.event.Constants.PROPERTY_NODE;
+import static org.apache.stanbol.enhancer.jobmanager.event.Constants.PROPERTY_EXECUTION;
 import static org.apache.stanbol.enhancer.jobmanager.event.Constants.TOPIC_JOB_MANAGER;
 import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.getEngine;
 
@@ -126,6 +126,7 @@ public class EnhancementJobHandler imple
             processingLock.writeLock().unlock();
         }
         if(init){
+            enhancementJob.startProcessing();
             executeNextNodes(enhancementJob);
         }
         return o;
@@ -134,8 +135,51 @@ public class EnhancementJobHandler imple
     @Override
     public void handleEvent(Event event) {
         EnhancementJob job = (EnhancementJob)event.getProperty(PROPERTY_JOB_MANAGER);
-        NonLiteral node = (NonLiteral)event.getProperty(PROPERTY_NODE);
-        String engineName = getEngine(job.getExecutionPlan(), node);
+        NonLiteral execution = (NonLiteral)event.getProperty(PROPERTY_EXECUTION);
+        if(job == null || execution == null){
+            log.warn("Unable to process EnhancementEvent where EnhancementJob " +
+            		"{} or Execution node {} is null -> ignore",job,execution);
+        }
+        try {
+            processEvent(job, execution);
+        } catch (Throwable t) {
+            //this ensures that an runtime exception does not 
+           job.setFailed(execution, null, new IllegalStateException(
+               "Unexpected Exception while processing ContentItem '"
+               + job.getContentItem().getUri()+"' with EnhancementJobManager: "
+               + EventJobManagerImpl.class,t)); 
+        }
+        //(2) trigger the next actions
+        log.debug("++ w: {}","check for next Executions");
+        job.getLock().writeLock().lock();
+        log.debug(">> w: {}","check for next Executions");
+        try {
+            if(job.isFinished()){
+                finish(job);
+            } else if(!job.isFailed()){
+                executeNextNodes(job);
+            } else {
+                if(log.isInfoEnabled()){
+                    Collection<String> running = new ArrayList<String>(3);
+                    for(NonLiteral runningNode : job.getRunning()){
+                        running.add(getEngine(job.getExecutionPlan(), runningNode));
+                    }
+                    log.debug("Job {} failed, but {} still running!",
+                        job.getContentItem().getUri(),running);
+                }
+            }
+        } finally {
+            log.debug("<< w: {}","check for next Executions");
+            job.getLock().writeLock().unlock();
+        }
+    }
+    /**
+     * @param job
+     * @param execution
+     */
+    private void processEvent(EnhancementJob job, NonLiteral execution) {
+        NonLiteral executionNode = job.getExecutionNode(execution);
+        String engineName = getEngine(job.getExecutionPlan(), executionNode);
         //(1) execute the parsed ExecutionNode
         EnhancementEngine engine = engineManager.getEngine(engineName);
         if(engine != null){
@@ -158,9 +202,9 @@ public class EnhancementJobHandler imple
                 log.debug(">> w: {}: {}","start sync execution", engine.getName());
                 try {
                     engine.computeEnhancements(job.getContentItem());
-                    job.setCompleted(node);
+                    job.setCompleted(execution);
                 } catch (EngineException e){
-                    job.setFailed(node, engine, e);
+                    job.setFailed(execution, engine, e);
                 } finally{
                     log.debug("<< w: {}: {}","finished sync execution", engine.getName());
                     job.getLock().writeLock().unlock();
@@ -170,38 +214,15 @@ public class EnhancementJobHandler imple
                     log.debug("++ n: start async execution of Engine {}",engine.getName());
                     engine.computeEnhancements(job.getContentItem());
                     log.debug("++ n: finished async execution of Engine {}",engine.getName());
-                    job.setCompleted(node);
+                    job.setCompleted(execution);
                 } catch (EngineException e) {
-                    job.setFailed(node, engine, e);
+                    job.setFailed(execution, engine, e);
                 }
             } else { //required engine is unable to enhance the content 
-                job.setFailed(node,engine,exception);
+                job.setFailed(execution,engine,exception);
             }
         } else { //engine with that name is not available
-            job.setFailed(node, null, null);
-        }
-        //(2) trigger the next actions
-        log.debug("++ w: {}: {}","check next after", engineName);
-        job.getLock().writeLock().lock();
-        log.debug(">> w: {}: {}","check next after", engineName);
-        try {
-            if(job.isFinished()){
-                finish(job);
-            } else if(!job.isFailed()){
-                executeNextNodes(job);
-            } else {
-                if(log.isInfoEnabled()){
-                    Collection<String> running = new ArrayList<String>(3);
-                    for(NonLiteral runningNode : job.getRunning()){
-                        running.add(getEngine(job.getExecutionPlan(), runningNode));
-                    }
-                    log.debug("Job {} failed, but {} still running!",
-                        job.getContentItem().getUri(),running);
-                }
-            }
-        } finally {
-            log.debug("<< w: {}: {}","check next after", engineName);
-            job.getLock().writeLock().unlock();
+            job.setFailed(execution, null, null);
         }
     }
     /**
@@ -240,7 +261,7 @@ public class EnhancementJobHandler imple
         for(NonLiteral executable : job.getExecutable()){
             Dictionary<String,Object> properties = new Hashtable<String,Object>();
             properties.put(PROPERTY_JOB_MANAGER, job);
-            properties.put(PROPERTY_NODE, executable);
+            properties.put(PROPERTY_EXECUTION, executable);
             job.setRunning(executable);
             if(log.isDebugEnabled()){
                 log.debug("SHEDULE execution of Engine {}",ExecutionPlanHelper.getEngine(job.getExecutionPlan(), executable));

Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EventJobManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EventJobManagerImpl.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EventJobManagerImpl.java (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EventJobManagerImpl.java Wed Feb  1 11:59:37 2012
@@ -61,6 +61,7 @@ public class EventJobManagerImpl impleme
     private ServiceRegistration jobHandlerRegistration;
     private EnhancementJobHandler jobHandler;
     
+    
     /**
      * Instantiates and registers the {@link EnhancementJobHandler} as
      * {@link EventHandler} for the topic 
@@ -114,7 +115,8 @@ public class EventJobManagerImpl impleme
                 "' because NULL was parsed as enhancement chain");
         }
         long start = System.currentTimeMillis();
-        EnhancementJob job = new EnhancementJob(ci, chain.getName(), chain.getExecutionPlan());
+        boolean isDefaultChain = chain.equals(chainManager.getDefault());
+        EnhancementJob job = new EnhancementJob(ci, chain.getName(), chain.getExecutionPlan(),isDefaultChain);
         //start the execution
         //wait for the results
         Object object = jobHandler.register(job);
@@ -132,6 +134,11 @@ public class EventJobManagerImpl impleme
             new Object[]{ job.isFailed() ? "Failed" : "Finished",
                     job.getContentItem().getUri(),
                     System.currentTimeMillis()-start});
+        //NOTE: ExecutionMetadata are not added to the metadata of the ContentItem
+        //      by the EnhancementJobManager.
+        //      However one could add this as an optional feature to the
+        //      RESTful interface of the Enhancer!
+        //ci.getMetadata().addAll(job.getExecutionMetadata());
         if(job.isFailed()){
             throw new ChainException(job.getErrorMessage(), job.getError());
         }

Modified: incubator/stanbol/trunk/integration-tests/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/integration-tests/pom.xml?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/integration-tests/pom.xml (original)
+++ incubator/stanbol/trunk/integration-tests/pom.xml Wed Feb  1 11:59:37 2012
@@ -156,11 +156,12 @@
             <keepJarRunning>${keepJarRunning}</keepJarRunning>
             <server.ready.timeout.seconds>180</server.ready.timeout.seconds>
             <server.ready.path.1>/:stanbol.css</server.ready.path.1>
-            <server.ready.path.2>/engines:There are currently</server.ready.path.2>
+            <server.ready.path.2>/enhancer:Stateless REST analysis</server.ready.path.2>
             <server.ready.path.3>/factstore:What is the FactStore</server.ready.path.3>
             <server.ready.path.4>/contenthub:Recently uploaded Content Items</server.ready.path.4>
-			<server.ready.path.5>/ontonet:Apache Stanbol OntoNet</server.ready.path.5>
-            <!-- server.ready.path.6>/reasoners:Apache Stanbol Reasoners</server.ready.path.6 -->
+            <server.ready.path.5>/entityhub:The RESTful API of the Entityhub</server.ready.path.5>
+            <server.ready.path.6>/ontonet:Apache Stanbol OntoNet</server.ready.path.6>
+            <!-- server.ready.path.7>/reasoners:Apache Stanbol Reasoners</server.ready.path.7 -->
           </systemPropertyVariables>
           <excludes>
             <!-- TODO: remove before commit -->