Repository: ode
Updated Branches:
  refs/heads/master 881a96e41 -> a5da5e58a


http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/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 0150c97..9208136 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
@@ -19,7 +19,6 @@
 package org.apache.ode.bpel.engine;
 
 import java.io.File;
-import java.io.InputStream;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -52,6 +51,7 @@ import 
org.apache.ode.bpel.engine.extvar.ExternalVariableManager;
 import org.apache.ode.bpel.evt.ProcessInstanceEvent;
 import org.apache.ode.bpel.explang.ConfigurationException;
 import org.apache.ode.bpel.explang.EvaluationException;
+import org.apache.ode.bpel.extension.ExtensionBundleRuntime;
 import org.apache.ode.bpel.iapi.BpelEngineException;
 import org.apache.ode.bpel.iapi.Endpoint;
 import org.apache.ode.bpel.iapi.EndpointReference;
@@ -131,6 +131,9 @@ public class BpelProcess {
     private ReplacementMap _replacementMap;
     final ProcessConf _pconf;
 
+       Set<String> _mustUnderstandExtensions;
+       Map<String, ExtensionBundleRuntime> _extensionRegistry;
+    
     /** {@link MessageExchangeInterceptor}s registered for this process. */
     private final List<MessageExchangeInterceptor> _mexInterceptors = new 
ArrayList<MessageExchangeInterceptor>();
 
@@ -588,6 +591,10 @@ public class BpelProcess {
         return routed;
     }
 
+       public void setExtensionRegistry(Map<String, ExtensionBundleRuntime> 
extensionRegistry) {
+               _extensionRegistry = extensionRegistry;
+       }
+    
     private void setRoles(OProcess oprocess) {
         _partnerRoles = new HashMap<OPartnerLink, 
PartnerLinkPartnerRoleImpl>();
         _myRoles = new HashMap<OPartnerLink, PartnerLinkMyRoleImpl>();
@@ -959,6 +966,7 @@ public class BpelProcess {
 //            }
             _replacementMap = null;
             _expLangRuntimeRegistry = null;
+           _extensionRegistry = null;
         }
 
         private void doHydrate() {
@@ -1000,6 +1008,25 @@ public class BpelProcess {
             _expLangRuntimeRegistry = new ExpressionLanguageRuntimeRegistry();
             registerExprLang(_oprocess);
 
+                       // 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()) {
+                               if (extension.isMustUnderstand()) {
+                                       if 
(_extensionRegistry.get(extension.getNamespace()) == null) {
+                                               String msg = 
__msgs.msgExtensionMustUnderstandError(_pconf.getProcessId(),
+                                                               
extension.getNamespace());
+                                               __log.error(msg);
+                                               throw new 
BpelEngineException(msg);
+                                       } else {
+                                               
_mustUnderstandExtensions.add(extension.getNamespace());
+                                       }
+                               } else {
+                                       __log.warn("The process declares the 
extension namespace " + extension.getNamespace()
+                                                       + " that is unkown to 
the engine");
+                               }
+                       }
+
             setRoles(_oprocess);
             initExternalVariables();
 

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/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 f4c9fec..1457a80 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
@@ -60,6 +60,8 @@ import org.apache.ode.bpel.evt.ScopeCompletionEvent;
 import org.apache.ode.bpel.evt.ScopeEvent;
 import org.apache.ode.bpel.evt.ScopeFaultEvent;
 import org.apache.ode.bpel.evt.ScopeStartEvent;
+import org.apache.ode.bpel.extension.ExtensionBundleRuntime;
+import org.apache.ode.bpel.extension.ExtensionOperation;
 import org.apache.ode.bpel.iapi.BpelEngineException;
 import org.apache.ode.bpel.iapi.ContextException;
 import org.apache.ode.bpel.iapi.Endpoint;
@@ -1531,4 +1533,18 @@ public class BpelRuntimeContextImpl implements 
BpelRuntimeContext {
     public void forceFlush() {
         _forceFlush = true;
     }
+
+       public ExtensionOperation createExtensionActivityImplementation(QName 
name) {
+               if (name == null) return null;
+        ExtensionBundleRuntime bundle = 
_bpelProcess._extensionRegistry.get(name.getNamespaceURI());
+        if (bundle == null) {
+            return null;
+        } else {
+            try {
+                return 
bundle.getExtensionOperationInstance(name.getLocalPart());
+            } catch (Exception e) {
+                return null;
+            }
+        }
+       }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java
index 3966fc1..ffb805c 100644
--- a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java
+++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java
@@ -44,6 +44,7 @@ import org.apache.ode.bpel.engine.cron.CronScheduler;
 import org.apache.ode.bpel.engine.migration.MigrationHandler;
 import org.apache.ode.bpel.evar.ExternalVariableModule;
 import org.apache.ode.bpel.evt.BpelEvent;
+import org.apache.ode.bpel.extension.ExtensionBundleRuntime;
 import org.apache.ode.bpel.iapi.BindingContext;
 import org.apache.ode.bpel.iapi.BpelEngine;
 import org.apache.ode.bpel.iapi.BpelEngineException;
@@ -175,6 +176,15 @@ public class BpelServerImpl implements BpelServer, 
Scheduler.JobProcessor {
         }
     }
 
+    public void registerExtensionBundle(ExtensionBundleRuntime bundle) {
+        _contexts.extensionRegistry.put(bundle.getNamespaceURI(), bundle);
+        bundle.registerExtensionActivities();
+    }
+
+    public void unregisterExtensionBundle(String nsURI) {
+        _contexts.extensionRegistry.remove(nsURI);
+    }
+
     public void registerExternalVariableEngine(ExternalVariableModule eve) {
         _contexts.externalVariableEngines.put(eve.getName(), eve);
     }
@@ -317,6 +327,8 @@ public class BpelServerImpl implements BpelServer, 
Scheduler.JobProcessor {
             __log.debug("Registering process " + conf.getProcessId() + " with 
server.");
 
             BpelProcess process = createBpelProcess(conf);
+            
+            process.setExtensionRegistry(_contexts.extensionRegistry);
             process._classLoader = 
Thread.currentThread().getContextClassLoader();
 
             _engine.registerProcess(process);

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java
index a965d58..ce4edd9 100644
--- a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java
+++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java
@@ -29,9 +29,12 @@ import org.apache.ode.bpel.iapi.Scheduler;
 import org.apache.ode.bpel.intercept.MessageExchangeInterceptor;
 import org.apache.ode.bpel.engine.cron.CronScheduler;
 import org.apache.ode.bpel.evar.ExternalVariableModule;
+import org.apache.ode.bpel.extension.ExtensionBundleRuntime;
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.xml.namespace.QName;
@@ -67,4 +70,7 @@ public class Contexts {
     
     public CustomProcessProperties customProcessProperties = new 
CustomProcessProperties(); 
 
+    /** Global extension bundle registry **/
+    final Map<String, ExtensionBundleRuntime> extensionRegistry = new 
ConcurrentHashMap<String, ExtensionBundleRuntime>();
+
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Messages.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Messages.java 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Messages.java
index 20f0fd8..35dac34 100644
--- a/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Messages.java
+++ b/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Messages.java
@@ -191,4 +191,9 @@ public class Messages extends MessageBundle {
         return format("Scheduled job failed; jobDetail={0}", jobDetail);
     }
 
+    public String msgExtensionMustUnderstandError(QName name, String 
extensionUri) {
+        return format("Deployment of process \"{0}\" failed. The process model 
requires the " +
+                       "engine to understand language extensions defined by 
{1}. No extension bundle " +
+                       "has been registered for this namespace.", name, 
extensionUri);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/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 0f442b9..ca442a0 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
@@ -26,6 +26,7 @@ import org.apache.ode.bpel.evt.ScopeEvent;
 import org.apache.ode.bpel.evt.VariableModificationEvent;
 import org.apache.ode.bpel.explang.EvaluationContext;
 import org.apache.ode.bpel.explang.EvaluationException;
+import org.apache.ode.bpel.extension.ExtensionOperation;
 import org.apache.ode.bpel.obj.OAssign;
 import org.apache.ode.bpel.obj.OAssign.DirectRef;
 import org.apache.ode.bpel.obj.OAssign.LValueExpression;
@@ -36,10 +37,13 @@ import org.apache.ode.bpel.obj.OExpression;
 import org.apache.ode.bpel.obj.OLink;
 import org.apache.ode.bpel.obj.OMessageVarType;
 import org.apache.ode.bpel.obj.OMessageVarType.Part;
+import org.apache.ode.bpel.obj.OProcess;
 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.apache.ode.bpel.runtime.common.extension.ExtensibilityQNames;
+import org.apache.ode.bpel.runtime.common.extension.ExtensionContext;
 import org.apache.ode.utils.DOMUtils;
 import org.apache.ode.utils.Namespaces;
 import org.apache.ode.utils.msg.MessageBundle;
@@ -82,23 +86,36 @@ class ASSIGN extends ACTIVITY {
 
         FaultData faultData = null;
 
-        for (OAssign.Copy aCopy : oassign.getCopy()) {
+               for (OAssign.OAssignOperation operation : 
oassign.getOperations()) {
             try {
-                copy(aCopy);
+                if (operation instanceof OAssign.Copy) {
+                                       copy((OAssign.Copy) operation);
+                               } else if (operation instanceof 
OAssign.ExtensionAssignOperation) {
+                                       
invokeExtensionAssignOperation((OAssign.ExtensionAssignOperation) operation);
+                               }
             } catch (FaultException fault) {
-                if (aCopy.isIgnoreMissingFromData()) {
-                    if 
(fault.getQName().equals(getOAsssign().getOwner().getConstants().getQnSelectionFailure())
 &&
-                            (fault.getCause() != null && 
"ignoreMissingFromData".equals(fault.getCause().getMessage()))) {
-                    continue;
-                    }
-                }
-                if (aCopy.isIgnoreUninitializedFromVariable()) {
-                    if 
(fault.getQName().equals(getOAsssign().getOwner().getConstants().getQnUninitializedVariable())
 &&
-                            (fault.getCause() == null || 
!"throwUninitializedToVariable".equals(fault.getCause().getMessage()))) {
-                    continue;
-                    }
-                }
-                faultData = createFault(fault.getQName(), aCopy, fault
+               if (operation instanceof OAssign.Copy) {
+                                       if (((OAssign.Copy) 
operation).isIgnoreMissingFromData()) {
+                                               if (fault
+                                                               .getQName()
+                                                               
.equals(getOAsssign().getOwner().getConstants().getQnSelectionFailure())
+                                                               && 
(fault.getCause() != null && "ignoreMissingFromData"
+                                                                               
.equals(fault.getCause().getMessage()))) {
+                                                       continue;
+                                               }
+                                       }
+                                       if (((OAssign.Copy) 
operation).isIgnoreUninitializedFromVariable()) {
+                                               if (fault
+                                                               .getQName()
+                                                               
.equals(getOAsssign().getOwner().getConstants().getQnUninitializedVariable())
+                                                               && 
(fault.getCause() == null || !"throwUninitializedToVariable"
+                                                                               
.equals(fault.getCause().getMessage()))) {
+                                                       continue;
+                                               }
+                                       }
+                               }
+                
+                faultData = createFault(fault.getQName(), operation, fault
                         .getMessage());
                 break;
             } catch (ExternalVariableModuleException e) {
@@ -655,6 +672,35 @@ class ASSIGN extends ACTIVITY {
         return data;
     }
 
+       private void 
invokeExtensionAssignOperation(OAssign.ExtensionAssignOperation eao) throws 
FaultException {
+        final ExtensionContext context = new ExtensionContextImpl(this, 
getBpelRuntimeContext());
+
+        try {
+            ExtensionOperation ea = 
getBpelRuntimeContext().createExtensionActivityImplementation(eao.getExtensionName());
+            if (ea == null) {
+                for (OProcess.OExtension oe : 
eao.getOwner().getMustUnderstandExtensions()) {
+                    if 
(eao.getExtensionName().getNamespaceURI().equals(oe.getNamespace())) {
+                        __log.warn("Lookup of extension assign operation " + 
eao.getExtensionName() + " failed.");
+                        throw new 
FaultException(ExtensibilityQNames.UNKNOWN_EA_FAULT_NAME, "Lookup of extension 
assign operation " + eao.getExtensionName() + " failed. No implementation 
found.");
+                    }
+                }
+                // act like <empty> - do nothing
+                context.complete();
+                return;
+            }
+
+            ea.run(context, DOMUtils.stringToDOM(eao.getNestedElement()));
+        } catch (FaultException fault) {
+            context.completeWithFault(fault);
+        } catch (SAXException e) {
+               FaultException fault = new 
FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, "The nested 
element of extension assign operation '" + eao.getExtensionName() + "' is no 
valid XML.");
+               context.completeWithFault(fault);
+               } catch (IOException e) {
+                       FaultException fault = new 
FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, "The nested 
element of extension assign operation '" + eao.getExtensionName() + "' is no 
valid XML.");
+                       context.completeWithFault(fault);
+               }
+    }
+
     private class EvaluationContextProxy implements EvaluationContext {
 
         private Variable _var;

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ActivityTemplateFactory.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ActivityTemplateFactory.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ActivityTemplateFactory.java
index 1942328..16ece33 100644
--- 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ActivityTemplateFactory.java
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ActivityTemplateFactory.java
@@ -43,6 +43,7 @@ public class ActivityTemplateFactory {
     if (type instanceof OWhile) return new WHILE(ai, scopeFrame, linkFrame);
     if (type instanceof OForEach) return new FOREACH(ai, scopeFrame, 
linkFrame);
     if (type instanceof ORepeatUntil) return new 
REPEATUNTIL(ai,scopeFrame,linkFrame);
+    if (type instanceof OExtensionActivity) return new EXTENSIONACTIVITY(ai, 
scopeFrame, linkFrame);
 
     throw new IllegalArgumentException("Unknown type: " + type);
   }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/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 448af9a..8aad3ec 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
@@ -28,6 +28,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.evt.ProcessInstanceEvent;
+import org.apache.ode.bpel.extension.ExtensionOperation;
 import org.apache.ode.bpel.obj.OPartnerLink;
 import org.apache.ode.bpel.obj.OProcess;
 import org.apache.ode.bpel.obj.OScope;
@@ -311,4 +312,13 @@ public interface BpelRuntimeContext {
     ClassLoader getProcessClassLoader();
     
     void checkInvokeExternalPermission();
+    
+    /**
+     * Create a new extension operation based on the given qualified name.
+     * 
+     * @param name The qualified name for which a corresponding extension 
operation should be created.
+     * 
+     * @return The created extension operation or NULL if no extension bundle 
registered a corresponding extension operation for the given qualified name.
+     */
+    ExtensionOperation createExtensionActivityImplementation(QName name);
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/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
new file mode 100644
index 0000000..7c61035
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EXTENSIONACTIVITY.java
@@ -0,0 +1,98 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.extension.ExtensionOperation;
+import org.apache.ode.bpel.obj.OExtensionActivity;
+import org.apache.ode.bpel.obj.OProcess;
+import 
org.apache.ode.bpel.runtime.common.extension.AbstractSyncExtensionOperation;
+import org.apache.ode.bpel.runtime.common.extension.ExtensibilityQNames;
+import org.apache.ode.bpel.runtime.common.extension.ExtensionContext;
+import org.apache.ode.utils.DOMUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * JacobRunnable that delegates the work of the <code>extensionActivity</code>
+ * activity to a registered extension implementation.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class EXTENSIONACTIVITY extends ACTIVITY {
+       private static final long serialVersionUID = 1L;
+       private static final Logger __log = LoggerFactory
+                       .getLogger(EXTENSIONACTIVITY.class);
+
+       public EXTENSIONACTIVITY(ActivityInfo self, ScopeFrame scopeFrame,
+                       LinkFrame linkFrame) {
+               super(self, scopeFrame, linkFrame);
+       }
+
+       public final void run() {
+               final ExtensionContext context = new ExtensionContextImpl(this,
+                               getBpelRuntimeContext());
+               final OExtensionActivity oea = (OExtensionActivity) _self.o;
+
+               try {
+                       ExtensionOperation ea = getBpelRuntimeContext()
+                                       
.createExtensionActivityImplementation(oea.getExtensionName());
+                       if (ea == null) {
+                               for (OProcess.OExtension oe : 
oea.getOwner().getMustUnderstandExtensions()) {
+                                       if 
(oea.getExtensionName().getNamespaceURI().equals(
+                                                       oe.getNamespace())) {
+                                               __log.warn("Lookup of extension 
activity "
+                                                               + 
oea.getExtensionName() + " failed.");
+                                               throw new FaultException(
+                                                               
ExtensibilityQNames.UNKNOWN_EA_FAULT_NAME,
+                                                               "Lookup of 
extension activity "
+                                                                               
+ oea.getExtensionName()
+                                                                               
+ " failed. No implementation found.");
+                                       }
+                               }
+                               // act like <empty> - do nothing
+                               context.complete();
+                               return;
+                       }
+
+                       ea.run(context, 
DOMUtils.stringToDOM(oea.getNestedElement()));
+
+                       // Complete the context for sync extension operations. 
Asynchronous
+                       // operations have to control their completion 
themselves.
+                       if (ea instanceof AbstractSyncExtensionOperation) {
+                               context.complete();
+                       }
+               } catch (FaultException fault) {
+                       __log.error("Execution of extension activity caused an 
exception.",
+                                       fault);
+                       context.completeWithFault(fault);
+               } catch (SAXException e) {
+               FaultException fault = new 
FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, "The nested 
element of extension activity '" + oea.getName() + "' for extension '" + 
oea.getExtensionName() + "' is no valid XML.");
+               context.completeWithFault(fault);
+               } catch (IOException e) {
+                       FaultException fault = new 
FaultException(ExtensibilityQNames.INVALID_EXTENSION_ELEMENT, "The nested 
element of extension activity '" + oea.getName() + "' for extension '" + 
oea.getExtensionName() + "' is no valid XML.");
+                       context.completeWithFault(fault);
+               }
+
+       }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/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
new file mode 100644
index 0000000..4117c7e
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/ExtensionContextImpl.java
@@ -0,0 +1,218 @@
+/*
+ * 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;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.evar.ExternalVariableModuleException;
+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.OPartnerLink;
+import org.apache.ode.bpel.obj.OProcess;
+import org.apache.ode.bpel.obj.OScope;
+import org.apache.ode.bpel.runtime.channels.FaultData;
+import org.apache.ode.bpel.runtime.common.extension.ExtensionContext;
+import org.apache.ode.utils.Namespaces;
+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 ACTIVITY _activity;
+       private ActivityInfo _activityInfo;
+       
+       private boolean hasCompleted = false;
+
+       //@hahnml: Changed to ACTIVITY to get the whole stuff with one parameter
+       public ExtensionContextImpl(ACTIVITY activity, BpelRuntimeContext 
context) {
+               _activityInfo = activity._self;
+               _context = context;
+               _activity = activity;
+       }
+       
+       public Long getProcessId() {
+               return _context.getPid();
+       }
+
+       public Map<String, OScope.Variable> getVisibleVariables()
+                       throws FaultException {
+               Map<String, OScope.Variable> visVars = new HashMap<String, 
OScope.Variable>();
+
+               OActivity current = _activity._scopeFrame.oscope;
+               while (current != null) {
+                       if (current instanceof OScope) {
+                               for (String varName : ((OScope) 
current).getVariables().keySet()) {
+                                       if (!visVars.containsKey(varName)) {
+                                               visVars.put(varName,
+                                                               ((OScope) 
current).getVariables().get(varName));
+                                       }
+                               }
+                       }
+                       current = current.getParent();
+               }
+
+               return visVars;
+       }
+
+       public String readMessageProperty(OScope.Variable variable,
+                       OProcess.OProperty property) throws FaultException {
+               VariableInstance vi = _activity._scopeFrame.resolve(variable);
+               return _context.readProperty(vi, property);
+       }
+
+       public Node readVariable(OScope.Variable variable) throws 
FaultException {
+               VariableInstance vi = _activity._scopeFrame.resolve(variable);
+               
+               return _activity._scopeFrame.fetchVariableData(_context, vi, 
false);
+       }
+
+       public void writeVariable(String variableName, Node value)
+                       throws FaultException, ExternalVariableModuleException {
+               OScope.Variable var = getVisibleVariable(variableName);
+               if (var == null) {
+                       throw new RuntimeException("Variable '" + variableName
+                                       + "' not visible.");
+               }
+               writeVariable(var, value);
+       }
+
+       public Node readVariable(String variableName) throws FaultException {
+               OScope.Variable var = getVisibleVariable(variableName);
+               if (var == null) {
+                       throw new RuntimeException("Variable '" + variableName
+                                       + "' not visible.");
+               }
+
+               return readVariable(var);
+       }
+
+       public void writeVariable(OScope.Variable variable, Node value)
+                       throws FaultException, ExternalVariableModuleException {
+               VariableInstance vi = _activity._scopeFrame.resolve(variable);
+               _activity._scopeFrame.initializeVariable(_context, vi, value);
+               VariableModificationEvent vme = new VariableModificationEvent(
+                               variable.getName());
+               vme.setNewValue(value);
+               sendEvent(vme);
+       }
+
+       public OScope.Variable getVisibleVariable(String varName) {
+               return _activity._scopeFrame.oscope.getVisibleVariable(varName);
+       }
+
+       public boolean isVariableVisible(String varName) {
+               return _activity._scopeFrame.oscope.getVisibleVariable(varName) 
!= null;
+       }
+
+       public String getActivityName() {
+               return _activityInfo.o.getName();
+       }
+
+       public OActivity getOActivity() {
+               return _activityInfo.o;
+       }
+
+       public void sendEvent(ScopeEvent event) {
+               if (event.getLineNo() == -1 && _activityInfo.o.getDebugInfo() 
!= null) {
+                       
event.setLineNo(_activityInfo.o.getDebugInfo().getStartLine());
+               }
+               _activity._scopeFrame.fillEventInfo(event);
+               
+               _context.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(
+                                       Namespaces.WSBPEL2_0_FINAL_EXEC,
+                                       "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.");
+                       }
+               }
+
+       }
+       
+       public BpelRuntimeContext getRuntimeInstance() {
+               return _context;
+       }
+
+       public URI getDUDir() {
+               return _context.getBaseResourceURI();
+       }
+
+       public void printToConsole(String msg) {
+               
LoggerFactory.getLogger("org.apache.ode.extension.Console").info(msg);
+       }
+
+       public PartnerLinkInstance resolvePartnerLinkInstance(OPartnerLink pl) {
+               return _activity._scopeFrame.resolve(pl);
+       }
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractAsyncExtensionOperation.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractAsyncExtensionOperation.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractAsyncExtensionOperation.java
new file mode 100644
index 0000000..a3c61df
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractAsyncExtensionOperation.java
@@ -0,0 +1,36 @@
+/*
+ * 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.common.extension;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.extension.ExtensionOperation;
+import org.w3c.dom.Element;
+
+/**
+ * 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(Object context, Element element)
+                       throws FaultException;
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractExtensionBundle.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractExtensionBundle.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractExtensionBundle.java
new file mode 100644
index 0000000..e4e1857
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractExtensionBundle.java
@@ -0,0 +1,109 @@
+/*
+ * 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.common.extension;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ode.bpel.extension.ExtensionBundleRuntime;
+import org.apache.ode.bpel.extension.ExtensionBundleValidation;
+import org.apache.ode.bpel.extension.ExtensionOperation;
+import org.apache.ode.bpel.extension.ExtensionValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class that bundles and registers
+ * <code>&lt;extensionActivity&gt;</code> and
+ * <code>&lt;extensionAssignOperation&gt;</code> implementations related to a
+ * particular namespace.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public abstract class AbstractExtensionBundle implements
+               ExtensionBundleRuntime, ExtensionBundleValidation {
+
+       private static Logger __log = 
LoggerFactory.getLogger(AbstractExtensionBundle.class);
+       private Map<String, Class<? extends ExtensionOperation>> 
extensionsByName = new HashMap<String, Class<? extends ExtensionOperation>>();
+
+       /**
+        * Returns the extension namespace this bundle provides implementations 
for.
+        * 
+        * @return
+        */
+       public abstract String getNamespaceURI();
+
+       /**
+        * Register extension operations.
+        */
+       public abstract void registerExtensionActivities();
+
+       /**
+        * Register an {@link org.apache.ode.bpel.extension.ExtensionOperation}
+        * implementation as <code>&lt;extensionActivity&gt;</code>.
+        * 
+        * @param localName
+        * @param activity
+        */
+       protected final void registerExtensionOperation(String localName,
+                       Class<? extends ExtensionOperation> operation) {
+               extensionsByName.put(localName, operation);
+       }
+
+       /**
+        * Returns a list of the local names of registered extension operations.
+        */
+       public final Set<String> getExtensionOperationNames() {
+               return Collections.unmodifiableSet(extensionsByName.keySet());
+       }
+
+       public final Class<? extends ExtensionOperation> 
getExtensionOperationClass(
+                       String localName) {
+               return extensionsByName.get(localName);
+       }
+
+       public final ExtensionOperation getExtensionOperationInstance(
+                       String localName) throws InstantiationException,
+                       IllegalAccessException {
+               return getExtensionOperationClass(localName).newInstance();
+       }
+
+       public final Map<QName, ExtensionValidator> getExtensionValidators() {
+               Map<QName, ExtensionValidator> result = new HashMap<QName, 
ExtensionValidator>();
+               String ns = getNamespaceURI();
+               for (String localName : extensionsByName.keySet()) {
+                       if 
(ExtensionValidator.class.isAssignableFrom(extensionsByName
+                                       .get(localName))) {
+                               try {
+                                       result.put(
+                                                       new QName(ns, 
localName),
+                                                       (ExtensionValidator) 
getExtensionOperationInstance(localName));
+                               } catch (Exception e) {
+                                       __log.warn("Could not instantiate 
extension validator for '{"
+                                                       + ns + "}" + localName);
+                               }
+                       }
+               }
+               return result;
+       }
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractSyncExtensionOperation.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractSyncExtensionOperation.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractSyncExtensionOperation.java
new file mode 100644
index 0000000..65420c4
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/AbstractSyncExtensionOperation.java
@@ -0,0 +1,45 @@
+/*
+ * 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.common.extension;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.extension.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(Object contexto, Element element) throws FaultException 
{
+               ExtensionContext context = (ExtensionContext) contexto;
+               try {
+                       runSync(context, element);
+               } catch (FaultException f) {
+                       throw f;
+               }
+       }
+       
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/ExtensibilityQNames.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/ExtensibilityQNames.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/ExtensibilityQNames.java
new file mode 100644
index 0000000..ed238ad
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/ExtensibilityQNames.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.runtime.common.extension;
+
+import javax.xml.namespace.QName;
+
+public abstract class ExtensibilityQNames {
+       /*
+        * Activity Recovery extensibility elements.
+        */
+       public static final String NS_ACTIVITY_RECOVERY = 
"http://ode.apache.org/activityRecovery";;
+       public static final QName FAILURE_HANDLING = new QName(
+                       NS_ACTIVITY_RECOVERY, "failureHandling");
+       public static final QName FAILURE_HANDLING_RETRY_FOR = new QName(
+                       NS_ACTIVITY_RECOVERY, "retryFor");
+       public static final QName FAILURE_HANDLING_RETRY_DELAY = new QName(
+                       NS_ACTIVITY_RECOVERY, "retryDelay");
+       public static final QName FAILURE_HANDLING_FAULT_ON = new QName(
+                       NS_ACTIVITY_RECOVERY, "faultOnFailure");
+
+       public static final String NS_BPEL_EXTENSIBILITY = 
"http://ode.apache.org/bpelExtensibility";;
+       
+       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");
+       
+       //
+       // External variables
+       //
+       /** Namespace for external variables. */
+       private static final String EXTVAR_NS = 
"http://ode.apache.org/externalVariables";;
+
+       /** Attribute name for external variable id. */
+       public static final QName EXTVAR_ATTR = new QName(EXTVAR_NS, "id");
+
+       /** Attribute holding the name of the "related" variable. */
+       public static final QName EXTVAR_RELATED = new QName(EXTVAR_NS,
+                       "relates-to");
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/ExtensionContext.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/ExtensionContext.java
 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/ExtensionContext.java
new file mode 100644
index 0000000..61da3aa
--- /dev/null
+++ 
b/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/common/extension/ExtensionContext.java
@@ -0,0 +1,190 @@
+/*
+ * 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.common.extension;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.evar.ExternalVariableModuleException;
+import org.apache.ode.bpel.obj.OActivity;
+import org.apache.ode.bpel.obj.OPartnerLink;
+import org.apache.ode.bpel.obj.OProcess;
+import org.apache.ode.bpel.obj.OScope;
+import org.apache.ode.bpel.runtime.BpelRuntimeContext;
+import org.apache.ode.bpel.runtime.PartnerLinkInstance;
+import org.w3c.dom.Node;
+
+/**
+ * Context for executing extension activities or extension assign operations.
+ * Implementations of the
+ * {@link org.apache.ode.bpel.extension.ExtensionOperation} class use this
+ * interface to access BPEL variables, property sets and link status.
+ * 
+ * All <code>ExtensionOperation</code> implementations must complete with
+ * <code>complete()</code>, <code>completeWithFault(...)</code>.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public interface ExtensionContext {
+
+       /**
+        * Returns a list of variables visible in the current scope.
+        * 
+        * @return an unmodifiable list of visible variables.
+        * @throws FaultException
+        */
+       Map<String, OScope.Variable> getVisibleVariables() throws 
FaultException;
+
+       /**
+        * Returns whether a variable is visible in the current scope or not.
+        * 
+        * @param variableName
+        *            name of the variable.
+        * @return true if the variable is visible.
+        * @throws FaultException
+        */
+       boolean isVariableVisible(String variableName);
+
+       /**
+        * Read the value of a BPEL variable.
+        * 
+        * @param variable
+        *            variable to read
+        * @return the value of the variable, wrapped in a <code>Node</code>
+        */
+       Node readVariable(OScope.Variable variable) throws FaultException;
+
+       /**
+        * Read the value of a BPEL variable.
+        * 
+        * @param variableName
+        *            variable to read
+        * @return the value of the variable, wrapped in a <code>Node</code>
+        */
+       Node readVariable(String variableName) throws FaultException;
+
+       /**
+        * Write the value into a BPEL variable.
+        * 
+        * @param variable
+        *            variable to write
+        * @param value
+        *            the value to be stored into the variable
+        * @return the value of the variable, wrapped in a <code>Node</code>
+        */
+       void writeVariable(OScope.Variable variable, Node value)
+                       throws FaultException, ExternalVariableModuleException;
+
+       /**
+        * Write the value into a BPEL variable.
+        * 
+        * @param variableName
+        *            variable to write
+        * @param value
+        *            the value to be stored into the variable
+        * @return the value of the variable, wrapped in a <code>Node</code>
+        */
+       void writeVariable(String variableName, Node value) throws 
FaultException,
+                       ExternalVariableModuleException;
+
+       /**
+        * Read the value of a BPEL property.
+        * 
+        * @param variable
+        *            variable containing property
+        * @param property
+        *            property to read
+        * @return value of the property
+        */
+       String readMessageProperty(OScope.Variable variable,
+                       OProcess.OProperty property) 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();
+
+       /**
+        * Returns the location of the deployment bundle of the executed 
process.
+        * 
+        * @return URI of the deployment bundle.
+        */
+       URI getDUDir();
+
+       /**
+        * Allows printing debug output to the console. Output will be 
redirected to
+        * the logger associated with 
<code>org.apache.ode.extension.Console</code>.
+        * The target log level is INFO.
+        */
+       void printToConsole(String msg);
+
+       /**
+        * Marks the currently executed activity as successfully completed.
+        */
+       void complete();
+
+       /**
+        * Marks the currently executed activity as faulted.
+        * 
+        * @param t
+        *            an exception to be reported as the fault cause.
+        */
+       void completeWithFault(Throwable t);
+
+       /**
+        * Marks the currently executed activity as faulted.
+        * 
+        * @param fault
+        *            a fault.
+        */
+       void completeWithFault(FaultException fault);
+
+       /*
+        * Low-level-methods
+        */
+
+       /**
+        * Returns the OActivity object.
+        */
+       OActivity getOActivity();
+
+       /**
+        * Returns ODE's runtime instance.
+        */
+       BpelRuntimeContext getRuntimeInstance();
+
+       /**
+        * Returns an instance of the given OPartnerLink object
+        * 
+        * @param pl
+        *            the partner link model object
+        * @return the related partner link instance
+        */
+       PartnerLinkInstance resolvePartnerLinkInstance(OPartnerLink pl);
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/MockCompilerContext.java
----------------------------------------------------------------------
diff --git 
a/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/MockCompilerContext.java
 
b/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/MockCompilerContext.java
index 1c4acb9..348ba28 100644
--- 
a/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/MockCompilerContext.java
+++ 
b/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/MockCompilerContext.java
@@ -35,6 +35,7 @@ import org.apache.ode.bpel.compiler.bom.Activity;
 import org.apache.ode.bpel.compiler.bom.BpelObject;
 import org.apache.ode.bpel.compiler.bom.Expression;
 import org.apache.ode.bpel.compiler.bom.ScopeLikeActivity;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.obj.OActivity;
 import org.apache.ode.bpel.obj.OElementVarType;
 import org.apache.ode.bpel.obj.OExpression;
@@ -249,4 +250,15 @@ public class MockCompilerContext implements 
CompilerContext {
     public NSContext tryCacheNamespaceContext(NSContext nsContext) {
         return nsContext;
     }
+
+    public boolean isExtensionDeclared(String namespace) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+    
+       @Override
+       public ExtensionValidator getExtensionValidator(QName 
extensionElementName) {
+               // TODO Auto-generated method stub
+               return null;
+       }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/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 456c1cf..3ae8f6f 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
@@ -34,6 +34,7 @@ import org.apache.ode.bpel.common.CorrelationKey;
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.evar.ExternalVariableModuleException;
 import org.apache.ode.bpel.evt.ProcessInstanceEvent;
+import org.apache.ode.bpel.extension.ExtensionOperation;
 import org.apache.ode.bpel.iapi.ProcessConf.PartnerRoleConfig;
 import org.apache.ode.bpel.obj.OCatch;
 import org.apache.ode.bpel.obj.OEmpty;
@@ -480,4 +481,20 @@ public class CoreBpelTest extends TestCase implements 
BpelRuntimeContext {
 
     public void checkInvokeExternalPermission() {}
 
+    public Node initializeVariable(VariableInstance var, ScopeFrame scopeFrame,
+                       Node val) throws ExternalVariableModuleException {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public Node fetchVariableData(VariableInstance variable,
+                       ScopeFrame scopeFrame, boolean forWriting) throws 
FaultException {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public ExtensionOperation createExtensionActivityImplementation(QName 
name) {
+               // TODO Auto-generated method stub
+               return null;
+       }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-store/src/main/java/org/apache/ode/store/DeploymentUnitDir.java
----------------------------------------------------------------------
diff --git 
a/bpel-store/src/main/java/org/apache/ode/store/DeploymentUnitDir.java 
b/bpel-store/src/main/java/org/apache/ode/store/DeploymentUnitDir.java
index b8a6d16..c36d4b1 100644
--- a/bpel-store/src/main/java/org/apache/ode/store/DeploymentUnitDir.java
+++ b/bpel-store/src/main/java/org/apache/ode/store/DeploymentUnitDir.java
@@ -49,6 +49,7 @@ import org.apache.ode.bpel.compiler.wsdl.WSDLFactoryBPEL20;
 import org.apache.ode.bpel.dd.DeployDocument;
 import org.apache.ode.bpel.dd.TDeployment;
 import org.apache.ode.bpel.dd.TDeployment.Process;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.iapi.ContextException;
 import org.apache.ode.bpel.obj.OProcess;
 import org.apache.ode.bpel.obj.serde.DeSerializer;
@@ -84,6 +85,8 @@ class DeploymentUnitDir {
     private volatile DeployDocument _dd;
     private volatile DocumentRegistry _docRegistry;
 
+    private Map<QName, ExtensionValidator> _extensionValidators;
+
     private long _version = -1;
 
     private static final FileFilter _wsdlFilter = new FileFilter() {
@@ -199,6 +202,7 @@ class DeploymentUnitDir {
             bpelc.setProcessWSDL(bpel11wsdl.toURI());
 
         bpelc.setCompileProperties(prepareCompileProperties(bpelFile));
+        bpelc.setExtensionValidators(_extensionValidators);
         bpelc.setBaseDirectory(_duDirectory);
         // Create process such that immutable objects are intern'ed.
         InternPool.runBlock(new InternableBlock() {
@@ -348,6 +352,10 @@ class DeploymentUnitDir {
         return result;
     }
 
+    public void setExtensionValidators(Map<QName, ExtensionValidator> 
extensionValidators) {
+       _extensionValidators = extensionValidators;
+    }
+
     public final class CBPInfo {
         final QName processName;
         final String guid;

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
----------------------------------------------------------------------
diff --git 
a/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java 
b/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
index 00a7c14..87927fe 100644
--- a/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
+++ b/bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
@@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory;
 import org.apache.ode.bpel.compiler.api.CompilationException;
 import org.apache.ode.bpel.dd.DeployDocument;
 import org.apache.ode.bpel.dd.TDeployment;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.iapi.*;
 import org.apache.ode.il.config.OdeConfigProperties;
 import org.apache.ode.store.DeploymentUnitDir.CBPInfo;
@@ -88,7 +89,7 @@ public class ProcessStoreImpl implements ProcessStore {
 
     protected File _configDir;
 
-
+    private Map<QName, ExtensionValidator> _extensionValidators = new 
HashMap<QName, ExtensionValidator>();
 
     /**
      * Executor used to process DB transactions. Allows us to isolate the TX 
context, and to ensure that only one TX gets executed a
@@ -189,6 +190,7 @@ public class ProcessStoreImpl implements ProcessStore {
 
         // Create the DU and compile/scan it before acquiring lock.
         final DeploymentUnitDir du = new 
DeploymentUnitDir(deploymentUnitDirectory);
+        du.setExtensionValidators(_extensionValidators);
         if( duName != null ) {
             // Override the package name if given from the parameter
             du.setName(duName);
@@ -927,4 +929,13 @@ public class ProcessStoreImpl implements ProcessStore {
         }
         return undeployed;
     }
+
+    public void setExtensionValidators(
+                       Map<QName, ExtensionValidator> extensionValidators) {
+               _extensionValidators = extensionValidators;
+       }
+       
+       public Map<QName, ExtensionValidator> getExtensionValidators() {
+               return _extensionValidators;
+       }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java
----------------------------------------------------------------------
diff --git a/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java 
b/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java
index 950d47e..3a789a1 100644
--- a/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java
+++ b/jbi/src/main/java/org/apache/ode/jbi/OdeLifeCycle.java
@@ -26,6 +26,9 @@ import org.apache.ode.bpel.connector.BpelServerConnector;
 import org.apache.ode.bpel.dao.BpelDAOConnectionFactoryJDBC;
 import org.apache.ode.bpel.engine.BpelServerImpl;
 import org.apache.ode.bpel.engine.ProcessAndInstanceManagementMBean;
+import org.apache.ode.bpel.extension.ExtensionBundleRuntime;
+import org.apache.ode.bpel.extension.ExtensionBundleValidation;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.extvar.jdbc.JdbcExternalVariableModule;
 import org.apache.ode.bpel.iapi.BpelEventListener;
 import org.apache.ode.bpel.intercept.MessageExchangeInterceptor;
@@ -135,6 +138,8 @@ public class OdeLifeCycle implements ComponentLifeCycle {
 
             registerMexInterceptors();
 
+            registerExtensionActivityBundles();
+
             registerMBean();
 
             __log.debug("Starting JCA connector.");
@@ -367,6 +372,61 @@ public class OdeLifeCycle implements ComponentLifeCycle {
             }
         }
     }
+    
+    // @hahnml: Added support for extension bundles based on ODE 2.0 alpha 
branch
+    private void registerExtensionActivityBundles() {
+               String extensionsRTStr = 
_ode._config.getExtensionActivityBundlesRT();
+               String extensionsValStr = _ode._config
+                               .getExtensionActivityBundlesValidation();
+               if (extensionsRTStr != null) {
+                       // TODO replace StringTokenizer by regex
+                       for (StringTokenizer tokenizer = new StringTokenizer(
+                                       extensionsRTStr, ",;"); 
tokenizer.hasMoreTokens();) {
+                               String bundleCN = tokenizer.nextToken();
+                               
+                               //@hahnml: Remove any whitespaces
+                               bundleCN = bundleCN.replaceAll(" ", "");
+                               
+                               try {
+                                       // instantiate bundle
+                                       ExtensionBundleRuntime bundleRT = 
(ExtensionBundleRuntime) Class
+                                                       
.forName(bundleCN).newInstance();
+                                       // register extension bundle (BPEL 
server)
+                                       
_ode._server.registerExtensionBundle(bundleRT);
+                               } catch (Exception e) {
+                                       __log.warn("Couldn't register the 
extension bundle runtime "
+                                                       + bundleCN
+                                                       + ", the class couldn't 
be "
+                                                       + "loaded properly.");
+                               }
+                       }
+               }
+               if (extensionsValStr != null) {
+                       Map<QName, ExtensionValidator> validators = new 
HashMap<QName, ExtensionValidator>();
+                       for (StringTokenizer tokenizer = new StringTokenizer(
+                                       extensionsValStr, ",;"); 
tokenizer.hasMoreTokens();) {
+                               String bundleCN = tokenizer.nextToken();
+                               
+                               //@hahnml: Remove any whitespaces
+                               bundleCN = bundleCN.replaceAll(" ", "");
+                               
+                               try {
+                                       // instantiate bundle
+                                       ExtensionBundleValidation bundleVal = 
(ExtensionBundleValidation) Class
+                                                       
.forName(bundleCN).newInstance();
+                                       // add validators
+                                       
validators.putAll(bundleVal.getExtensionValidators());
+                               } catch (Exception e) {
+                                       __log.warn("Couldn't register the 
extension bundle validator "
+                                                       + bundleCN
+                                                       + ", the class couldn't 
be "
+                                                       + "loaded properly.");
+                               }
+                       }
+                       // register extension bundle (BPEL store)
+                       _ode._store.setExtensionValidators(validators);
+        }
+    }
 
     public synchronized void start() throws JBIException {
         if (_started)

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/utils/src/main/java/org/apache/ode/utils/DOMUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/org/apache/ode/utils/DOMUtils.java 
b/utils/src/main/java/org/apache/ode/utils/DOMUtils.java
index 854a8bc..dc91e6f 100644
--- a/utils/src/main/java/org/apache/ode/utils/DOMUtils.java
+++ b/utils/src/main/java/org/apache/ode/utils/DOMUtils.java
@@ -701,6 +701,10 @@ public class DOMUtils {
         }
         return true;
     }
+    
+    public static QName getElementQName(Element el) {
+        return new QName(el.getNamespaceURI(),el.getLocalName());
+    }
 
     public static QName getNodeQName(Node el) {
         String localName = el.getLocalName();

Reply via email to