Port extension activity and extension assign operation support from ODE 2.0 alpha branch
diff --git a/.gitignore b/.gitignore
index 27225ba..c7cf71d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,5 @@
Gemfile.lock
spoon
*.log
+.m2/
+tmp/
diff --git a/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties b/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties
index 03ac79c..3c61926 100644
--- a/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties
+++ b/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties
@@ -101,3 +101,8 @@
## Clustering Implementation class.
#ode-axis2.clustering.impl.class = org.apache.ode.clustering.hazelcast.HazelcastClusterImpl
+
+## Extension Bundles
+## FQCNs, comma separated.
+#ode-axis2.extension.bundles.runtime=[packageName].[bundleClassName]
+#ode-axis2.extension.bundles.validation=[packageName].[bundleClassName]
diff --git a/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java b/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
index e002695..347f44c 100644
--- a/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
+++ b/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
@@ -38,12 +38,16 @@
import org.apache.ode.bpel.engine.BpelServerImpl;
import org.apache.ode.bpel.engine.CountLRUDehydrationPolicy;
import org.apache.ode.bpel.engine.cron.CronScheduler;
+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.*;
import org.apache.ode.bpel.intercept.MessageExchangeInterceptor;
import org.apache.ode.bpel.memdao.BpelDAOConnectionFactoryImpl;
import org.apache.ode.bpel.pmapi.InstanceManagement;
import org.apache.ode.bpel.pmapi.ProcessManagement;
+import org.apache.ode.bpel.runtime.common.extension.AbstractExtensionBundle;
import org.apache.ode.il.config.OdeConfigProperties;
import org.apache.ode.il.dbutil.Database;
import org.apache.ode.scheduler.simple.JdbcDelegate;
@@ -58,6 +62,8 @@
import javax.sql.DataSource;
import javax.transaction.*;
import javax.transaction.xa.XAResource;
+import javax.xml.namespace.QName;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -195,6 +201,7 @@
registerEventListeners();
registerMexInterceptors();
registerExternalVariableModules();
+ registerExtensionActivityBundles();
_store.loadAll();
if (_clusterManager != null) {
@@ -691,6 +698,86 @@
}
+ // Add support for extension bundles based on ODE 2.0 alpha branch
+ private void registerExtensionActivityBundles() {
+ String extensionsRTStr = _odeConfig.getExtensionActivityBundlesRT();
+ String extensionsValStr = _odeConfig
+ .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)
+ _bpelServer.registerExtensionBundle(bundleRT);
+
+ if (bundleRT instanceof AbstractExtensionBundle) {
+ AbstractExtensionBundle bundle = (AbstractExtensionBundle) bundleRT;
+
+ //@hahnml: Get the registered validators from the process store
+ Map<QName, ExtensionValidator> validators = _store.getExtensionValidators();
+
+ //Add the validators of this bundle to the existing validators
+ validators.putAll(bundle.getExtensionValidators());
+
+ // register extension bundle (BPEL store)
+ _store.setExtensionValidators(validators);
+ }
+ } 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)
+ //@hahnml: Check if validators are registered already
+ if (_store.getExtensionValidators().isEmpty()) {
+ _store.setExtensionValidators(validators);
+ } else {
+ //@hahnml: Get the registered validators from the process store
+ Map<QName, ExtensionValidator> allValidators = _store.getExtensionValidators();
+
+ //Add the registered validators to the existing validators
+ allValidators.putAll(validators);
+
+ // register extension bundle (BPEL store)
+ _store.setExtensionValidators(allValidators);
+ }
+ }
+ }
private class ProcessStoreListenerImpl implements ProcessStoreListener {
public void onProcessStoreEvent(ProcessStoreEvent event) {
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensibleElement.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensibleElement.java
new file mode 100644
index 0000000..f7922d4
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensibleElement.java
@@ -0,0 +1,32 @@
+/*
+ * 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.extension;
+
+import org.w3c.dom.Element;
+
+/**
+ * Common interface for ExtensionActivity and AssignExtensionOperation.
+ *
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public interface ExtensibleElement {
+
+ Element getNestedElement();
+
+}
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleRuntime.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleRuntime.java
new file mode 100644
index 0000000..2ddf3ac
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleRuntime.java
@@ -0,0 +1,12 @@
+package org.apache.ode.bpel.extension;
+
+public interface ExtensionBundleRuntime {
+
+ String getNamespaceURI();
+
+ void registerExtensionActivities();
+
+ ExtensionOperation getExtensionOperationInstance(String localName)
+ throws InstantiationException, IllegalAccessException;
+
+}
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleValidation.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleValidation.java
new file mode 100644
index 0000000..f12cf14
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleValidation.java
@@ -0,0 +1,13 @@
+package org.apache.ode.bpel.extension;
+
+import javax.xml.namespace.QName;
+import java.util.Map;
+
+/**
+ * Compile-time validation of extensions implemented by your bundle.
+ */
+public interface ExtensionBundleValidation {
+
+ Map<QName, ExtensionValidator> getExtensionValidators();
+
+}
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionOperation.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionOperation.java
new file mode 100644
index 0000000..da1c930
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionOperation.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.extension;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.w3c.dom.Element;
+
+/**
+ * This is the basis interface for implementations of
+ * <code><extensionAssignOperation></code> and
+ * <code><extensionActivity></code> nodes.
+ *
+ * Implementations of this interface must provide a default constructor as they
+ * are created using reflection.
+ *
+ * @see AbstractExtensionBundle
+ *
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public interface ExtensionOperation {
+
+ /**
+ * Provides the runtime implementation.
+ *
+ * <strong>Note:</strong> This method MAY run concurrently. Since Xerces'
+ * DOM implementation is not thread-safe, please make sure to synchronize
+ * the access to <code>element</code> if necessary.
+ *
+ * @param context
+ * injected ExtensionContext
+ * @param element
+ * the extension element (child of <code>extensionActivity</code>
+ * or <code>extensionAssignOperation</code>
+ * @throws FaultException
+ */
+ void run(Object context, Element element) throws FaultException;
+
+}
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionValidator.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionValidator.java
new file mode 100644
index 0000000..5159c1b
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionValidator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.extension;
+
+import org.apache.ode.bpel.extension.ExtensibleElement;
+
+/**
+ * Interface that allows Ode extensions to validate an extension element's
+ * content during compilation.
+ *
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public interface ExtensionValidator {
+
+ /**
+ *
+ * @param compilerContext
+ * @param element
+ */
+ void validate(Object compilerContext, ExtensibleElement element);
+
+}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java
index a2b5f25..91a6384 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java
@@ -23,7 +23,9 @@
import org.apache.ode.bpel.compiler.api.CompilationException;
import org.apache.ode.bpel.compiler.bom.Activity;
import org.apache.ode.bpel.compiler.bom.AssignActivity;
+import org.apache.ode.bpel.compiler.bom.AssignActivity.AssignOperation;
import org.apache.ode.bpel.compiler.bom.Copy;
+import org.apache.ode.bpel.compiler.bom.ExtensionAssignOperation;
import org.apache.ode.bpel.compiler.bom.ExtensionVal;
import org.apache.ode.bpel.compiler.bom.From;
import org.apache.ode.bpel.compiler.bom.LiteralVal;
@@ -31,6 +33,7 @@
import org.apache.ode.bpel.compiler.bom.PropertyVal;
import org.apache.ode.bpel.compiler.bom.To;
import org.apache.ode.bpel.compiler.bom.VariableVal;
+import org.apache.ode.bpel.extension.ExtensionValidator;
import org.apache.ode.bpel.obj.DebugInfo;
import org.apache.ode.bpel.obj.OActivity;
import org.apache.ode.bpel.obj.OAssign;
@@ -62,7 +65,9 @@
public void compile(OActivity dest, Activity source) {
OAssign oassign = (OAssign) dest;
AssignActivity ad = (AssignActivity) source;
- for (Copy scopy : ad.getCopies()) {
+ for (AssignOperation operation : ad.getOperations()) {
+ if (operation instanceof Copy) {
+ Copy scopy = (Copy) operation;
OAssign.Copy ocopy = new OAssign.Copy(_context.getOProcess());
ocopy.setKeepSrcElementName(scopy.isKeepSrcElement());
ocopy.setIgnoreMissingFromData(scopy.isIgnoreMissingFromData());
@@ -81,11 +86,45 @@
ocopy.setFrom(compileFrom(scopy.getFrom(), toResultType[0]));
verifyCopy(ocopy);
- oassign.getCopy().add(ocopy);
+ oassign.getOperations().add(ocopy);
} catch (CompilationException ce) {
_context.recoveredFromError(scopy, ce);
}
+ } else if (operation instanceof ExtensionAssignOperation) {
+ ExtensionAssignOperation sop = (ExtensionAssignOperation) operation;
+ OAssign.ExtensionAssignOperation oext = new OAssign.ExtensionAssignOperation(
+ _context.getOProcess());
+ oext.setDebugInfo(new DebugInfo(_context.getSourceLocation(),
+ sop.getLineNo(), source.getExtensibilityElements()));
+ try {
+ if (source.is20Draft()) {
+ throw new CompilationException(
+ __cmsgs.errExtensibleAssignNotSupported());
+ }
+ Element el = sop.getNestedElement();
+ if (el == null) {
+ throw new CompilationException(__cmsgs
+ .errMissingExtensionAssignOperationElement()
+ .setSource(sop));
+ }
+ if (!_context.isExtensionDeclared(el.getNamespaceURI())) {
+ throw new CompilationException(__cmsgs
+ .errUndeclaredExtensionAssignOperation()
+ .setSource(sop));
+ }
+ ExtensionValidator validator = _context
+ .getExtensionValidator(DOMUtils.getElementQName(el));
+ if (validator != null) {
+ validator.validate(_context, sop);
+ }
+ oext.setExtensionName(DOMUtils.getElementQName(el));
+ oext.setNestedElement(DOMUtils.domToString(el));
+ oassign.getOperations().add(oext);
+ } catch (CompilationException ce) {
+ _context.recoveredFromError(sop, ce);
+ }
+ }
}
}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java
index 74252dc..abef091 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java
@@ -86,4 +86,18 @@
return this.formatCompilationMessage("To-spec format is unrecognized.");
}
+ /**ExtensionAssignOperation's nested element missing*/
+ public CompilationMessage errMissingExtensionAssignOperationElement(){
+ return this.formatCompilationMessage("Extensibility element in <extensionAssignOperation> is missing.");
+ }
+
+ /**ExtensionAssignOperation's nested element missing*/
+ public CompilationMessage errUndeclaredExtensionAssignOperation(){
+ return this.formatCompilationMessage("Extension namespace of <extensionAssignOperation> has not been declared.");
+ }
+
+ /**Draft extensibleAssign is not supported.*/
+ public CompilationMessage errExtensibleAssignNotSupported(){
+ return this.formatCompilationMessage("ExtensibleAssign is not supported, please upgrade to BPEL 2.0 final.");
+ }
}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java
index ff1bd34..71cb107 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java
@@ -38,6 +38,7 @@
import org.apache.ode.bpel.compiler.api.SourceLocation;
import org.apache.ode.bpel.compiler.bom.BpelObjectFactory;
import org.apache.ode.bpel.compiler.bom.Process;
+import org.apache.ode.bpel.extension.ExtensionValidator;
import org.apache.ode.bpel.obj.OProcess;
import org.apache.ode.bpel.obj.OProcessWrapper;
import org.apache.ode.bpel.obj.serde.DeSerializer;
@@ -72,6 +73,8 @@
private Map<String,Object> _compileProperties;
private boolean _dryRun = false;
+ private Map<QName, ExtensionValidator> _extensionValidators;
+
public static BpelC newBpelCompiler() {
return new BpelC();
}
@@ -252,6 +255,9 @@
if (_compileProperties.get(PROCESS_CUSTOM_PROPERTIES) != null)
compiler.setCustomProperties((Map<QName, Node>) _compileProperties.get(PROCESS_CUSTOM_PROPERTIES));
}
+ if (_extensionValidators != null) {
+ compiler.setExtensionValidators(_extensionValidators);
+ }
} catch (CompilationException ce) {
this.invalidate();
throw ce;
@@ -523,4 +529,12 @@
}
}
+ /**
+ * Registers extension validators to eventually validate the content of extensibility
+ * elements.
+ * @param extensionValidators
+ */
+ public void setExtensionValidators(Map<QName, ExtensionValidator> extensionValidators) {
+ _extensionValidators = extensionValidators;
+ }
}
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 00d8ccd..a1545ee 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
@@ -63,6 +63,7 @@
import org.apache.ode.bpel.compiler.bom.CorrelationSet;
import org.apache.ode.bpel.compiler.bom.Expression;
import org.apache.ode.bpel.compiler.bom.Expression11;
+import org.apache.ode.bpel.compiler.bom.Extension;
import org.apache.ode.bpel.compiler.bom.FaultHandler;
import org.apache.ode.bpel.compiler.bom.Import;
import org.apache.ode.bpel.compiler.bom.LinkSource;
@@ -81,6 +82,7 @@
import org.apache.ode.bpel.compiler.bom.Variable;
import org.apache.ode.bpel.compiler.wsdl.Definition4BPEL;
import org.apache.ode.bpel.compiler.wsdl.WSDLFactory4BPEL;
+import org.apache.ode.bpel.extension.ExtensionValidator;
import org.apache.ode.bpel.obj.DebugInfo;
import org.apache.ode.bpel.obj.OActivity;
import org.apache.ode.bpel.obj.OAssign;
@@ -138,7 +140,7 @@
private Date _generatedDate;
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
private HashMap<Class, ActivityGenerator> _actGenerators = new HashMap<Class, ActivityGenerator>();
private boolean _supressJoinFailure = false;
@@ -182,6 +184,9 @@
private URI _processURI;
+ private final Set<String> _declaredExtensionNS = new HashSet<String>();
+ private Map<QName, ExtensionValidator> _extensionValidators = new HashMap<QName, ExtensionValidator>();
+
BpelCompiler(WSDLFactory4BPEL wsdlFactory) {
_wsdlFactory = wsdlFactory;
_wsdlRegistry = new WSDLRegistry(this);
@@ -733,6 +738,11 @@
}
}
+ // compile extensions
+ for (Extension e : _processDef.getExtensions()) {
+ compileExtension(e);
+ }
+
OScope procesScope = new OScope(_oprocess, null);
procesScope.setName("__PROCESS_SCOPE:" + (process.getName()));
procesScope.setDebugInfo(createDebugInfo(process, null));
@@ -1628,17 +1638,44 @@
for (OActivity act : _compiledActivities) {
if (act instanceof OAssign) {
OAssign assign = (OAssign) act;
- for (OAssign.Copy copy : assign.getCopy()) {
- if (copy.getTo() instanceof OAssign.PartnerLinkRef) {
- if (((OAssign.PartnerLinkRef) copy.getTo()).getPartnerLink().getName().equals(plink))
- return true;
- }
- }
+ for (OAssign.OAssignOperation operation : assign.getOperations()) {
+ if (operation instanceof OAssign.Copy) {
+ OAssign.Copy copy = (OAssign.Copy) operation;
+ if (copy.getTo() instanceof OAssign.PartnerLinkRef) {
+ if (((OAssign.PartnerLinkRef) copy.getTo()).getPartnerLink()
+ .getName().equals(plink))
+ return true;
+ }
+ }
+ }
}
}
return false;
}
+ /**
+ * Registers a declared extension. Since compilation may take place
+ * independently of the target engine configuration, the compiler will not
+ * check whether a extension implementation is registered.
+ */
+ private void compileExtension(Extension ext) {
+ OProcess.OExtension oextension = new OProcess.OExtension(_oprocess);
+ oextension.setNamespace(ext.getNamespaceURI());
+ oextension.setMustUnderstand(ext.isMustUnderstand());
+
+ oextension.setDebugInfo(createDebugInfo(_processDef,
+ "Extension " + ext.getNamespaceURI()));
+
+ _declaredExtensionNS.add(ext.getNamespaceURI());
+ _oprocess.getDeclaredExtensions().add(oextension);
+ if (ext.isMustUnderstand()) {
+ _oprocess.getMustUnderstandExtensions().add(oextension);
+ }
+
+ if (__log.isDebugEnabled())
+ __log.debug("Compiled extension " + oextension);
+ }
+
public Definition[] getWsdlDefinitions() {
Definition[] result = new Definition[_wsdlRegistry.getDefinitions().length];
for (int m = 0; m < _wsdlRegistry.getDefinitions().length; m++) {
@@ -1657,7 +1694,7 @@
return type;
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
private ActivityGenerator findActivityGen(Activity source) {
Class actClass = source.getClass();
@@ -1674,7 +1711,7 @@
throw new CompilationException(__cmsgs.errUnknownActivity(actClass.getName()).setSource(source));
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
protected void registerActivityCompiler(Class defClass, ActivityGenerator generator) {
if (__log.isDebugEnabled()) {
__log.debug("Adding compiler for nodes class \"" + defClass.getName() + " = " + generator);
@@ -1709,12 +1746,25 @@
_expLanguageCompilers.put(expLangUri, expressionCompiler);
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
protected void registerExpressionLanguage(String expLangUri, String classname) throws Exception {
Class cls = Class.forName(classname);
registerExpressionLanguage(expLangUri, (ExpressionCompiler) cls.newInstance());
}
+ public void setExtensionValidators(
+ Map<QName, ExtensionValidator> extensionValidators) {
+ _extensionValidators = extensionValidators;
+ }
+
+ public boolean isExtensionDeclared(String namespace) {
+ return _declaredExtensionNS.contains(namespace);
+ }
+
+ public ExtensionValidator getExtensionValidator(QName extensionElementName) {
+ return _extensionValidators.get(extensionElementName);
+ }
+
public List<OActivity> getActivityStack() {
ArrayList<OActivity> rval = new ArrayList<OActivity>(_structureStack._stack);
Collections.reverse(rval);
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java
index 7bba612..e4b1f0d 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java
@@ -23,6 +23,7 @@
import org.apache.ode.bpel.compiler.bom.CompensateActivity;
import org.apache.ode.bpel.compiler.bom.CompensateScopeActivity;
import org.apache.ode.bpel.compiler.bom.EmptyActivity;
+import org.apache.ode.bpel.compiler.bom.ExtensionActivity;
import org.apache.ode.bpel.compiler.bom.FlowActivity;
import org.apache.ode.bpel.compiler.bom.ForEachActivity;
import org.apache.ode.bpel.compiler.bom.IfActivity;
@@ -71,6 +72,7 @@
registerActivityCompiler(TerminateActivity.class, new TerminateGenerator());
registerActivityCompiler(RethrowActivity.class, new RethrowGenerator());
registerActivityCompiler(ForEachActivity.class, new ForEachGenerator());
+ registerActivityCompiler(ExtensionActivity.class, new ExtensionActivtityGenerator());
registerExpressionLanguage(OASIS_EXPLANG_XPATH_1_0, new XPath10ExpressionCompilerBPEL20());
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java
index 8faf69a..bb9f082 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java
@@ -23,6 +23,7 @@
import org.apache.ode.bpel.compiler.bom.Bpel20QNames;
import org.apache.ode.bpel.compiler.bom.CompensateScopeActivity;
import org.apache.ode.bpel.compiler.bom.EmptyActivity;
+import org.apache.ode.bpel.compiler.bom.ExtensionActivity;
import org.apache.ode.bpel.compiler.bom.FlowActivity;
import org.apache.ode.bpel.compiler.bom.ForEachActivity;
import org.apache.ode.bpel.compiler.bom.IfActivity;
@@ -70,6 +71,7 @@
registerActivityCompiler(TerminateActivity.class, new TerminateGenerator());
registerActivityCompiler(RethrowActivity.class, new RethrowGenerator());
registerActivityCompiler(ForEachActivity.class, new ForEachGenerator());
+ registerActivityCompiler(ExtensionActivity.class, new ExtensionActivtityGenerator());
registerExpressionLanguage(OASIS_EXPLANG_XPATH_1_0, new XPath10ExpressionCompilerBPEL20Draft());
try {
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivityGeneratorMessages.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivityGeneratorMessages.java
new file mode 100644
index 0000000..5971bc8
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivityGeneratorMessages.java
@@ -0,0 +1,43 @@
+/*
+ * 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.compiler;
+
+import org.apache.ode.bpel.compiler.api.CompilationMessage;
+import org.apache.ode.bpel.compiler.api.CompilationMessageBundle;
+
+/**
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class ExtensionActivityGeneratorMessages extends
+ CompilationMessageBundle {
+
+ /** ExtensionActivity is empty. */
+ public CompilationMessage errMissingExtensionActivityElement() {
+ return this
+ .formatCompilationMessage("Extensibility element in <extensionActivity> is missing.");
+ }
+
+ /** Extension namespace is not yet declared. */
+ public CompilationMessage errUndeclaredExtensionActivity() {
+ return this
+ .formatCompilationMessage("Extension namespace of <extensionActivity> has not been declared.");
+ }
+
+}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivtityGenerator.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivtityGenerator.java
new file mode 100644
index 0000000..22d949b
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivtityGenerator.java
@@ -0,0 +1,86 @@
+/*
+ * 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.compiler;
+
+import org.apache.ode.bpel.compiler.api.CompilationException;
+import org.apache.ode.bpel.compiler.bom.Activity;
+import org.apache.ode.bpel.compiler.bom.CompositeActivity;
+import org.apache.ode.bpel.compiler.bom.ExtensionActivity;
+import org.apache.ode.bpel.extension.ExtensionValidator;
+import org.apache.ode.bpel.obj.OActivity;
+import org.apache.ode.bpel.obj.OExtensionActivity;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.msg.MessageBundle;
+import org.w3c.dom.Element;
+
+/**
+ * Generates code for <code><empty></code> activities.
+ *
+ * @author Tammo van Lessen
+ */
+public class ExtensionActivtityGenerator extends DefaultActivityGenerator {
+ private static final ExtensionActivityGeneratorMessages __cmsgs = MessageBundle
+ .getMessages(ExtensionActivityGeneratorMessages.class);
+
+ public void compile(OActivity output, Activity srcx) {
+ ExtensionActivity src = (ExtensionActivity) srcx;
+ OExtensionActivity oactivity = (OExtensionActivity) output;
+ Element child = src.getFirstExtensibilityElementElement();
+ try {
+ if (child == null) {
+ throw new CompilationException(
+ __cmsgs.errMissingExtensionActivityElement());
+ }
+ if (!_context.isExtensionDeclared(child.getNamespaceURI())) {
+ throw new CompilationException(__cmsgs
+ .errUndeclaredExtensionActivity().setSource(src));
+ }
+ ExtensionValidator validator = _context
+ .getExtensionValidator(DOMUtils.getElementQName(child));
+ if (validator != null) {
+ validator.validate(_context, src);
+ }
+ oactivity.setExtensionName(DOMUtils.getElementQName(child));
+ oactivity.setNestedElement(DOMUtils.domToString(child));
+
+ compileChildren(oactivity, (ExtensionActivity) src);
+
+ } catch (CompilationException e) {
+ _context.recoveredFromError(src, e);
+ }
+ }
+
+ public OActivity newInstance(Activity src) {
+ return new OExtensionActivity(_context.getOProcess(),
+ _context.getCurrent());
+ }
+
+ protected void compileChildren(OExtensionActivity dest,
+ CompositeActivity src) {
+ for (Activity child : src.getActivities()) {
+ try {
+ OActivity compiledChild = _context.compile(child);
+ dest.getChildren().add(compiledChild);
+ } catch (CompilationException ce) {
+ _context.recoveredFromError(child, ce);
+ }
+ }
+ }
+
+}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java
index 5d9f634..83467df 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java
@@ -29,6 +29,7 @@
import org.apache.ode.bpel.compiler.bom.Activity;
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.OExpression;
import org.apache.ode.bpel.obj.OLValueExpression;
@@ -146,6 +147,10 @@
Map<URI, Source> getSchemaSources();
+ boolean isExtensionDeclared(String namespace);
+
+ ExtensionValidator getExtensionValidator(QName extensionElementName);
+
/**
* Retrieves the base URI that the BPEL Process execution contextis running relative to.
*
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java
index f503a83..1c890aa 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java
@@ -18,6 +18,7 @@
*/
package org.apache.ode.bpel.compiler.bom;
+import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Element;
@@ -41,4 +42,38 @@
public List<Copy> getCopies() {
return getChildren(Copy.class);
}
+
+ /**
+ * Get the list of <code><extensionAssignOperation></code> entries for this activity.
+ *
+ * @return extensionAssignOperation entries
+ */
+ public List<ExtensionAssignOperation> getExtensionAssignOperations() {
+ return getChildren(ExtensionAssignOperation.class);
+ }
+
+ /**
+ * Get the list of all assign operation entries (<code>copy</code>
+ * and <code>extensionAssignOperation</code>) for this activity.
+ *
+ * @return assign operation entries
+ */
+ public List<AssignOperation> getOperations() {
+ //all children objects
+ List<BpelObject> children = getChildren(BpelObject.class);
+
+ //aggregate only copy and extensionAssignOperation entries
+ List<AssignOperation> ops = new ArrayList<AssignOperation>();
+ for (BpelObject bo: children) {
+ if ((bo instanceof Copy)
+ ||(bo instanceof ExtensionAssignOperation)) {
+ ops.add((AssignOperation)bo);
+ }
+ }
+
+ return ops;
+ }
+
+ /** Marker interface for assign operations */
+ public static interface AssignOperation {}
}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
index 492514e..3e962a0 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
@@ -109,6 +109,10 @@
public static final QName FINAL_PROPQUERY = new QName(NS_WSBPEL2_0_FINAL_VARPROP, "query");
public static final QName FINAL_PLINKTYPE = new QName(NS_WSBPEL2_0_FINAL_PLINK, "partnerLinkType");
public static final QName FINAL_PLINKROLE = new QName(NS_WSBPEL2_0_FINAL_PLINK, "role");
+ public static final QName FINAL_EXTENSIONS = newFinalQName("extensions");
+ public static final QName FINAL_EXTENSION = newFinalQName("extension");
+ public static final QName FINAL_EXTENSION_ASSIGN_OPERATION = newFinalQName("extensionAssignOperation");
+ public static final QName FINAL_EXTENSION_ACTIVITY = newFinalQName("extensionActivity");
/** Some BPEL 2.0 Draft Elements **/
public static final QName PROCESS = newQName("process");
@@ -183,6 +187,10 @@
public static final QName PROPERTY = newQName("property");
public static final QName PLINKTYPE = new QName(NS_WSBPEL_PARTNERLINK_2004_03, "partnerLinkType");
public static final QName PLINKROLE = new QName(NS_WSBPEL_PARTNERLINK_2004_03, "role");
+ public static final QName EXTENSIONS = newQName("extensions");
+ public static final QName EXTENSION = newQName("extension");
+ public static final QName EXTENSIBLE_ASSIGN = newQName("extensibleAssign");
+ public static final QName EXTENSION_ACTIVITY = newQName("extensionActivity");
/** Not part of BPEL, but handy to have. */
public static final String NS_RDF = "http://www.w3.org/2000/01/rdf-schema#";
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
index 7ab2acb..f2b64aa 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
@@ -131,6 +131,10 @@
_mappings.put(Bpel20QNames.FINAL_EVENTHANDLERS, BpelObject.class);
_mappings.put(Bpel20QNames.FINAL_TARGETS,Targets.class);
_mappings.put(Bpel20QNames.FINAL_SOURCES,Sources.class);
+ _mappings.put(Bpel20QNames.FINAL_EXTENSIONS,Extensions.class);
+ _mappings.put(Bpel20QNames.FINAL_EXTENSION,Extension.class);
+ _mappings.put(Bpel20QNames.FINAL_EXTENSION_ACTIVITY,ExtensionActivity.class);
+ _mappings.put(Bpel20QNames.FINAL_EXTENSION_ASSIGN_OPERATION,ExtensionAssignOperation.class);
//
// BPEL 2.0 draft Mappings
@@ -207,6 +211,10 @@
_mappings.put(Bpel20QNames.TARGETS,Targets.class);
_mappings.put(Bpel20QNames.SOURCES,Sources.class);
_mappings.put(Bpel20QNames.RDF_LABEL,RdfLabel.class);
+ _mappings.put(Bpel20QNames.EXTENSIONS,Extensions.class);
+ _mappings.put(Bpel20QNames.EXTENSION,Extension.class);
+ _mappings.put(Bpel20QNames.EXTENSION_ACTIVITY,ExtensionActivity.class);
+ _mappings.put(Bpel20QNames.EXTENSIBLE_ASSIGN,ExtensionAssignOperation.class);
//
// BPEL 1.1 Mappings
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java
index 1764828..22523e0 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java
@@ -18,6 +18,7 @@
*/
package org.apache.ode.bpel.compiler.bom;
+import org.apache.ode.bpel.compiler.bom.AssignActivity.AssignOperation;
import org.w3c.dom.Element;
/**
@@ -25,7 +26,7 @@
* (L-value) and a "right hand side (R-value). The value on the right hand side
* is copied to the location referenced in the left hand side.
*/
-public class Copy extends BpelObject {
+public class Copy extends BpelObject implements AssignOperation {
public Copy(Element el) {
super(el);
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extension.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extension.java
new file mode 100644
index 0000000..2a5a755
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extension.java
@@ -0,0 +1,41 @@
+/*
+ * 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.compiler.bom;
+
+import org.w3c.dom.Element;
+
+/**
+ * BOM representation of the BPEL <code><extension></code> element.
+ *
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class Extension extends BpelObject {
+
+ public Extension(Element el) {
+ super(el);
+ }
+
+ public boolean isMustUnderstand() {
+ return getAttribute("mustUnderstand", "no").equals("yes");
+ }
+
+ public String getNamespaceURI() {
+ return getAttribute("namespace", null);
+ }
+}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionActivity.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionActivity.java
new file mode 100644
index 0000000..78c5d87
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionActivity.java
@@ -0,0 +1,104 @@
+/*
+ * 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.compiler.bom;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.w3c.dom.Element;
+import org.apache.ode.bpel.extension.ExtensibleElement;
+
+/**
+ * BOM representation of the BPEL <code><extensionActivity></code>
+ * activity. The <code><extensionActivity></code> activity contains a
+ * nested DOM element that represents the actual extension element. According to
+ * the BPEL 2.0 PR1 specification, the standards elements and standards
+ * attributes are not located in the extensionActivity element but in the nested
+ * element. Therefore the convenient access methods for standards
+ * attributes/elements are overridden to refer to the nested elements.
+ *
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class ExtensionActivity extends CompositeActivity implements
+ ExtensibleElement {
+ private Activity _childActivity;
+
+ public ExtensionActivity(Element el) {
+ super(el);
+ _childActivity = null;
+ Element child = getFirstExtensibilityElementElement();
+ if (child != null) {
+ _childActivity = new Activity(getFirstExtensibilityElementElement());
+ }
+ }
+
+ @Override
+ public Expression getJoinCondition() {
+ if (_childActivity == null) {
+ return null;
+ }
+ return _childActivity.getJoinCondition();
+ }
+
+ @Override
+ public List<LinkSource> getLinkSources() {
+ if (_childActivity == null) {
+ return Collections.emptyList();
+ }
+ return _childActivity.getLinkSources();
+ }
+
+ @Override
+ public List<LinkTarget> getLinkTargets() {
+ if (_childActivity == null) {
+ return Collections.emptyList();
+ }
+ return _childActivity.getLinkTargets();
+ }
+
+ @Override
+ public String getName() {
+ if (_childActivity == null) {
+ return null;
+ }
+ return _childActivity.getName();
+ }
+
+ @Override
+ public SuppressJoinFailure getSuppressJoinFailure() {
+ if (_childActivity == null) {
+ return SuppressJoinFailure.NOTSET;
+ }
+ return _childActivity.getSuppressJoinFailure();
+ }
+
+ @Override
+ public List<Activity> getActivities() {
+ if (_childActivity == null) {
+ return Collections.emptyList();
+ }
+
+ return _childActivity.getChildren(Activity.class);
+ }
+
+ public Element getNestedElement() {
+ return getFirstExtensibilityElementElement();
+ }
+
+}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionAssignOperation.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionAssignOperation.java
new file mode 100644
index 0000000..6a18cdf
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionAssignOperation.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.compiler.bom;
+
+import org.apache.ode.bpel.compiler.bom.AssignActivity.AssignOperation;
+import org.apache.ode.bpel.extension.ExtensibleElement;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * BOM representation of the BPEL <code><extensionAssignOperation></code>.
+ *
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class ExtensionAssignOperation extends BpelObject implements
+ AssignOperation, ExtensibleElement {
+ private Element _childElement;
+
+ public ExtensionAssignOperation(Element el) {
+ super(el);
+ }
+
+ public Element getNestedElement() {
+ // XXX
+ // return getFirstExtensibilityElement();
+ if (_childElement == null) {
+ NodeList nl = getElement().getChildNodes();
+ for (int i = 0; i < nl.getLength(); ++i) {
+ Node node = nl.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE
+ && !Bpel20QNames.NS_WSBPEL2_0.equals(node
+ .getNamespaceURI())) {
+ _childElement = (Element) node;
+ break;
+ }
+ }
+ }
+ return _childElement;
+ }
+
+}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extensions.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extensions.java
new file mode 100644
index 0000000..5f7365b
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extensions.java
@@ -0,0 +1,34 @@
+/*
+ * 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.compiler.bom;
+
+import org.w3c.dom.Element;
+
+/**
+ * BOM representation of the BPEL <code><extension></code> element.
+ *
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class Extensions extends BpelObject {
+
+ public Extensions(Element el) {
+ super(el);
+ }
+
+}
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java
index 694c10c..017c175 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java
@@ -20,6 +20,7 @@
import org.w3c.dom.Element;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -111,4 +112,16 @@
return getChildren(Import.class);
}
+ /**
+ * Get the <code><extensions></code>(s) of the process.
+ *
+ * @return {@link Set} of {@link Extension}s
+ */
+ public List<Extension> getExtensions() {
+ Extensions extensions = getFirstChild(Extensions.class);
+ if (extensions == null)
+ return Collections.emptyList();
+ return extensions.getChildren(Extension.class);
+
+ }
}
diff --git a/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java b/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java
index 57f6ea4..df00dac 100644
--- a/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java
+++ b/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java
@@ -44,6 +44,7 @@
import org.apache.ode.bpel.elang.xpath10.compiler.XPath10ExpressionCompilerBPEL20Draft;
import org.apache.ode.bpel.elang.xpath20.compiler.XPath20ExpressionCompilerBPEL20;
import org.apache.ode.bpel.elang.xpath20.compiler.XPath20ExpressionCompilerBPEL20Draft;
+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;
@@ -301,4 +302,12 @@
public NSContext tryCacheNamespaceContext(NSContext nsContext) {
return nsContext;
}
+
+ public boolean isExtensionDeclared(String namespace) {
+ return false;
+ }
+
+ public ExtensionValidator getExtensionValidator(QName extensionElementName) {
+ return null;
+ }
}
diff --git a/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java b/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java
index c03edf6..abfc50f 100644
--- a/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java
+++ b/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java
@@ -112,6 +112,10 @@
public static final String DEFAULT_CLUSTERING_IMPL_CLASS_NAME = "org.apache.ode.clustering.hazelcast.HazelcastClusterImpl";
+ public static final String PROP_EXTENSION_BUNDLES_RT = "extension.bundles.runtime";
+
+ public static final String PROP_EXTENSION_BUNDLES_VAL = "extension.bundles.validation";
+
private File _cfgFile;
private String _prefix;
@@ -384,4 +388,11 @@
return Integer.valueOf(getProperty(PROP_MIGRATION_TRANSACTION_TIMEOUT, String.valueOf(0)));
}
+ public String getExtensionActivityBundlesRT() {
+ return getProperty(PROP_EXTENSION_BUNDLES_RT);
+ }
+
+ public String getExtensionActivityBundlesValidation() {
+ return getProperty(PROP_EXTENSION_BUNDLES_VAL);
+ }
}
diff --git a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java
index 8db6375..b0b5868 100644
--- a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java
+++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java
@@ -32,36 +32,37 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
-public class OAssign extends OActivity implements Serializable{
+public class OAssign extends OActivity implements Serializable {
public static final long serialVersionUID = -1L;
- private static final String COPY = "copy";
+ private static final String OPERATION = "operation";
@JsonCreator
public OAssign(){
}
+
public OAssign(OProcess owner, OActivity parent) {
super(owner, parent);
- setCopy(new ArrayList<Copy>());
+ setOperations(new ArrayList<OAssignOperation>());
}
@Override
public void dehydrate() {
super.dehydrate();
- for (Copy copy : getCopy()) {
- copy.dehydrate();
+ for (OAssignOperation operation : getOperations()) {
+ operation.dehydrate();
}
}
@SuppressWarnings("unchecked")
@JsonIgnore
- public List<Copy> getCopy() {
- Object o = fieldContainer.get(COPY);
- return o == null ? null : (List<Copy>)o;
+ public List<OAssignOperation> getOperations() {
+ Object o = fieldContainer.get(OPERATION);
+ return o == null ? null : (List<OAssignOperation>)o;
}
- public void setCopy(List<Copy> copy) {
- if (getCopy() == null){
- fieldContainer.put(COPY, copy);
+ public void setOperations(List<OAssignOperation> operation) {
+ if (getOperations() == null){
+ fieldContainer.put(OPERATION, operation);
}
}
@@ -69,12 +70,31 @@
return "{OAssign : " + getName() + ", joinCondition="
+ getJoinCondition() + "}";
}
+
+ /**
+ * Base class for assign operations.
+ */
+ public static abstract class OAssignOperation extends OBase implements Serializable {
+ private static final long serialVersionUID = -3042873658302758854L;
+
+ public enum Type { Copy, ExtensionOperation }
+
+ @JsonCreator
+ public OAssignOperation() {
+ }
+
+ public OAssignOperation(OProcess owner) {
+ super(owner);
+ }
+
+ public abstract Type getType();
+ }
/**
- * Assignmenet copy entry, i.e. what the assignment consits of.
+ * Assignment copy entry, i.e. what the assignment consists of.
*/
- public static class Copy extends OBase implements Serializable{
- public static final long serialVersionUID = -1L;
+ public static class Copy extends OAssignOperation implements Serializable {
+ public static final long serialVersionUID = -1L;
private static final String TO = "to";
private static final String FROM = "from";
private static final String KEEPSRCELEMENTNAME = "keepSrcElementName";
@@ -86,10 +106,12 @@
public Copy(){
initPrimitive();
}
+
public Copy(OProcess owner) {
super(owner);
initPrimitive();
}
+
private void initPrimitive(){
setIgnoreMissingFromData(false);
setIgnoreUninitializedFromVariable(false);
@@ -107,13 +129,13 @@
@JsonIgnore
public RValue getFrom() {
Object o = fieldContainer.get(FROM);
- return o == null ? null : (RValue)o;
+ return o == null ? null : (RValue)o;
}
@JsonIgnore
public boolean isIgnoreMissingFromData() {
Object o = fieldContainer.get(IGNOREMISSINGFROMDATA);
- return o == null ? false : (Boolean)o;
+ return o == null ? false : (Boolean)o;
}
@JsonIgnore
@@ -125,19 +147,19 @@
@JsonIgnore
public boolean isInsertMissingToData() {
Object o = fieldContainer.get(INSERTMISSINGTODATA);
- return o == null ? false : (Boolean)o;
+ return o == null ? false : (Boolean)o;
}
@JsonIgnore
public boolean isKeepSrcElementName() {
Object o = fieldContainer.get(KEEPSRCELEMENTNAME);
- return o == null ? false : (Boolean)o;
+ return o == null ? false : (Boolean)o;
}
@JsonIgnore
public LValue getTo() {
Object o = fieldContainer.get(TO);
- return o == null ? null : (LValue)o;
+ return o == null ? null : (LValue)o;
}
public void setFrom(RValue from) {
@@ -169,7 +191,65 @@
public String toString() {
return "{OCopy " + getTo() + "=" + getFrom() + "}";
}
+
+ @JsonIgnore
+ public Type getType() {
+ return Type.Copy;
+ }
}
+
+ /**
+ * Assignment extension operation entry, i.e. what the assignment consists of.
+ */
+ public static class ExtensionAssignOperation extends OAssignOperation {
+ private static final long serialVersionUID = 1L;
+
+ private static final String EXTENSIONNAME = "extensionName";
+ private static final String NESTEDELEMENT = "nestedElement";
+
+ @JsonCreator
+ public ExtensionAssignOperation(){
+ }
+
+ public ExtensionAssignOperation(OProcess owner) {
+ super(owner);
+ }
+
+ @JsonIgnore
+ public QName getExtensionName() {
+ Object o = fieldContainer.get(EXTENSIONNAME);
+ return o == null ? null : (QName) o;
+ }
+
+ @JsonIgnore
+ public String getNestedElement() {
+ Object o = fieldContainer.get(NESTEDELEMENT);
+ return o == null ? null : (String)o;
+ }
+
+ public void setExtensionName(QName extensionName) {
+ fieldContainer.put(EXTENSIONNAME, extensionName);
+ }
+
+ public void setNestedElement(String nestedElement) {
+ fieldContainer.put(NESTEDELEMENT, nestedElement);
+ }
+
+ public String toString() {
+ return "{OExtensionAssignOperation; " + getExtensionName() + "}";
+ }
+
+ @Override
+ public void dehydrate() {
+ super.dehydrate();
+ setExtensionName(null);
+ setNestedElement(null);
+ }
+
+ public Type getType() {
+ return Type.ExtensionOperation;
+ }
+ }
/**
* Direct reference: selects named child of the message document element.
diff --git a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OExtensionActivity.java b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OExtensionActivity.java
new file mode 100644
index 0000000..2c3632a
--- /dev/null
+++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OExtensionActivity.java
@@ -0,0 +1,102 @@
+/*
+ * 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.obj;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * Compiled representation of the BPEL <code><extensionActivity></code>
+ * activity.
+ * <p>
+ * Adapted initial version for compatibility with new ODE object model (bpel-nobj).
+ *
+ * @author Tammo van Lessen (University of Stuttgart), Michael Hahn (mhahn.dev@gmail.com)
+ */
+public class OExtensionActivity extends OActivity implements Serializable {
+
+ static final long serialVersionUID = -1L;
+
+ private static final String EXTENSIONNAME = "extensionName";
+ private static final String NESTEDELEMENT = "nestedElement";
+ private static final String CHILDREN = "children";
+
+ @JsonCreator
+ public OExtensionActivity(){
+ }
+
+ public OExtensionActivity(OProcess owner, OActivity parent) {
+ super(owner, parent);
+ setChildren(new ArrayList<OActivity>());
+ }
+
+ @JsonIgnore
+ public QName getExtensionName() {
+ Object o = fieldContainer.get(EXTENSIONNAME);
+ return o == null ? null : (QName) o;
+ }
+
+ @JsonIgnore
+ public String getNestedElement() {
+ Object o = fieldContainer.get(NESTEDELEMENT);
+ return o == null ? null : (String)o;
+ }
+
+ @SuppressWarnings("unchecked")
+ @JsonIgnore
+ public List<OActivity> getChildren() {
+ Object o = fieldContainer.get(CHILDREN);
+ return o == null ? null : (List<OActivity>)o;
+ }
+
+ public void setExtensionName(QName extensionName) {
+ fieldContainer.put(EXTENSIONNAME, extensionName);
+ }
+
+ public void setNestedElement(String nestedElement) {
+ fieldContainer.put(NESTEDELEMENT, nestedElement);
+ }
+
+ void setChildren(List<OActivity> children) {
+ if (getChildren() == null) {
+ fieldContainer.put(CHILDREN, children);
+ }
+ }
+
+ public String toString() {
+ return "{OExtensionActivity; " + getExtensionName() + "}";
+ }
+
+ @Override
+ public void dehydrate() {
+ super.dehydrate();
+ setExtensionName(null);
+ setNestedElement(null);
+ for (OBase obase : getChildren()) {
+ obase.dehydrate();
+ }
+ getChildren().clear();
+ }
+}
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 2296210..d8f0e67 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
@@ -20,7 +20,6 @@
import java.io.IOException;
import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
@@ -92,7 +91,12 @@
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.
*/
@@ -114,6 +118,9 @@
setXsdTypes(new HashMap<QName, OXsdTypeVarType>());
setXslSheets(new HashMap<URI, OXslSheet>());
+ setDeclaredExtensions(new HashSet<OExtension>());
+ setMustUnderstandExtensions(new HashSet<OExtension>());
+
setChildIdCounter(0);
}
@@ -130,6 +137,8 @@
getElementTypes().clear();
getXsdTypes().clear();
getXslSheets().clear();
+ getDeclaredExtensions().clear();
+ getMustUnderstandExtensions().clear();
}
@Override
@@ -164,6 +173,7 @@
return o == null ? 0 : (Integer)o;
}
+ @SuppressWarnings("unchecked")
@JsonIgnore
public List<OBase> getChildren() {
Object o = fieldContainer.get(CHILDREN);
@@ -182,9 +192,9 @@
return o == null ? null : (OConstants)o;
}
+ @SuppressWarnings("rawtypes")
@ObjectDiffProperty(ignore = true)
@JsonIgnore
- @SuppressWarnings("unchecked")
public List<String> getCorrelators() {
// MOVED from ProcessSchemaGenerator
List<String> correlators = new ArrayList<String>();
@@ -311,6 +321,20 @@
Object o = fieldContainer.get(XSLSHEETS);
return o == null ? null : (HashMap<URI, OXslSheet>)o;
}
+
+ @SuppressWarnings("unchecked")
+ @JsonIgnore
+ public Set<OExtension> getDeclaredExtensions() {
+ return (Set<OExtension>) fieldContainer
+ .get(DECLAREDEXTENSIONS);
+ }
+
+ @SuppressWarnings("unchecked")
+ @JsonIgnore
+ public Set<OExtension> getMustUnderstandExtensions() {
+ return (Set<OExtension>) fieldContainer
+ .get(MUSTUNDERSTANDEXTENSIONS);
+ }
public void setAllPartnerLinks(Set<OPartnerLink> allPartnerLinks) {
if (getAllPartnerLinks() == null) {
@@ -398,6 +422,18 @@
fieldContainer.put(XSLSHEETS, xslSheets);
}
}
+
+ public void setDeclaredExtensions(Set<OExtension> extensions) {
+ if (getDeclaredExtensions() == null) {
+ fieldContainer.put(DECLAREDEXTENSIONS, extensions);
+ }
+ }
+
+ public void setMustUnderstandExtensions(Set<OExtension> extensions) {
+ if (getMustUnderstandExtensions() == null) {
+ fieldContainer.put(MUSTUNDERSTANDEXTENSIONS, extensions);
+ }
+ }
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
ois.defaultReadObject();
@@ -535,6 +571,42 @@
}
}
+
+ public static class OExtension extends OBase implements Serializable {
+ public static final long serialVersionUID = -1L ;
+
+ private static final String NAMESPACE = "namespaceURI";
+ private static final String MUSTUNDERSTAND = "mustUnderstand";
+
+ @JsonCreator
+ public OExtension(){}
+
+ public OExtension(OProcess process) { super(process); }
+
+ @JsonIgnore
+ public String getNamespace() {
+ Object o = fieldContainer.get(NAMESPACE);
+ return o == null ? null : (String)o;
+ }
+
+ @JsonIgnore
+ public boolean isMustUnderstand() {
+ Object o = fieldContainer.get(MUSTUNDERSTAND);
+ return o == null ? false : (Boolean)o;
+ }
+
+ public void setNamespace(String namespaceURI) {
+ fieldContainer.put(NAMESPACE, namespaceURI);
+ }
+
+ public void setMustUnderstand(boolean mustUnderstand) {
+ fieldContainer.put(MUSTUNDERSTAND, mustUnderstand);
+ }
+
+ public String toString() {
+ return "{OExtension " + getNamespace() + (isMustUnderstand() ? " mustUnderstand" : "") + "}";
+ }
+ }
/**
* custom deserializer of OProcess.
diff --git a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java
index 64248a3..5212a13 100644
--- a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java
+++ b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java
@@ -26,12 +26,13 @@
import org.apache.ode.bpel.o.OScope.Variable;
import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.SerializableElement;
import org.w3c.dom.Document;
public class OAssign extends OActivity {
static final long serialVersionUID = -1L ;
- public final List<Copy> copy = new ArrayList<Copy>();
+ public final List<OAssignOperation> operations = new ArrayList<OAssignOperation>();
public OAssign(OProcess owner, OActivity parent) {
super(owner, parent);
@@ -41,11 +42,26 @@
public String toString() {
return "{OAssign : " + name + ", joinCondition=" + joinCondition + "}";
}
+
+ /**
+ * Base class for assign operations.
+ */
+ public static abstract class OAssignOperation extends OBase {
+ private static final long serialVersionUID = -3042873658302758854L;
+
+ public enum Type { Copy, ExtensionOperation }
+
+ public OAssignOperation(OProcess owner) {
+ super(owner);
+ }
+
+ public abstract Type getType();
+ }
/**
* Assignmenet copy entry, i.e. what the assignment consits of.
*/
- public static class Copy extends OBase {
+ public static class Copy extends OAssignOperation {
private static final long serialVersionUID = 1L;
public LValue to;
public RValue from;
@@ -68,6 +84,38 @@
to = null;
from = null;
}
+
+ public Type getType() {
+ return Type.Copy;
+ }
+ }
+
+ /**
+ * Assignment extension operation entry, i.e. what the assignment consists of.
+ */
+ public static class ExtensionAssignOperation extends OAssignOperation {
+ private static final long serialVersionUID = 1L;
+ public SerializableElement nestedElement;
+ public QName extensionName;
+
+ public ExtensionAssignOperation(OProcess owner) {
+ super(owner);
+ }
+
+ public String toString() {
+ return "{OExtensionAssignOperation; " + nestedElement.getElement().getTagName() + "}";
+ }
+
+ @Override
+ public void dehydrate() {
+ super.dehydrate();
+ nestedElement = null;
+ extensionName = null;
+ }
+
+ public Type getType() {
+ return Type.ExtensionOperation;
+ }
}
public interface LValue {
@@ -255,8 +303,12 @@
@Override
public void dehydrate() {
super.dehydrate();
- for (Copy copy : this.copy) {
- copy.dehydrate();
+ for (OAssignOperation operation : this.operations) {
+ if (operation.getType().equals(OAssignOperation.Type.Copy)) {
+ ((Copy)operation).dehydrate();
+ } else if (operation.getType().equals(OAssignOperation.Type.ExtensionOperation)) {
+ ((ExtensionAssignOperation)operation).dehydrate();
+ }
}
}
}
diff --git a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OExtensionActivity.java b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OExtensionActivity.java
new file mode 100644
index 0000000..deb73cf
--- /dev/null
+++ b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OExtensionActivity.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.o;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ode.utils.SerializableElement;
+
+/**
+ * Compiled representation of the BPEL <code><extensionActivity></code>
+ * activity.
+ *
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class OExtensionActivity extends OActivity {
+
+ static final long serialVersionUID = -1L;
+ public final List<OActivity> children = new ArrayList<OActivity>();
+ public SerializableElement nestedElement;
+ public QName extensionName;
+
+ public OExtensionActivity(OProcess owner, OActivity parent) {
+ super(owner, parent);
+ }
+
+}
diff --git a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java
index 717b9e2..7b95919 100644
--- a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java
+++ b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java
@@ -76,6 +76,12 @@
public final HashMap<URI, OXslSheet> xslSheets = new HashMap<URI, OXslSheet>();
+ /** All declared extensions in the process. **/
+ public final Set<OExtension> declaredExtensions = new HashSet<OExtension>();
+
+ /** All must-understand extensions in the process. **/
+ public final Set<OExtension> mustUnderstandExtensions = new HashSet<OExtension>();
+
public OProcess(String bpelVersion) {
super(null);
this.version = bpelVersion;
@@ -114,12 +120,12 @@
return processName;
}
- @SuppressWarnings("unchecked")
- public Collection getExpressionLanguages() {
+ @SuppressWarnings("rawtypes")
+ public Collection getExpressionLanguages() {
throw new UnsupportedOperationException(); // TODO: implement me!
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
public List<String> getCorrelators() {
// MOVED from ProcessSchemaGenerator
List<String> correlators = new ArrayList<String>();
@@ -186,6 +192,18 @@
}
}
+
+ public static class OExtension extends OBase {
+ static final long serialVersionUID = -1L ;
+ public String namespaceURI;
+ public boolean mustUnderstand;
+
+ public OExtension(OProcess process) { super(process); }
+
+ public String toString() {
+ return "{OExtension " + namespaceURI + (mustUnderstand ? " mustUnderstand" : "") + "}";
+ }
+ }
public QName getQName() {
return new QName(targetNamespace, processName);
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.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 @@
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 @@
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 @@
// }
_replacementMap = null;
_expLangRuntimeRegistry = null;
+ _extensionRegistry = null;
}
private void doHydrate() {
@@ -1000,6 +1008,25 @@
_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();
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.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 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;
+ }
+ }
+ }
}
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.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 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 @@
__log.debug("Registering process " + conf.getProcessId() + " with server.");
BpelProcess process = createBpelProcess(conf);
+
+ process.setExtensionRegistry(_contexts.extensionRegistry);
process._classLoader = Thread.currentThread().getContextClassLoader();
_engine.registerProcess(process);
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.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 CustomProcessProperties customProcessProperties = new CustomProcessProperties();
+ /** Global extension bundle registry **/
+ final Map<String, ExtensionBundleRuntime> extensionRegistry = new ConcurrentHashMap<String, ExtensionBundleRuntime>();
+
}
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 @@
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);
+ }
}
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.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.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 @@
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 @@
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;
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 @@
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);
}
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 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 @@
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);
}
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
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);
+ }
+}
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;
+
+}
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><extensionActivity></code> and
+ * <code><extensionAssignOperation></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><extensionActivity></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;
+ }
+}
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;
+ }
+ }
+
+}
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");
+
+}
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);
+}
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.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 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;
+ }
}
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.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 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;
+ }
}
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.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 @@
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 @@
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 @@
return result;
}
+ public void setExtensionValidators(Map<QName, ExtensionValidator> extensionValidators) {
+ _extensionValidators = extensionValidators;
+ }
+
public final class CBPInfo {
final QName processName;
final String guid;
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.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 @@
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 @@
// 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 @@
}
return undeployed;
}
+
+ public void setExtensionValidators(
+ Map<QName, ExtensionValidator> extensionValidators) {
+ _extensionValidators = extensionValidators;
+ }
+
+ public Map<QName, ExtensionValidator> getExtensionValidators() {
+ return _extensionValidators;
+ }
}
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.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 @@
registerMexInterceptors();
+ registerExtensionActivityBundles();
+
registerMBean();
__log.debug("Starting JCA connector.");
@@ -367,6 +372,61 @@
}
}
}
+
+ // @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)
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 @@
}
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();