Micheal Hahn PR#6, Extension Activity improvements

Project: http://git-wip-us.apache.org/repos/asf/ode/repo
Commit: http://git-wip-us.apache.org/repos/asf/ode/commit/28503b88
Tree: http://git-wip-us.apache.org/repos/asf/ode/tree/28503b88
Diff: http://git-wip-us.apache.org/repos/asf/ode/diff/28503b88

Branch: refs/heads/master
Commit: 28503b8803e768654ef144be8b695c028a56c03e
Parents: 93c9155
Author: sathwik <[email protected]>
Authored: Sat Apr 28 18:42:12 2018 +0530
Committer: sathwik <[email protected]>
Committed: Sat Apr 28 18:42:12 2018 +0530

----------------------------------------------------------------------
 .gitignore                                      |    2 +
 README.extensions                               |   22 +
 Rakefile                                        |    2 +-
 .../apache/ode/bpel/eapi/ExtensionContext.java  |   36 +-
 .../apache/ode/bpel/compiler/BpelCompiler.java  |    3 +
 .../bpel/compiler/bom/ExtensibilityQNames.java  |    2 +-
 .../java/org/apache/ode/bpel/obj/OProcess.java  | 1094 +++++++++---------
 .../apache/ode/bpel/obj/migrate/OmOld2new.java  |    3 +-
 .../bpel4restlight/Bpel4RestLightOperation.java |    6 +-
 .../org/apache/ode/bpel/engine/BpelProcess.java |    8 +-
 .../ode/bpel/engine/BpelRuntimeContextImpl.java |   54 +-
 .../org/apache/ode/bpel/runtime/ASSIGN.java     |   73 +-
 .../ode/bpel/runtime/BpelRuntimeContext.java    |    5 +-
 .../ode/bpel/runtime/EXTENSIONACTIVITY.java     |   68 +-
 .../ode/bpel/runtime/ExtensionContextImpl.java  |   93 +-
 .../runtime/channels/ExtensionResponse.java     |   30 -
 .../AbstractAsyncExtensionOperation.java        |   35 +
 .../AbstractSyncExtensionOperation.java         |   46 +
 .../apache/ode/bpel/runtime/CoreBpelTest.java   |   12 +-
 .../apache/ode/test/MockExtensionContext.java   |  106 ++
 .../org/apache/ode/test/ExtensibilityTest.java  |  146 +++
 .../ExtensionActivity.bpel                      |   82 ++
 .../ExtensionActivity.wsdl                      |   67 ++
 .../bpel/2.0/TestExtensionActivity/deploy.xml   |   12 +
 .../2.0/TestExtensionActivity/test.properties   |    6 +
 .../ExtensionActivity.bpel                      |   75 ++
 .../ExtensionActivity.wsdl                      |   50 +
 .../deploy.xml                                  |   12 +
 .../test.properties                             |    6 +
 .../ExtensionAssign.bpel                        |   56 +
 .../ExtensionAssign.wsdl                        |   68 ++
 .../2.0/TestExtensionAssignOperation/deploy.xml |   12 +
 .../test.properties                             |    6 +
 33 files changed, 1554 insertions(+), 744 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 27225ba..5199c2a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,5 @@ derby.log
 Gemfile.lock
 spoon
 *.log
+.m2
+tmp/

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/README.extensions
----------------------------------------------------------------------
diff --git a/README.extensions b/README.extensions
new file mode 100644
index 0000000..689ee97
--- /dev/null
+++ b/README.extensions
@@ -0,0 +1,22 @@
+=============================================
+  Apache ODE - Extension Installation Guide
+=============================================
+
+BPEL 2.0 introduces extensibility mechanisms, which allow you to extend
+the set of activities and/or variable assignment mechanisms.
+With BPEL 2.0 it is possible to extend the language by user-defined
+activities and custom assignment logic.
+
+Since version 1.2 Apache ODE supports these extensibility mechanismns
+and provides a plug-in architecture that allows for registering
+third-party extensions.
+
+1.) Installation of extensions (WAR)
+  1) Copy the extension 
+      TBC
+  
+2.) Installation of extensions (JBI)
+      TBW
+
+3.) Writing ODE extensions
+TBW

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/Rakefile
----------------------------------------------------------------------
diff --git a/Rakefile b/Rakefile
index fd54945..e5abd4f 100644
--- a/Rakefile
+++ b/Rakefile
@@ -316,7 +316,7 @@ define "ode" do
   desc "ODE BPEL Tests"
   define "bpel-test" do
     compile.with projects("bpel-api", "bpel-compiler", "bpel-dao", 
"bpel-runtime",
-      "bpel-store", "utils", "bpel-epr", "dao-hibernate", "agents", 
"scheduler-simple"),
+      "bpel-store", "utils", "bpel-epr", "dao-hibernate", "agents", 
"scheduler-simple", "bpel-nobj"),
       DERBY, JUnit.dependencies, JAVAX.persistence, OPENJPA, WSDL4J, 
COMMONS.httpclient, COMMONS.io,
       GERONIMO.transaction, GERONIMO.kernel, GERONIMO.connector, 
JAVAX.connector, JAVAX.ejb, JAVAX.transaction, TRANQL, 
"tranql:tranql-connector-derby-common:jar:1.1",
       SPRING_TEST, COMMONS.codec, SLF4J, LOG4J2

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java
----------------------------------------------------------------------
diff --git 
a/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java 
b/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java
index e3cf271..378edc6 100644
--- a/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/eapi/ExtensionContext.java
@@ -14,11 +14,10 @@
  */
 package org.apache.ode.bpel.eapi;
 
-import java.util.List;
 import java.util.Map;
 
 import org.apache.ode.bpel.common.FaultException;
-import org.apache.ode.bpel.obj.OLink;
+import org.apache.ode.bpel.obj.OActivity;
 import org.apache.ode.bpel.obj.OProcess;
 import org.apache.ode.bpel.obj.OScope;
 import org.w3c.dom.Node;
@@ -42,14 +41,6 @@ public interface ExtensionContext {
     Map<String, OScope.Variable> getVisibleVariables() throws FaultException;
 
     /**
-     * Returns a list of links.
-     * 
-     * @return an unmodifiable list of visible variables.
-     * @throws FaultException
-     */
-    List<OLink> getLinks() throws FaultException;
-
-    /**
      * Read the value of a BPEL variable.
      *
      * @param variable variable to read
@@ -96,18 +87,27 @@ public interface ExtensionContext {
             throws FaultException;
 
     /**
-     * Obtain the status of a control link.
-     *
-     * @param olink link to check
-     * @return <code>true</code> if the link is active, <code>false</code> 
otherwise.
-     */
-    boolean isLinkActive(OLink olink) throws FaultException;
-
-    /**
      * Reads the current process instance id.
      * 
      * @return instance id
      */
     Long getProcessId();
 
+    /**
+     * Returns the name of the invoking activity.
+     * @return activity name
+     */
+    String getActivityName();
+    
+    /**
+     * Low-level-method
+     */
+    OActivity getOActivity();
+    
+    //ScopeFrame getScopeFrame();
+    void complete();
+    
+    void completeWithFault(Throwable t);
+    
+    void completeWithFault(FaultException fault);
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
----------------------------------------------------------------------
diff --git 
a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java 
b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
index ef4a876..24c72bc 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
@@ -1665,6 +1665,9 @@ public abstract class BpelCompiler implements 
CompilerContext {
 
         _declaredExtensionNS.add(ext.getNamespaceURI());
         _oprocess.getDeclaredExtensions().add(oextension);
+        if (ext.isMustUnderstand()) {
+            _oprocess.getMustUnderstandExtensions().add(oextension);
+        }
 
         if (__log.isDebugEnabled())
             __log.debug("Compiled extension " + oextension);

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java
----------------------------------------------------------------------
diff --git 
a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java
 
b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java
index 8f87d57..4f40d8d 100644
--- 
a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java
+++ 
b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java
@@ -46,7 +46,7 @@ public abstract class ExtensibilityQNames {
 
     public static final String NS_BPEL_EXTENSIBILITY = 
"http://ode.apache.org/bpelExtensibility";;
        
-    public static final QName UNKNOWN_EO_FAULT_NAME = new 
QName(NS_BPEL_EXTENSIBILITY, "unknownExtensionOperation");
+    public static final QName UNKNOWN_EA_FAULT_NAME = new 
QName(NS_BPEL_EXTENSIBILITY, "unknownExtensionImplementation");
        
     public static final QName INVALID_EXTENSION_ELEMENT = new 
QName(NS_BPEL_EXTENSIBILITY, "invalidExtensionElement");
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java
----------------------------------------------------------------------
diff --git a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java 
b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java
index a01936f..bc1ebde 100644
--- a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java
+++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java
@@ -1,20 +1,16 @@
 /*
- * 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
+ * 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
+ * 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.
+ * 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.
  */
 package org.apache.ode.bpel.obj;
 
@@ -51,272 +47,272 @@ import 
de.danielbechler.diff.annotation.ObjectDiffProperty;
 /**
  * Compiled BPEL process representation.
  */
-public class OProcess extends OBase  implements Serializable{
-       public static final long serialVersionUID = -1L;
-       
-       /**
-        * Change log of class version
-        * initial 1
-        * current 2
-        * 
-        * 1->2:
-        *      added namespaceContext attribute
-        *  */
-       public static final int CURRENT_CLASS_VERSION = 2;
-
-       public static int instanceCount = 0;
-       private static final String GUID = "guid";
-       /** BPEL version. */
-       private static final String VERSION = "version";
-       /** Various constants that are needed at runtime. */
-       private static final String CONSTANTS = "constants";
-       /** Universally Unique Identifier */
-       private static final String UUID = "uuid";
-       /** Namespace of the process. */
-       private static final String TARGETNAMESPACE = "targetNamespace";
-       /** Name of the process. */
-       private static final String PROCESSNAME = "processName";
-       /** ProcessImpl-level scope. */
-       private static final String PROCESSCOPE = "procesScope";
-       /** All partner links in the process. */
-       private static final String ALLPARTNERLINKS = "allPartnerLinks";
-       private static final String PROPERTIES = "properties";
-       /** Date process was compiled. */
-       private static final String COMPILEDATE = "compileDate";
-       private static final String CHILDIDCOUNTER = "_childIdCounter";
-       private static final String CHILDREN = "_children";
-       private static final String EXPRESSIONLANGUAGES = "expressionLanguages";
-       private static final String MESSAGETYPES = "messageTypes";
-       private static final String ELEMENTTYPES = "elementTypes";
-       private static final String XSDTYPES = "xsdTypes";
-       private static final String XSLSHEETS = "xslSheets";
-       private static final String NAMESPACECONTEXT = "namespaceContext";
-       
-       /** All declared extensions in the process. **/
-       private static final String DECLAREDEXTENSIONS = "declaredExtensions";
-       
-       /**
-        * This constructor should only be used by Jackson when deserialize.
-        */
-       @JsonCreator
-       public OProcess() {
-               instanceCount ++;
-               setChildIdCounter(0);
-       }
-       public OProcess(String version) {
-               super(null);
-               setVersion(version);
-               instanceCount++;
-               setAllPartnerLinks(new HashSet<OPartnerLink>());
-               setProperties(new ArrayList<OProperty>());
-               setChildren(new ArrayList<OBase>());
-               setExpressionLanguages(new HashSet<OExpressionLanguage>());
-               setMessageTypes(new HashMap<QName, OMessageVarType>());
-               setElementTypes(new HashMap<QName, OElementVarType>());
-               setXsdTypes(new HashMap<QName, OXsdTypeVarType>());
-               setXslSheets(new HashMap<URI, OXslSheet>());
-               
-               setDeclaredExtensions(new HashSet<OExtension>());
-               
-               setChildIdCounter(0);
-       }
-
-       @Override
-       public void dehydrate() {
-               super.dehydrate();
-               getProcesScope().dehydrate();
-               getAllPartnerLinks().clear();
-               for (OBase obase : getChildren()) {
-                       obase.dehydrate();
-               }
-               getChildren().clear();
-               getMessageTypes().clear();
-               getElementTypes().clear();
-               getXsdTypes().clear();
-               getXslSheets().clear();
-               getDeclaredExtensions().clear();
-       }
-
-       @Override
-       public String digest() {
-               return getProcessName() + ";" + getProcesScope().digest();
-       }
-
-       protected void finalize() throws Throwable {
-               instanceCount--;
-       }
-
-       @SuppressWarnings("unchecked")
-       @JsonIgnore
-       public Set<OPartnerLink> getAllPartnerLinks() {
-               Set<OPartnerLink> links = (Set<OPartnerLink>) fieldContainer
-                               .get(ALLPARTNERLINKS);
-               return links;
-       }
-
-       public OBase getChild(final int id) {
-               for (int i = getChildren().size() - 1; i >= 0; i--) {
-                       OBase child = getChildren().get(i);
-                       if (child.getId() == id)
-                               return child;
-               }
-               return null;
-       }
-
-       @JsonIgnore
-       int getChildIdCounter() {
-               Object o = fieldContainer.get(CHILDIDCOUNTER);
-               return o == null ? 0 : (Integer)o;
-       }
-
-       @SuppressWarnings("unchecked")
-       @JsonIgnore
-       public List<OBase> getChildren() {
-               Object o = fieldContainer.get(CHILDREN);
-               return o == null ? null : (List<OBase>)o;
-       }
-
-       @JsonIgnore
-       public Date getCompileDate() {
-               Object o = fieldContainer.get(COMPILEDATE);
-               return o == null ? null : (Date)o;
-       }
-
-       @JsonIgnore
-       public OConstants getConstants() {
-               Object o = fieldContainer.get(CONSTANTS);
-               return o == null ? null : (OConstants)o;
-       }
-
-       @SuppressWarnings("rawtypes")
-       @ObjectDiffProperty(ignore = true)
-       @JsonIgnore
-       public List<String> getCorrelators() {
-               // MOVED from ProcessSchemaGenerator
-               List<String> correlators = new ArrayList<String>();
-
-               for (OPartnerLink plink : getAllPartnerLinks()) {
-                       if (plink.hasMyRole()) {
-                               for (Iterator opI = 
plink.getMyRolePortType().getOperations()
-                                               .iterator(); opI.hasNext();) {
-                                       Operation op = (Operation) opI.next();
-                                       correlators.add(plink.getName() + "." + 
op.getName());
-                               }
-                       }
-               }
-
-               return correlators;
-       }
-
-       @SuppressWarnings("unchecked")
-       @JsonIgnore
-       public HashMap<QName, OElementVarType> getElementTypes() {
-               return (HashMap<QName, OElementVarType>) fieldContainer
-                               .get(ELEMENTTYPES);
-       }
-
-       @JsonIgnore
-       @SuppressWarnings("unchecked")
-       public HashSet<OExpressionLanguage> getExpressionLanguages() {
-               //TODO conflicts with legacy impl of this method
-               return (HashSet<OExpressionLanguage>) fieldContainer
-                               .get(EXPRESSIONLANGUAGES);
-       }
-
-       @JsonIgnore
-       public String getGuid() {
-               Object o = fieldContainer.get(GUID);
-               return o == null ? null : (String)o;
-       }
-
-       @SuppressWarnings("unchecked")
-       @JsonIgnore
-       public HashMap<QName, OMessageVarType> getMessageTypes() {
-               return (HashMap<QName, OMessageVarType>) fieldContainer
-                               .get(MESSAGETYPES);
-       }
-
-       @JsonIgnore
-       public String getName() {
-               return getProcessName();
-       }
-
-       @JsonIgnore
-       public NSContext getNamespaceContext() {
-               Object o = fieldContainer.get(NAMESPACECONTEXT);
-               return o == null ? null : (NSContext)o;
-       }
-
-       @JsonIgnore
-       public OPartnerLink getPartnerLink(String name) {
-               for (OPartnerLink partnerLink : getAllPartnerLinks()) {
-                       if (partnerLink.getName().equals(name)) {
-                               return partnerLink;
-                       }
-               }
-               return null;
-       }
-
-       @JsonIgnore
-       public OScope getProcesScope() {
-               Object o = fieldContainer.get(PROCESSCOPE);
-               return o == null ? null : (OScope)o;
-       }
-
-       @JsonIgnore
-       public String getProcessName() {
-               Object o = fieldContainer.get(PROCESSNAME);
-               return o == null ? null : (String)o;
-       }
-
-       @SuppressWarnings("unchecked")
-       @JsonIgnore
-       public List<OProperty> getProperties() {
-               Object o = fieldContainer.get(PROPERTIES);
-               return o == null ? null : (List<OProperty>)o;
-       }
-
-       @ObjectDiffProperty(ignore = true)
-       @JsonIgnore
-       public QName getQName() {
-               return new QName(getTargetNamespace(), getProcessName());
-       }
-
-       public OScope getScope(String scopeName) {
-               throw new UnsupportedOperationException();
-       }
-
-       @JsonIgnore
-       public String getTargetNamespace() {
-               Object o = fieldContainer.get(TARGETNAMESPACE);
-               return o == null ? null : (String)o;
-       }
-
-       @JsonIgnore
-       public String getUuid() {
-               Object o = fieldContainer.get(UUID);
-               return o == null ? null : (String)o;
-       }
-
-       @JsonIgnore
-       public String getVersion() {
-               Object o = fieldContainer.get(VERSION);
-               return o == null ? null : (String)o;
-       }
-
-       @SuppressWarnings("unchecked")
-       @JsonIgnore
-       public HashMap<QName, OXsdTypeVarType> getXsdTypes() {
-               Object o = fieldContainer.get(XSDTYPES);
-               return o == null ? null : (HashMap<QName, OXsdTypeVarType>)o;
-       }
-
-       @SuppressWarnings("unchecked")
-       @JsonIgnore
-       public HashMap<URI, OXslSheet> getXslSheets() {
-               Object o = fieldContainer.get(XSLSHEETS);
-               return o == null ? null : (HashMap<URI, OXslSheet>)o;
-       }
+public class OProcess extends OBase implements Serializable {
+    public static final long serialVersionUID = -1L;
+
+    /**
+     * Change log of class version initial 1 current 2
+     * 
+     * 1->2: added namespaceContext attribute
+     */
+    public static final int CURRENT_CLASS_VERSION = 2;
+
+    public static int instanceCount = 0;
+    private static final String GUID = "guid";
+    /** BPEL version. */
+    private static final String VERSION = "version";
+    /** Various constants that are needed at runtime. */
+    private static final String CONSTANTS = "constants";
+    /** Universally Unique Identifier */
+    private static final String UUID = "uuid";
+    /** Namespace of the process. */
+    private static final String TARGETNAMESPACE = "targetNamespace";
+    /** Name of the process. */
+    private static final String PROCESSNAME = "processName";
+    /** ProcessImpl-level scope. */
+    private static final String PROCESSCOPE = "procesScope";
+    /** All partner links in the process. */
+    private static final String ALLPARTNERLINKS = "allPartnerLinks";
+    private static final String PROPERTIES = "properties";
+    /** Date process was compiled. */
+    private static final String COMPILEDATE = "compileDate";
+    private static final String CHILDIDCOUNTER = "_childIdCounter";
+    private static final String CHILDREN = "_children";
+    private static final String EXPRESSIONLANGUAGES = "expressionLanguages";
+    private static final String MESSAGETYPES = "messageTypes";
+    private static final String ELEMENTTYPES = "elementTypes";
+    private static final String XSDTYPES = "xsdTypes";
+    private static final String XSLSHEETS = "xslSheets";
+    private static final String NAMESPACECONTEXT = "namespaceContext";
+
+    /** All declared extensions in the process. **/
+    private static final String DECLAREDEXTENSIONS = "declaredExtensions";
+
+    /** All must-understand extensions in the process. **/
+    private static final String MUSTUNDERSTANDEXTENSIONS = 
"mustUnderstandExtensions";
+
+    /**
+     * This constructor should only be used by Jackson when deserialize.
+     */
+    @JsonCreator
+    public OProcess() {
+        instanceCount++;
+        setChildIdCounter(0);
+    }
+
+    public OProcess(String version) {
+        super(null);
+        setVersion(version);
+        instanceCount++;
+        setAllPartnerLinks(new HashSet<OPartnerLink>());
+        setProperties(new ArrayList<OProperty>());
+        setChildren(new ArrayList<OBase>());
+        setExpressionLanguages(new HashSet<OExpressionLanguage>());
+        setMessageTypes(new HashMap<QName, OMessageVarType>());
+        setElementTypes(new HashMap<QName, OElementVarType>());
+        setXsdTypes(new HashMap<QName, OXsdTypeVarType>());
+        setXslSheets(new HashMap<URI, OXslSheet>());
+
+        setDeclaredExtensions(new HashSet<OExtension>());
+
+        setMustUnderstandExtensions(new HashSet<OExtension>());
+
+        setChildIdCounter(0);
+    }
+
+    @Override
+    public void dehydrate() {
+        super.dehydrate();
+        getProcesScope().dehydrate();
+        getAllPartnerLinks().clear();
+        for (OBase obase : getChildren()) {
+            obase.dehydrate();
+        }
+        getChildren().clear();
+        getMessageTypes().clear();
+        getElementTypes().clear();
+        getXsdTypes().clear();
+        getXslSheets().clear();
+        getDeclaredExtensions().clear();
+        getMustUnderstandExtensions().clear();
+    }
+
+    @Override
+    public String digest() {
+        return getProcessName() + ";" + getProcesScope().digest();
+    }
+
+    protected void finalize() throws Throwable {
+        instanceCount--;
+    }
+
+    @SuppressWarnings("unchecked")
+    @JsonIgnore
+    public Set<OPartnerLink> getAllPartnerLinks() {
+        Set<OPartnerLink> links = (Set<OPartnerLink>) 
fieldContainer.get(ALLPARTNERLINKS);
+        return links;
+    }
+
+    public OBase getChild(final int id) {
+        for (int i = getChildren().size() - 1; i >= 0; i--) {
+            OBase child = getChildren().get(i);
+            if (child.getId() == id)
+                return child;
+        }
+        return null;
+    }
+
+    @JsonIgnore
+    int getChildIdCounter() {
+        Object o = fieldContainer.get(CHILDIDCOUNTER);
+        return o == null ? 0 : (Integer) o;
+    }
+
+    @SuppressWarnings("unchecked")
+    @JsonIgnore
+    public List<OBase> getChildren() {
+        Object o = fieldContainer.get(CHILDREN);
+        return o == null ? null : (List<OBase>) o;
+    }
+
+    @JsonIgnore
+    public Date getCompileDate() {
+        Object o = fieldContainer.get(COMPILEDATE);
+        return o == null ? null : (Date) o;
+    }
+
+    @JsonIgnore
+    public OConstants getConstants() {
+        Object o = fieldContainer.get(CONSTANTS);
+        return o == null ? null : (OConstants) o;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @ObjectDiffProperty(ignore = true)
+    @JsonIgnore
+    public List<String> getCorrelators() {
+        // MOVED from ProcessSchemaGenerator
+        List<String> correlators = new ArrayList<String>();
+
+        for (OPartnerLink plink : getAllPartnerLinks()) {
+            if (plink.hasMyRole()) {
+                for (Iterator opI = 
plink.getMyRolePortType().getOperations().iterator(); opI
+                        .hasNext();) {
+                    Operation op = (Operation) opI.next();
+                    correlators.add(plink.getName() + "." + op.getName());
+                }
+            }
+        }
+
+        return correlators;
+    }
+
+    @SuppressWarnings("unchecked")
+    @JsonIgnore
+    public HashMap<QName, OElementVarType> getElementTypes() {
+        return (HashMap<QName, OElementVarType>) 
fieldContainer.get(ELEMENTTYPES);
+    }
+
+    @JsonIgnore
+    @SuppressWarnings("unchecked")
+    public HashSet<OExpressionLanguage> getExpressionLanguages() {
+        // TODO conflicts with legacy impl of this method
+        return (HashSet<OExpressionLanguage>) 
fieldContainer.get(EXPRESSIONLANGUAGES);
+    }
+
+    @JsonIgnore
+    public String getGuid() {
+        Object o = fieldContainer.get(GUID);
+        return o == null ? null : (String) o;
+    }
+
+    @SuppressWarnings("unchecked")
+    @JsonIgnore
+    public HashMap<QName, OMessageVarType> getMessageTypes() {
+        return (HashMap<QName, OMessageVarType>) 
fieldContainer.get(MESSAGETYPES);
+    }
+
+    @JsonIgnore
+    public String getName() {
+        return getProcessName();
+    }
+
+    @JsonIgnore
+    public NSContext getNamespaceContext() {
+        Object o = fieldContainer.get(NAMESPACECONTEXT);
+        return o == null ? null : (NSContext) o;
+    }
+
+    @JsonIgnore
+    public OPartnerLink getPartnerLink(String name) {
+        for (OPartnerLink partnerLink : getAllPartnerLinks()) {
+            if (partnerLink.getName().equals(name)) {
+                return partnerLink;
+            }
+        }
+        return null;
+    }
+
+    @JsonIgnore
+    public OScope getProcesScope() {
+        Object o = fieldContainer.get(PROCESSCOPE);
+        return o == null ? null : (OScope) o;
+    }
+
+    @JsonIgnore
+    public String getProcessName() {
+        Object o = fieldContainer.get(PROCESSNAME);
+        return o == null ? null : (String) o;
+    }
+
+    @SuppressWarnings("unchecked")
+    @JsonIgnore
+    public List<OProperty> getProperties() {
+        Object o = fieldContainer.get(PROPERTIES);
+        return o == null ? null : (List<OProperty>) o;
+    }
+
+    @ObjectDiffProperty(ignore = true)
+    @JsonIgnore
+    public QName getQName() {
+        return new QName(getTargetNamespace(), getProcessName());
+    }
+
+    public OScope getScope(String scopeName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @JsonIgnore
+    public String getTargetNamespace() {
+        Object o = fieldContainer.get(TARGETNAMESPACE);
+        return o == null ? null : (String) o;
+    }
+
+    @JsonIgnore
+    public String getUuid() {
+        Object o = fieldContainer.get(UUID);
+        return o == null ? null : (String) o;
+    }
+
+    @JsonIgnore
+    public String getVersion() {
+        Object o = fieldContainer.get(VERSION);
+        return o == null ? null : (String) o;
+    }
+
+    @SuppressWarnings("unchecked")
+    @JsonIgnore
+    public HashMap<QName, OXsdTypeVarType> getXsdTypes() {
+        Object o = fieldContainer.get(XSDTYPES);
+        return o == null ? null : (HashMap<QName, OXsdTypeVarType>) o;
+    }
+
+    @SuppressWarnings("unchecked")
+    @JsonIgnore
+    public HashMap<URI, OXslSheet> getXslSheets() {
+        Object o = fieldContainer.get(XSLSHEETS);
+        return o == null ? null : (HashMap<URI, OXslSheet>) o;
+    }
 
     @SuppressWarnings("unchecked")
     @JsonIgnore
@@ -324,235 +320,261 @@ public class OProcess extends OBase  implements 
Serializable{
         return (Set<OExtension>) fieldContainer.get(DECLAREDEXTENSIONS);
     }
 
-       public void setAllPartnerLinks(Set<OPartnerLink> allPartnerLinks) {
-               if (getAllPartnerLinks() == null) {
-                       fieldContainer.put(ALLPARTNERLINKS, allPartnerLinks);
-               }
-       }
-
-       void setChildIdCounter(int childIdCounter) {
-               fieldContainer.put(CHILDIDCOUNTER, childIdCounter);
-       }
-
-       void setChildren(List<OBase> children) {
-               fieldContainer.put(CHILDREN, children);
-       }
-
-       public void setCompileDate(Date compileDate) {
-               fieldContainer.put(COMPILEDATE, compileDate);
-       }
-
-       public void setConstants(OConstants constants) {
-               fieldContainer.put(CONSTANTS, constants);
-       }
-
-       public void setElementTypes(HashMap<QName, OElementVarType> 
elementTypes) {
-               if (getElementTypes() == null) {
-                       fieldContainer.put(ELEMENTTYPES, elementTypes);
-               }
-       }
-
-       public void setExpressionLanguages(
-                       HashSet<OExpressionLanguage> expressionLanguages) {
-               if (getExpressionLanguages() == null) {
-                       fieldContainer.put(EXPRESSIONLANGUAGES, 
expressionLanguages);
-               }
-       }
-
-       public void setGuid(String guid) {
-               fieldContainer.put(GUID, guid);
-       }
-
-       public void setMessageTypes(HashMap<QName, OMessageVarType> 
messageTypes) {
-               if (getMessageTypes() == null) {
-                       fieldContainer.put(MESSAGETYPES, messageTypes);
-               }
-       }
-
-       public void setNamespaceContext(NSContext namespaceContext) {
-               fieldContainer.put(NAMESPACECONTEXT, namespaceContext);
-       }
-
-       public void setProcesScope(OScope procesScope) {
-               fieldContainer.put(PROCESSCOPE, procesScope);
-       }
-
-       public void setProcessName(String processName) {
-               fieldContainer.put(PROCESSNAME, processName);
-       }
-
-       public void setProperties(List<OProperty> properties) {
-               if (getProperties() == null) {
-                       fieldContainer.put(PROPERTIES, properties);
-               }
-       }
-
-       public void setTargetNamespace(String targetNamespace) {
-               fieldContainer.put(TARGETNAMESPACE, targetNamespace);
-       }
-
-       public void setUuid(String uuid) {
-               fieldContainer.put(UUID, uuid);
-       }
-
-       public void setVersion(String version) {
-               fieldContainer.put(VERSION, version);
-       }
-
-       public void setXsdTypes(HashMap<QName, OXsdTypeVarType> xsdTypes) {
-               if (getXsdTypes() == null) {
-                       fieldContainer.put(XSDTYPES, xsdTypes);
-               }
-       }
-
-       public void setXslSheets(HashMap<URI, OXslSheet> xslSheets) {
-               if (getXslSheets() == null) {
-                       fieldContainer.put(XSLSHEETS, xslSheets);
-               }
-       }
-       
+    @SuppressWarnings("unchecked")
+    @JsonIgnore
+    public Set<OExtension> getMustUnderstandExtensions() {
+        return (Set<OExtension>) fieldContainer.get(MUSTUNDERSTANDEXTENSIONS);
+    }
+
+    @JsonIgnore
+    public boolean hasMustUnderstandExtension(String namespaceURI) {
+        boolean found = false;
+        
+        // Check if an extension implementation is registered for the given 
namespareURI that the
+        // engine must understand
+        Iterator<OExtension> iter = getMustUnderstandExtensions().iterator();
+        while (!found && iter.hasNext()) {
+            OExtension ext = iter.next();
+            if (ext.getNamespace().equals(namespaceURI)) {
+                found = true;
+            }
+        }
+        
+        return found;
+    }
+
+    public void setAllPartnerLinks(Set<OPartnerLink> allPartnerLinks) {
+        if (getAllPartnerLinks() == null) {
+            fieldContainer.put(ALLPARTNERLINKS, allPartnerLinks);
+        }
+    }
+
+    void setChildIdCounter(int childIdCounter) {
+        fieldContainer.put(CHILDIDCOUNTER, childIdCounter);
+    }
+
+    void setChildren(List<OBase> children) {
+        fieldContainer.put(CHILDREN, children);
+    }
+
+    public void setCompileDate(Date compileDate) {
+        fieldContainer.put(COMPILEDATE, compileDate);
+    }
+
+    public void setConstants(OConstants constants) {
+        fieldContainer.put(CONSTANTS, constants);
+    }
+
+    public void setElementTypes(HashMap<QName, OElementVarType> elementTypes) {
+        if (getElementTypes() == null) {
+            fieldContainer.put(ELEMENTTYPES, elementTypes);
+        }
+    }
+
+    public void setExpressionLanguages(HashSet<OExpressionLanguage> 
expressionLanguages) {
+        if (getExpressionLanguages() == null) {
+            fieldContainer.put(EXPRESSIONLANGUAGES, expressionLanguages);
+        }
+    }
+
+    public void setGuid(String guid) {
+        fieldContainer.put(GUID, guid);
+    }
+
+    public void setMessageTypes(HashMap<QName, OMessageVarType> messageTypes) {
+        if (getMessageTypes() == null) {
+            fieldContainer.put(MESSAGETYPES, messageTypes);
+        }
+    }
+
+    public void setNamespaceContext(NSContext namespaceContext) {
+        fieldContainer.put(NAMESPACECONTEXT, namespaceContext);
+    }
+
+    public void setProcesScope(OScope procesScope) {
+        fieldContainer.put(PROCESSCOPE, procesScope);
+    }
+
+    public void setProcessName(String processName) {
+        fieldContainer.put(PROCESSNAME, processName);
+    }
+
+    public void setProperties(List<OProperty> properties) {
+        if (getProperties() == null) {
+            fieldContainer.put(PROPERTIES, properties);
+        }
+    }
+
+    public void setTargetNamespace(String targetNamespace) {
+        fieldContainer.put(TARGETNAMESPACE, targetNamespace);
+    }
+
+    public void setUuid(String uuid) {
+        fieldContainer.put(UUID, uuid);
+    }
+
+    public void setVersion(String version) {
+        fieldContainer.put(VERSION, version);
+    }
+
+    public void setXsdTypes(HashMap<QName, OXsdTypeVarType> xsdTypes) {
+        if (getXsdTypes() == null) {
+            fieldContainer.put(XSDTYPES, xsdTypes);
+        }
+    }
+
+    public void setXslSheets(HashMap<URI, OXslSheet> xslSheets) {
+        if (getXslSheets() == null) {
+            fieldContainer.put(XSLSHEETS, xslSheets);
+        }
+    }
+
     public void setDeclaredExtensions(Set<OExtension> extensions) {
         if (getDeclaredExtensions() == null) {
             fieldContainer.put(DECLAREDEXTENSIONS, extensions);
         }
     }
-       
-       private void readObject(ObjectInputStream ois) throws IOException, 
ClassNotFoundException{
-               ois.defaultReadObject();
-               fieldContainer.remove(NAMESPACECONTEXT);
-       }
-
-       public static class OProperty extends OBase  implements Serializable{
-       public static final long serialVersionUID = -1L;
-
-               private static final String ALIASES = "aliases";
-               private static final String NAME = "name";
-               
-               @JsonCreator
-               public OProperty(){}
-               public OProperty(OProcess process) {
-                       super(process);
-                       setAliases(new ArrayList<OPropertyAlias>());
-               }
-
-               public OPropertyAlias getAlias(OVarType messageType) {
-                       for (OPropertyAlias aliase : getAliases())
-                               if (aliase.getVarType().equals(messageType))
-                                       return aliase;
-                       return null;
-               }
-
-               @SuppressWarnings("unchecked")
-               @JsonIgnore
-               public List<OPropertyAlias> getAliases() {
-                       Object o = fieldContainer.get(ALIASES);
-               return o == null ? null : (List<OPropertyAlias>)o;
-               }
-
-               @JsonIgnore
-               public QName getName() {
-                       Object o = fieldContainer.get(NAME);
-               return o == null ? null : (QName)o;
-               }
-
-               public void setAliases(List<OPropertyAlias> aliases) {
-                       fieldContainer.put(ALIASES, aliases);
-               }
-
-               public void setName(QName name) {
-                       fieldContainer.put(NAME, name);
-               }
-
-               public String toString() {
-                       return "{OProperty " + getName() + "}";
-               }
-       }
-
-       public static class OPropertyAlias extends OBase  implements 
Serializable{
-               public static final long serialVersionUID = -1L;
-               /**
-                * Change log of class version
-                * initial 1
-                * current 2
-                * 
-                * 1->2:
-                *      added header attribute
-                *  */
-               public static final int CURRENT_CLASS_VERSION = 2;
-
-               private static final String VARTYPE = "varType";
-
-               /** For BPEL 1.1 */
-               private static final String PART = "part";
-               private static final String HEADER = "header";
-               private static final String LOCATION = "location";
-
-               @JsonCreator
-               public OPropertyAlias(){}
-               
-               public OPropertyAlias(OProcess owner) {
-                       super(owner);
-               }
-
-               @JsonIgnore
-               public String getDescription() {
-                       StringBuffer buf = new 
StringBuffer(getVarType().toString());
-                       buf.append('[');
-                       buf.append(getPart() != null ? getPart().getName() : 
"");
-                       buf.append(getHeader() != null ? "header: " + 
getHeader() : "");
-                       if (getLocation() != null) {
-                               buf.append("][");
-                               buf.append(getLocation().toString());
-                       }
-                       buf.append(']');
-                       return buf.toString();
-               }
-
-               @JsonIgnore
-               public String getHeader() {
-                       Object o = fieldContainer.get(HEADER);
-                       return o == null ? null : (String)o;
-               }
-
-               @JsonIgnore
-               public OExpression getLocation() {
-                       Object o = fieldContainer.get(LOCATION);
-               return o == null ? null : (OExpression)o;
-               }
-
-               @JsonIgnore
-               public Part getPart() {
-                       Object o = fieldContainer.get(PART);
-               return o == null ? null : (Part)o;
-               }
-
-               @JsonIgnore
-               public OVarType getVarType() {
-                       Object o = fieldContainer.get(VARTYPE);
-               return o == null ? null : (OVarType)o;
-               }
-
-               public void setHeader(String header) {
-                       fieldContainer.put(HEADER, header);
-               }
-
-               public void setLocation(OExpression location) {
-                       fieldContainer.put(LOCATION, location);
-               }
-
-               public void setPart(Part part) {
-                       fieldContainer.put(PART, part);
-               }
-
-               public void setVarType(OVarType varType) {
-                       fieldContainer.put(VARTYPE, varType);
-               }
-
-               public String toString() {
-                       return "{OPropertyAlias " + getDescription() + "}";
-               }
-
-       }
+
+    public void setMustUnderstandExtensions(Set<OExtension> extensions) {
+        if (getMustUnderstandExtensions() == null) {
+            fieldContainer.put(MUSTUNDERSTANDEXTENSIONS, extensions);
+        }
+    }
+
+    private void readObject(ObjectInputStream ois) throws IOException, 
ClassNotFoundException {
+        ois.defaultReadObject();
+        fieldContainer.remove(NAMESPACECONTEXT);
+    }
+
+    public static class OProperty extends OBase implements Serializable {
+        public static final long serialVersionUID = -1L;
+
+        private static final String ALIASES = "aliases";
+        private static final String NAME = "name";
+
+        @JsonCreator
+        public OProperty() {}
+
+        public OProperty(OProcess process) {
+            super(process);
+            setAliases(new ArrayList<OPropertyAlias>());
+        }
+
+        public OPropertyAlias getAlias(OVarType messageType) {
+            for (OPropertyAlias aliase : getAliases())
+                if (aliase.getVarType().equals(messageType))
+                    return aliase;
+            return null;
+        }
+
+        @SuppressWarnings("unchecked")
+        @JsonIgnore
+        public List<OPropertyAlias> getAliases() {
+            Object o = fieldContainer.get(ALIASES);
+            return o == null ? null : (List<OPropertyAlias>) o;
+        }
+
+        @JsonIgnore
+        public QName getName() {
+            Object o = fieldContainer.get(NAME);
+            return o == null ? null : (QName) o;
+        }
+
+        public void setAliases(List<OPropertyAlias> aliases) {
+            fieldContainer.put(ALIASES, aliases);
+        }
+
+        public void setName(QName name) {
+            fieldContainer.put(NAME, name);
+        }
+
+        public String toString() {
+            return "{OProperty " + getName() + "}";
+        }
+    }
+
+    public static class OPropertyAlias extends OBase implements Serializable {
+        public static final long serialVersionUID = -1L;
+        /**
+         * Change log of class version initial 1 current 2
+         * 
+         * 1->2: added header attribute
+         */
+        public static final int CURRENT_CLASS_VERSION = 2;
+
+        private static final String VARTYPE = "varType";
+
+        /** For BPEL 1.1 */
+        private static final String PART = "part";
+        private static final String HEADER = "header";
+        private static final String LOCATION = "location";
+
+        @JsonCreator
+        public OPropertyAlias() {}
+
+        public OPropertyAlias(OProcess owner) {
+            super(owner);
+        }
+
+        @JsonIgnore
+        public String getDescription() {
+            StringBuffer buf = new StringBuffer(getVarType().toString());
+            buf.append('[');
+            buf.append(getPart() != null ? getPart().getName() : "");
+            buf.append(getHeader() != null ? "header: " + getHeader() : "");
+            if (getLocation() != null) {
+                buf.append("][");
+                buf.append(getLocation().toString());
+            }
+            buf.append(']');
+            return buf.toString();
+        }
+
+        @JsonIgnore
+        public String getHeader() {
+            Object o = fieldContainer.get(HEADER);
+            return o == null ? null : (String) o;
+        }
+
+        @JsonIgnore
+        public OExpression getLocation() {
+            Object o = fieldContainer.get(LOCATION);
+            return o == null ? null : (OExpression) o;
+        }
+
+        @JsonIgnore
+        public Part getPart() {
+            Object o = fieldContainer.get(PART);
+            return o == null ? null : (Part) o;
+        }
+
+        @JsonIgnore
+        public OVarType getVarType() {
+            Object o = fieldContainer.get(VARTYPE);
+            return o == null ? null : (OVarType) o;
+        }
+
+        public void setHeader(String header) {
+            fieldContainer.put(HEADER, header);
+        }
+
+        public void setLocation(OExpression location) {
+            fieldContainer.put(LOCATION, location);
+        }
+
+        public void setPart(Part part) {
+            fieldContainer.put(PART, part);
+        }
+
+        public void setVarType(OVarType varType) {
+            fieldContainer.put(VARTYPE, varType);
+        }
+
+        public String toString() {
+            return "{OPropertyAlias " + getDescription() + "}";
+        }
+
+    }
 
     public static class OExtension extends OBase implements Serializable {
         public static final long serialVersionUID = -1L;
@@ -593,36 +615,36 @@ public class OProcess extends OBase  implements 
Serializable{
         }
     }
 
-       /**
-        * custom deserializer of OProcess.
-        * @author fangzhen
-        * @deprecated unnecessary now
-        */
-       public static class OProcessDeser extends StdDeserializer<OProcess>
-                       implements ResolvableDeserializer {
-               private static final long serialVersionUID = 
7750214662590623362L;
-               private JsonDeserializer<?> defaultDeserializer;
-
-               public OProcessDeser(JsonDeserializer<?> defaultDeserializer) {
-                       super(OProcess.class);
-                       this.defaultDeserializer = defaultDeserializer;
-               }
-
-               @Override
-               public OProcess deserialize(JsonParser jp, 
DeserializationContext ctxt)
-                               throws IOException, JsonProcessingException {
-                       OProcess process = (OProcess) 
defaultDeserializer.deserialize(jp,
-                                       ctxt);
-                       OProcess.instanceCount++;
-                       return process;
-               }
-
-               // for some reason you have to implement ResolvableDeserializer 
when modifying BeanDeserializer
-               // otherwise deserializing throws JsonMappingException??
-               @Override
-               public void resolve(DeserializationContext ctxt)
-                               throws JsonMappingException {
-                       ((ResolvableDeserializer) 
defaultDeserializer).resolve(ctxt);
-               }
-       }
+    /**
+     * custom deserializer of OProcess.
+     * 
+     * @author fangzhen
+     * @deprecated unnecessary now
+     */
+    public static class OProcessDeser extends StdDeserializer<OProcess>
+            implements ResolvableDeserializer {
+        private static final long serialVersionUID = 7750214662590623362L;
+        private JsonDeserializer<?> defaultDeserializer;
+
+        public OProcessDeser(JsonDeserializer<?> defaultDeserializer) {
+            super(OProcess.class);
+            this.defaultDeserializer = defaultDeserializer;
+        }
+
+        @Override
+        public OProcess deserialize(JsonParser jp, DeserializationContext ctxt)
+                throws IOException, JsonProcessingException {
+            OProcess process = (OProcess) defaultDeserializer.deserialize(jp, 
ctxt);
+            OProcess.instanceCount++;
+            return process;
+        }
+
+        // for some reason you have to implement ResolvableDeserializer when 
modifying
+        // BeanDeserializer
+        // otherwise deserializing throws JsonMappingException??
+        @Override
+        public void resolve(DeserializationContext ctxt) throws 
JsonMappingException {
+            ((ResolvableDeserializer) defaultDeserializer).resolve(ctxt);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java
----------------------------------------------------------------------
diff --git 
a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java 
b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java
index d8f017e..0c8692d 100644
--- a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java
+++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/migrate/OmOld2new.java
@@ -194,10 +194,11 @@ public class OmOld2new extends AbstractObjectVisitor {
             }
         }
 
-        // @hahnml: We need to add the new "declaredExtensions" field to the 
process for
+        // @hahnml: We need to add the new "declaredExtensions" and 
"mustUnderstandExtensions" fields to the process for
         // equality.
         if (old.getClass().getSimpleName().equals("OProcess")) {
             fieldMap.put("declaredExtensions", new HashSet<OExtension>());
+            fieldMap.put("mustUnderstandExtensions", new 
HashSet<OExtension>());
         }
 
         n.setClassVersion(1);

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java
----------------------------------------------------------------------
diff --git 
a/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java
 
b/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java
index f2b80df..1f40dc2 100644
--- 
a/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java
+++ 
b/bpel-rest-extensions/src/main/java/org/apache/ode/bpel/extension/bpel4restlight/Bpel4RestLightOperation.java
@@ -16,10 +16,10 @@ package org.apache.ode.bpel.extension.bpel4restlight;
 
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.eapi.ExtensionContext;
-import org.apache.ode.bpel.eapi.ExtensionOperation;
 import org.apache.ode.bpel.extension.bpel4restlight.http.HighLevelRestApi;
 import org.apache.ode.bpel.extension.bpel4restlight.http.HttpMethod;
 import org.apache.ode.bpel.extension.bpel4restlight.http.HttpResponseMessage;
+import org.apache.ode.bpel.runtime.extension.AbstractSyncExtensionOperation;
 import org.w3c.dom.Element;
 
 /**
@@ -30,9 +30,9 @@ import org.w3c.dom.Element;
  * @author Michael Hahn ([email protected])
  * 
  */
-public class Bpel4RestLightOperation implements ExtensionOperation {
+public class Bpel4RestLightOperation extends AbstractSyncExtensionOperation {
 
-    public void run(ExtensionContext context, Element element) throws 
FaultException {
+    public void runSync(ExtensionContext context, Element element) throws 
FaultException {
         String httpMethod = element.getLocalName();
 
         // Extract requestUri

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
index 60f5e34..990d79d 100644
--- a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
+++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
@@ -129,8 +129,6 @@ public class BpelProcess {
     ExpressionLanguageRuntimeRegistry _expLangRuntimeRegistry;
     private ReplacementMap _replacementMap;
     final ProcessConf _pconf;
-
-    Set<String> _mustUnderstandExtensions;
     
     /** {@link MessageExchangeInterceptor}s registered for this process. */
     private final List<MessageExchangeInterceptor> _mexInterceptors = new 
ArrayList<MessageExchangeInterceptor>();
@@ -960,7 +958,6 @@ public class BpelProcess {
 //            }
             _replacementMap = null;
             _expLangRuntimeRegistry = null;
-            _mustUnderstandExtensions = null;
         }
 
         private void doHydrate() {
@@ -1004,16 +1001,13 @@ public class BpelProcess {
 
             // Checking for registered extension bundles, throw an exception 
when
             // a "mustUnderstand" extension is not available
-            _mustUnderstandExtensions = new HashSet<String>();
-            for (OProcess.OExtension extension : 
_oprocess.getDeclaredExtensions()) {
+            for (OProcess.OExtension extension : 
_oprocess.getMustUnderstandExtensions()) {
                 if (extension.isMustUnderstand()) {
                     if 
(_engine._contexts.extensionRegistry.get(extension.getNamespace()) == null) {
                         String msg = 
__msgs.msgExtensionMustUnderstandError(_pid,
                                 extension.getNamespace());
                         __log.error(msg);
                         throw new BpelEngineException(msg);
-                    } else {
-                        
_mustUnderstandExtensions.add(extension.getNamespace());
                     }
                 } else {
                     __log.warn("The process declares the extension namespace "

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
index 5a576de..9f916cc 100644
--- 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
@@ -37,7 +37,6 @@ import org.apache.ode.bpel.common.CorrelationKey;
 import org.apache.ode.bpel.common.CorrelationKeySet;
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.common.ProcessState;
-import org.apache.ode.bpel.compiler.bom.ExtensibilityQNames;
 import org.apache.ode.bpel.dao.CorrelationSetDAO;
 import org.apache.ode.bpel.dao.CorrelatorDAO;
 import org.apache.ode.bpel.dao.MessageDAO;
@@ -50,7 +49,6 @@ import org.apache.ode.bpel.dao.ScopeDAO;
 import org.apache.ode.bpel.dao.ScopeStateEnum;
 import org.apache.ode.bpel.dao.XmlDataDAO;
 import org.apache.ode.bpel.eapi.AbstractExtensionBundle;
-import org.apache.ode.bpel.eapi.ExtensionContext;
 import org.apache.ode.bpel.eapi.ExtensionOperation;
 import org.apache.ode.bpel.evar.ExternalVariableModule.Value;
 import org.apache.ode.bpel.evar.ExternalVariableModuleException;
@@ -93,7 +91,6 @@ import org.apache.ode.bpel.runtime.PartnerLinkInstance;
 import org.apache.ode.bpel.runtime.Selector;
 import org.apache.ode.bpel.runtime.VariableInstance;
 import org.apache.ode.bpel.runtime.channels.ActivityRecovery;
-import org.apache.ode.bpel.runtime.channels.ExtensionResponse;
 import org.apache.ode.bpel.runtime.channels.FaultData;
 import org.apache.ode.bpel.runtime.channels.InvokeResponse;
 import org.apache.ode.bpel.runtime.channels.PickResponse;
@@ -1537,56 +1534,7 @@ public class BpelRuntimeContextImpl implements 
BpelRuntimeContext {
         _forceFlush = true;
     }
 
-    public void executeExtension(QName extensionId, ExtensionContext context, 
Element element,
-            ExtensionResponse extResponseChannel) throws FaultException {
-        __log.debug("Execute extension activity");
-        final String extResponseChannelStr = 
ProcessUtil.exportChannel(extResponseChannel);
-
-        ExtensionOperation ea = 
createExtensionActivityImplementation(extensionId);
-        if (ea == null) {
-            if 
(_bpelProcess._mustUnderstandExtensions.contains(extensionId.getNamespaceURI()))
 {
-                // TODO
-                __log.warn("Lookup of extension activity " + extensionId + " 
failed.");
-                throw new 
FaultException(ExtensibilityQNames.UNKNOWN_EO_FAULT_NAME,
-                        "Lookup of extension operation " + extensionId + " 
failed.");
-            } else {
-                // act like <empty> - do nothing
-                completeExtensionExecution(extResponseChannelStr, null);
-                return;
-            }
-        }
-
-        try {
-            // should be running in a pooled thread
-            ea.run(context, element);
-            completeExtensionExecution(extResponseChannelStr, null);
-        } catch (RuntimeException e) {
-            __log.error("Error during execution of extension activity.", e);
-            completeExtensionExecution(extResponseChannelStr, e);
-        }
-    }
-
-       private void completeExtensionExecution(final String channelId, final 
Throwable t) {
-               if (t != null) {
-               _vpu.inject(new BpelJacobRunnable() {
-                   private static final long serialVersionUID = -1L;
-
-                   public void run() {
-                      importChannel(channelId, 
ExtensionResponse.class).onFailure(t);
-                   }
-               });
-               } else {
-               _vpu.inject(new BpelJacobRunnable() {
-                   private static final long serialVersionUID = -1L;
-
-                   public void run() {
-                      importChannel(channelId, 
ExtensionResponse.class).onCompleted();
-                   }
-               });
-               }
-       }
-
-       private ExtensionOperation createExtensionActivityImplementation(QName 
name) {
+       public ExtensionOperation createExtensionActivityImplementation(QName 
name) {
                if (name == null) {
                        return null;
                }

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java
----------------------------------------------------------------------
diff --git a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java
index 53e25be..3290958 100644
--- a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java
+++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ASSIGN.java
@@ -19,8 +19,6 @@
 package org.apache.ode.bpel.runtime;
 
 import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.net.URI;
 import java.util.Calendar;
 import java.util.Date;
@@ -32,6 +30,7 @@ import javax.xml.namespace.QName;
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.compiler.bom.ExtensibilityQNames;
 import org.apache.ode.bpel.eapi.ExtensionContext;
+import org.apache.ode.bpel.eapi.ExtensionOperation;
 import org.apache.ode.bpel.evar.ExternalVariableModuleException;
 import org.apache.ode.bpel.evt.PartnerLinkModificationEvent;
 import org.apache.ode.bpel.evt.ScopeEvent;
@@ -51,9 +50,7 @@ import org.apache.ode.bpel.obj.OMessageVarType.Part;
 import org.apache.ode.bpel.obj.OProcess.OProperty;
 import org.apache.ode.bpel.obj.OScope;
 import org.apache.ode.bpel.obj.OScope.Variable;
-import org.apache.ode.bpel.runtime.channels.ExtensionResponse;
 import org.apache.ode.bpel.runtime.channels.FaultData;
-import org.apache.ode.jacob.ReceiveProcess;
 import org.apache.ode.utils.DOMUtils;
 import org.apache.ode.utils.Namespaces;
 import org.apache.ode.utils.msg.MessageBundle;
@@ -679,49 +676,47 @@ class ASSIGN extends ACTIVITY {
 
     private void 
invokeExtensionAssignOperation(OAssign.ExtensionAssignOperation eao)
             throws FaultException {
-        try {
-            final ExtensionContext helper =
-                    new ExtensionContextImpl(this._scopeFrame, 
getBpelRuntimeContext());
-            final ExtensionResponse responseChannel = 
newChannel(ExtensionResponse.class);
-
-            getBpelRuntimeContext().executeExtension(eao.getExtensionName(), 
helper,
-                    DOMUtils.stringToDOM(eao.getNestedElement()), 
responseChannel);
-
-            object(new ReceiveProcess() {
-                private static final long serialVersionUID = 
1467660715539203917L;
-            }.setChannel(responseChannel).setReceiver(new ExtensionResponse() {
-                private static final long serialVersionUID = 
509910466826372712L;
+        final ExtensionContext context =
+                new ExtensionContextImpl(this._self, this._scopeFrame, 
getBpelRuntimeContext());
+        final QName extensionId = eao.getExtensionName();
 
-                public void onCompleted() {
-                    _self.parent.completed(null, 
CompensationHandler.emptySet());
+        try {
+            ExtensionOperation ea =
+                    
getBpelRuntimeContext().createExtensionActivityImplementation(extensionId);
+            if (ea == null) {
+                if 
(eao.getOwner().hasMustUnderstandExtension(extensionId.getNamespaceURI())) {
+                    __log.warn("Lookup of extension activity " + extensionId + 
" failed.");
+                    throw new 
FaultException(ExtensibilityQNames.UNKNOWN_EA_FAULT_NAME,
+                            "Lookup of extension assign operation " + 
extensionId
+                                    + " failed. No implementation found.");
+                } else {
+                    // act like <empty> - do nothing
+                    context.complete();
+                    return;
                 }
+            }
 
-                public void onFailure(Throwable t) {
-                    StringWriter sw = new StringWriter();
-                    t.printStackTrace(new PrintWriter(sw));
-                    FaultData fault = createFault(
-                            
_self.o.getOwner().getConstants().getQnSubLanguageExecutionFault(),
-                            _self.o, sw.getBuffer().toString());
-                    _self.parent.completed(fault, 
CompensationHandler.emptySet());
-                };
-            }));
+            ea.run(context, DOMUtils.stringToDOM(eao.getNestedElement()));
 
         } catch (FaultException fault) {
             __log.error("Exception while invoking extension assign operation", 
fault);
-            FaultData faultData = createFault(fault.getQName(), _self.o, 
fault.getMessage());
-            _self.parent.completed(faultData, CompensationHandler.emptySet());
+            context.completeWithFault(fault);
         } catch (SAXException e) {
-            __log.error("Exception while invoking extension assign operation", 
e);
-            FaultData faultData = 
createFault(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT,
-                    _self.o, "The nested element of extension assign operation 
'"
-                            + eao.getExtensionName() + "' is no valid XML.");
-            _self.parent.completed(faultData, CompensationHandler.emptySet());
+            __log.error("Exception while invoking extension assign operation",
+                    e);
+            FaultException faultData =
+                    new 
FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT,
+                            "The nested element of extension assign operation 
'"
+                                    + eao.getExtensionName() + "' is no valid 
XML.", e);
+            context.completeWithFault(faultData);
         } catch (IOException e) {
-            __log.error("Exception while invoking extension assign operation", 
e);
-            FaultData faultData = 
createFault(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT,
-                    _self.o, "The nested element of extension assign operation 
'"
-                            + eao.getExtensionName() + "' is no valid XML.");
-            _self.parent.completed(faultData, CompensationHandler.emptySet());
+            __log.error("Exception while invoking extension assign operation",
+                    e);
+            FaultException faultData =
+                    new 
FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT,
+                            "The nested element of extension assign operation 
'"
+                                    + eao.getExtensionName() + "' is no valid 
XML.", e);
+            context.completeWithFault(faultData);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java
index 30b318a..82891e8 100644
--- 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java
@@ -27,7 +27,7 @@ import javax.xml.namespace.QName;
 
 import org.apache.ode.bpel.common.CorrelationKey;
 import org.apache.ode.bpel.common.FaultException;
-import org.apache.ode.bpel.eapi.ExtensionContext;
+import org.apache.ode.bpel.eapi.ExtensionOperation;
 import org.apache.ode.bpel.evar.ExternalVariableModuleException;
 import org.apache.ode.bpel.evt.ProcessInstanceEvent;
 import org.apache.ode.bpel.iapi.ProcessConf.PartnerRoleConfig;
@@ -36,7 +36,6 @@ import org.apache.ode.bpel.obj.OProcess;
 import org.apache.ode.bpel.obj.OScope;
 import org.apache.ode.bpel.obj.OScope.Variable;
 import org.apache.ode.bpel.runtime.channels.ActivityRecovery;
-import org.apache.ode.bpel.runtime.channels.ExtensionResponse;
 import org.apache.ode.bpel.runtime.channels.FaultData;
 import org.apache.ode.bpel.runtime.channels.InvokeResponse;
 import org.apache.ode.bpel.runtime.channels.PickResponse;
@@ -314,5 +313,5 @@ public interface BpelRuntimeContext {
     
     void checkInvokeExternalPermission();
     
-    void executeExtension(QName extensionId, ExtensionContext context, Element 
element, ExtensionResponse extResponseChannel) throws FaultException;
+    ExtensionOperation createExtensionActivityImplementation(QName name);
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java
index dfa5771..3f378ba 100644
--- 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java
@@ -15,16 +15,14 @@
 package org.apache.ode.bpel.runtime;
 
 import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
+
+import javax.xml.namespace.QName;
 
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.compiler.bom.ExtensibilityQNames;
 import org.apache.ode.bpel.eapi.ExtensionContext;
+import org.apache.ode.bpel.eapi.ExtensionOperation;
 import org.apache.ode.bpel.obj.OExtensionActivity;
-import org.apache.ode.bpel.runtime.channels.ExtensionResponse;
-import org.apache.ode.bpel.runtime.channels.FaultData;
-import org.apache.ode.jacob.ReceiveProcess;
 import org.apache.ode.utils.DOMUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,56 +46,48 @@ public class EXTENSIONACTIVITY extends ACTIVITY {
     }
 
     public final void run() {
+        final ExtensionContext context =
+                new ExtensionContextImpl(_self, _scopeFrame, 
getBpelRuntimeContext());
+        final QName extensionId = _oext.getExtensionName();
         try {
-            final ExtensionResponse responseChannel = 
newChannel(ExtensionResponse.class);
-            final ExtensionContext helper =
-                    new ExtensionContextImpl(_scopeFrame, 
getBpelRuntimeContext());
-
-            getBpelRuntimeContext().executeExtension(_oext.getExtensionName(), 
helper,
-                    DOMUtils.stringToDOM(_oext.getNestedElement()), 
responseChannel);
-
-            object(new ReceiveProcess() {
-                private static final long serialVersionUID = 
3643564901004147956L;
-            }.setChannel(responseChannel).setReceiver(new ExtensionResponse() {
-                private static final long serialVersionUID = 
-6977609968638662977L;
-
-                public void onCompleted() {
-                    _self.parent.completed(null, 
CompensationHandler.emptySet());
+            ExtensionOperation ea =
+                    
getBpelRuntimeContext().createExtensionActivityImplementation(extensionId);
+            if (ea == null) {
+                if 
(_oext.getOwner().hasMustUnderstandExtension(extensionId.getNamespaceURI())) {
+                    __log.warn("Lookup of extension activity " + extensionId + 
" failed.");
+                    throw new 
FaultException(ExtensibilityQNames.UNKNOWN_EA_FAULT_NAME,
+                            "Lookup of extension activity " + extensionId
+                                    + " failed. No implementation found.");
+                } else {
+                    // act like <empty> - do nothing
+                    context.complete();
+                    return;
                 }
+            }
 
-                public void onFailure(Throwable t) {
-                    StringWriter sw = new StringWriter();
-                    t.printStackTrace(new PrintWriter(sw));
-                    FaultData fault = createFault(
-                            
_oext.getOwner().getConstants().getQnSubLanguageExecutionFault(), _oext,
-                            sw.getBuffer().toString());
-                    _self.parent.completed(fault, 
CompensationHandler.emptySet());
-                };
-            }));
-
+            ea.run(context, DOMUtils.stringToDOM(_oext.getNestedElement()));
         } catch (FaultException fault) {
             __log.error("Exception while invoking extension activity '" + 
_oext.getName() + "'.",
                     fault);
-            FaultData faultData = createFault(fault.getQName(), _oext, 
fault.getMessage());
-            _self.parent.completed(faultData, CompensationHandler.emptySet());
+            context.completeWithFault(fault);
         } catch (SAXException e) {
             __log.error("Exception while invoking extension activity '" + 
_oext.getName() + "'.",
                     e);
-            FaultData faultData =
-                    createFault(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, 
_self.o,
+            FaultException faultData =
+                    new 
FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT,
                             "The nested element of extension activity '" + 
_oext.getName()
                                     + "' for extension '" + 
_oext.getExtensionName()
-                                    + "' is no valid XML.");
-            _self.parent.completed(faultData, CompensationHandler.emptySet());
+                                    + "' is no valid XML.", e);
+            context.completeWithFault(faultData);
         } catch (IOException e) {
             __log.error("Exception while invoking extension activity '" + 
_oext.getName() + "'.",
                     e);
-            FaultData faultData =
-                    createFault(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, 
_self.o,
+            FaultException faultData =
+                    new 
FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT,
                             "The nested element of extension activity '" + 
_oext.getName()
                                     + "' for extension '" + 
_oext.getExtensionName()
-                                    + "' is no valid XML.");
-            _self.parent.completed(faultData, CompensationHandler.emptySet());
+                                    + "' is no valid XML.", e);
+            context.completeWithFault(faultData);
         }
 
     }

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java
index 9e69dc7..6dc846c 100644
--- 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java
@@ -14,27 +14,45 @@
  */
 package org.apache.ode.bpel.runtime;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.namespace.QName;
+
 import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.compiler.bom.Bpel20QNames;
 import org.apache.ode.bpel.eapi.ExtensionContext;
+import org.apache.ode.bpel.evt.ScopeEvent;
+import org.apache.ode.bpel.evt.VariableModificationEvent;
 import org.apache.ode.bpel.obj.OActivity;
 import org.apache.ode.bpel.obj.OLink;
 import org.apache.ode.bpel.obj.OProcess.OProperty;
 import org.apache.ode.bpel.obj.OScope;
 import org.apache.ode.bpel.obj.OScope.Variable;
+import org.apache.ode.bpel.runtime.channels.FaultData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.Node;
 
 /**
  * @author Tammo van Lessen (University of Stuttgart)
  */
 public class ExtensionContextImpl implements ExtensionContext {
+
+    private static final Logger __log = 
LoggerFactory.getLogger(ExtensionContextImpl.class);
+
     private BpelRuntimeContext _context;
     private ScopeFrame _scopeFrame;
+    private ActivityInfo _activityInfo;
+
+    private boolean hasCompleted = false;
 
-    public ExtensionContextImpl(ScopeFrame scopeFrame, BpelRuntimeContext 
context) {
+    public ExtensionContextImpl(ActivityInfo activityInfo, ScopeFrame 
scopeFrame,
+            BpelRuntimeContext context) {
+        _activityInfo = activityInfo;
         _context = context;
         _scopeFrame = scopeFrame;
     }
@@ -48,6 +66,14 @@ public class ExtensionContextImpl implements 
ExtensionContext {
         return _context.getPid();
     }
 
+    public String getActivityName() {
+        return _activityInfo.o.getName();
+    }
+
+    public OActivity getOActivity() {
+        return _activityInfo.o;
+    }
+
     public Map<String, OScope.Variable> getVisibleVariables() throws 
FaultException {
         Map<String, OScope.Variable> visVars = new HashMap<String, 
OScope.Variable>();
 
@@ -66,11 +92,6 @@ public class ExtensionContextImpl implements 
ExtensionContext {
         return visVars;
     }
 
-    public boolean isLinkActive(OLink olink) throws FaultException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
     public String readMessageProperty(Variable variable, OProperty property) 
throws FaultException {
         VariableInstance vi = _scopeFrame.resolve(variable);
         return _context.readProperty(vi, property);
@@ -84,6 +105,10 @@ public class ExtensionContextImpl implements 
ExtensionContext {
     public void writeVariable(String variableName, Node value) throws 
FaultException {
         VariableInstance vi = 
_scopeFrame.resolve(getVisibleVariable(variableName));
         _context.writeVariable(vi, value);
+
+        VariableModificationEvent vme = new 
VariableModificationEvent(variableName);
+        vme.setNewValue(value);
+        sendEvent(vme);
     }
 
     public Node readVariable(String variableName) throws FaultException {
@@ -99,4 +124,60 @@ public class ExtensionContextImpl implements 
ExtensionContext {
     private Variable getVisibleVariable(String varName) {
         return _scopeFrame.oscope.getVisibleVariable(varName);
     }
+
+    public BpelRuntimeContext getBpelRuntimeContext() {
+        return _context;
+    }
+
+    public void sendEvent(ScopeEvent event) {
+        if (event.getLineNo() == -1 && _activityInfo.o.getDebugInfo() != null) 
{
+            event.setLineNo(_activityInfo.o.getDebugInfo().getStartLine());
+        }
+        _scopeFrame.fillEventInfo(event);
+        getBpelRuntimeContext().sendEvent(event);
+    }
+
+    public void complete() {
+        if (!hasCompleted) {
+            _activityInfo.parent.completed(null, 
CompensationHandler.emptySet());
+            hasCompleted = true;
+        } else {
+            if (__log.isWarnEnabled()) {
+                __log.warn(
+                        "Activity '" + _activityInfo.o.getName() + "' has 
already been completed.");
+            }
+        }
+    }
+
+    public void completeWithFault(Throwable t) {
+        if (!hasCompleted) {
+            StringWriter sw = new StringWriter();
+            t.printStackTrace(new PrintWriter(sw));
+            FaultData fault =
+                    new FaultData(new QName(Bpel20QNames.NS_WSBPEL2_0, 
"subLanguageExecutionFault"),
+                            _activityInfo.o, sw.getBuffer().toString());
+            _activityInfo.parent.completed(fault, 
CompensationHandler.emptySet());
+            hasCompleted = true;
+        } else {
+            if (__log.isWarnEnabled()) {
+                __log.warn(
+                        "Activity '" + _activityInfo.o.getName() + "' has 
already been completed.");
+            }
+        }
+    }
+
+    public void completeWithFault(FaultException ex) {
+        if (!hasCompleted) {
+            FaultData fault = new FaultData(ex.getQName(), _activityInfo.o, 
ex.getMessage());
+            _activityInfo.parent.completed(fault, 
CompensationHandler.emptySet());
+            hasCompleted = true;
+        } else {
+            if (__log.isWarnEnabled()) {
+                __log.warn(
+                        "Activity '" + _activityInfo.o.getName() + "' has 
already been completed.");
+            }
+        }
+
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/channels/ExtensionResponse.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/channels/ExtensionResponse.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/channels/ExtensionResponse.java
deleted file mode 100644
index faf4e5f..0000000
--- 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/channels/ExtensionResponse.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-package org.apache.ode.bpel.runtime.channels;
-
-import org.apache.ode.jacob.Channel;
-
-/**
- * Response channel for extension activity executions.
- *
- * @author Tammo van Lessen (University of Stuttgart)
- */
-public interface ExtensionResponse extends Channel {
-
-    void onCompleted();
-
-    void onFailure(Throwable t);
-
-}

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractAsyncExtensionOperation.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractAsyncExtensionOperation.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractAsyncExtensionOperation.java
new file mode 100644
index 0000000..2167538
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractAsyncExtensionOperation.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package org.apache.ode.bpel.runtime.extension;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.eapi.ExtensionContext;
+import org.apache.ode.bpel.eapi.ExtensionOperation;
+
+/**
+ * Base class for creating new asynchronous extension implementations.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public abstract class AbstractAsyncExtensionOperation implements 
ExtensionOperation {
+
+    public abstract void run(ExtensionContext context, String element)
+            throws FaultException;
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractSyncExtensionOperation.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractSyncExtensionOperation.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractSyncExtensionOperation.java
new file mode 100644
index 0000000..3e463ad
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/extension/AbstractSyncExtensionOperation.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+package org.apache.ode.bpel.runtime.extension;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.eapi.ExtensionContext;
+import org.apache.ode.bpel.eapi.ExtensionOperation;
+import org.w3c.dom.Element;
+
+/**
+ * Base class for creating new extension implementations.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public abstract class AbstractSyncExtensionOperation implements 
ExtensionOperation {
+
+    protected abstract void runSync(ExtensionContext context, Element element) 
throws FaultException;
+    
+    public void run(ExtensionContext context, Element element)
+            throws FaultException {
+        try {
+            runSync(context, element);
+            context.complete();
+        } catch (FaultException f) {
+            context.completeWithFault(f);
+        } catch (Exception e) {
+            context.completeWithFault(e);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java 
b/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java
index aa3a871..afc6d9e 100644
--- a/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java
+++ b/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java
@@ -28,13 +28,11 @@ import java.util.HashMap;
 import javax.wsdl.Operation;
 import javax.xml.namespace.QName;
 
-import junit.framework.TestCase;
-
 import org.apache.ode.bpel.common.CorrelationKey;
 import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.eapi.ExtensionOperation;
 import org.apache.ode.bpel.evar.ExternalVariableModuleException;
 import org.apache.ode.bpel.evt.ProcessInstanceEvent;
-import org.apache.ode.bpel.eapi.ExtensionContext;
 import org.apache.ode.bpel.iapi.ProcessConf.PartnerRoleConfig;
 import org.apache.ode.bpel.obj.OCatch;
 import org.apache.ode.bpel.obj.OEmpty;
@@ -49,7 +47,6 @@ import org.apache.ode.bpel.obj.OScope.Variable;
 import org.apache.ode.bpel.obj.OSequence;
 import org.apache.ode.bpel.obj.OThrow;
 import org.apache.ode.bpel.runtime.channels.ActivityRecovery;
-import org.apache.ode.bpel.runtime.channels.ExtensionResponse;
 import org.apache.ode.bpel.runtime.channels.FaultData;
 import org.apache.ode.bpel.runtime.channels.InvokeResponse;
 import org.apache.ode.bpel.runtime.channels.PickResponse;
@@ -59,6 +56,8 @@ import org.apache.ode.jacob.vpu.JacobVPU;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
+import junit.framework.TestCase;
+
 /**
  * Test core BPEL processing capabilities.
  */
@@ -482,9 +481,8 @@ public class CoreBpelTest extends TestCase implements 
BpelRuntimeContext {
 
     public void checkInvokeExternalPermission() {}
 
-    public void executeExtension(QName extensionId, ExtensionContext context, 
Element element,
-            ExtensionResponse extResponseChannel) throws FaultException {
+    public ExtensionOperation createExtensionActivityImplementation(QName 
name) {
         // TODO Auto-generated method stub
-
+        return null;
     }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/28503b88/bpel-test/src/main/java/org/apache/ode/test/MockExtensionContext.java
----------------------------------------------------------------------
diff --git 
a/bpel-test/src/main/java/org/apache/ode/test/MockExtensionContext.java 
b/bpel-test/src/main/java/org/apache/ode/test/MockExtensionContext.java
new file mode 100644
index 0000000..07b9eb8
--- /dev/null
+++ b/bpel-test/src/main/java/org/apache/ode/test/MockExtensionContext.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+package org.apache.ode.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.eapi.ExtensionContext;
+import org.apache.ode.bpel.obj.OActivity;
+import org.apache.ode.bpel.obj.OProcess.OProperty;
+import org.apache.ode.bpel.obj.OScope.Variable;
+import org.apache.ode.bpel.runtime.BpelRuntimeContext;
+import org.apache.ode.utils.DOMUtils;
+import org.w3c.dom.Node;
+
+/**
+ * Very simple mock implementation of the ExtensionContext interface.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class MockExtensionContext implements ExtensionContext {
+    private Map<String, Node> variables = new HashMap<String, Node>();
+    public boolean completed;
+    public boolean faulted;
+    
+    public Map<String, Node> getVariables() {
+        return variables;
+    }
+    
+    public Long getProcessId() {
+        return 0L;
+    }
+
+    public Node readVariable(String variableName) throws FaultException {
+        System.out.println("Reading " + variableName);
+        return variables.get(variableName);
+    }
+
+    public void writeVariable(String variableName, Node value)
+            throws FaultException {
+        variables.put(variableName, value);
+        System.out.println("Storing in " + variableName + ": " + 
DOMUtils.domToString(value));
+    }
+
+    public String getActivityName() {
+        return "mockActivity";
+    }
+    
+    public OActivity getOActivity() {
+        throw new UnsupportedOperationException("This method is not available 
in this mock implementation.");
+    }
+    
+    public BpelRuntimeContext getBpelRuntimeContext() {
+        throw new UnsupportedOperationException("This method is not available 
in this mock implementation.");
+    }
+    
+    public Map<String, Variable> getVisibleVariables()
+        throws FaultException {
+        throw new UnsupportedOperationException("This method is not available 
in this mock implementation.");
+    }
+    
+    public String readMessageProperty(Variable variable, OProperty property)
+        throws FaultException {
+        throw new UnsupportedOperationException("This method is not available 
in this mock implementation.");
+    }
+    
+    public Node readVariable(Variable variable) throws FaultException {
+        throw new UnsupportedOperationException("This method is not available 
in this mock implementation.");
+    }
+    
+    public void writeVariable(Variable variable, Node value) throws 
FaultException {
+        throw new UnsupportedOperationException("This method is not available 
in this mock implementation.");
+    }
+
+    public void complete() {
+        this.completed = true;
+    }
+
+    public void completeWithFault(Throwable t) {
+        this.completed = true;
+        this.faulted = true;
+    }
+
+    public void completeWithFault(FaultException fault) {
+        this.completed = true;
+        this.faulted = true;
+    }
+    
+}
\ No newline at end of file

Reply via email to