You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by ms...@apache.org on 2007/11/08 20:02:48 UTC

svn commit: r593256 - in /ode/branches/extvar: bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ bpel-obj/src/main/java/org/apache/ode/bpel/o/ bpel-runtime/src/main/java/org/apache/o...

Author: mszefler
Date: Thu Nov  8 11:02:38 2007
New Revision: 593256

URL: http://svn.apache.org/viewvc?rev=593256&view=rev
Log:
experimental:external variables
* added apache license headers
* add missing files to svn
* refactoring of variable init
* more informative error messages
* integration test


Added:
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableConf.java   (with props)
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableKeyMapSerializer.java   (with props)
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableManager.java   (with props)
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/extvar/
    ode/branches/extvar/bpel-runtime/src/test/java/org/apache/ode/bpel/extvar/
    ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/
    ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/ExtVar.xsd   (with props)
    ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.bpel
    ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.wsdl   (with props)
    ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/deploy.xml   (with props)
    ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/test.properties   (with props)
Removed:
    ode/branches/extvar/bpel-runtime/src/test/java/org/apache/ode/bpel/evar/
Modified:
    ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
    ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
    ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
    ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java
    ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Variable.java
    ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OBase.java
    ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java
    ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OVarType.java
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/FOREACH.java
    ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/SCOPE.java
    ode/branches/extvar/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java
    ode/branches/extvar/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
    ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java
    ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BindingContextImpl.java
    ode/branches/extvar/utils/src/main/java/org/apache/ode/utils/DOMUtils.java

Modified: ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java (original)
+++ ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java Thu Nov  8 11:02:38 2007
@@ -36,6 +36,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.ExtVarKeyMapping;
 import org.apache.ode.bpel.compiler.bom.FaultHandler;
 import org.apache.ode.bpel.compiler.bom.Import;
 import org.apache.ode.bpel.compiler.bom.LinkSource;
@@ -67,6 +68,7 @@
 import org.apache.ode.bpel.o.OEventHandler;
 import org.apache.ode.bpel.o.OExpression;
 import org.apache.ode.bpel.o.OExpressionLanguage;
+import org.apache.ode.bpel.o.OExtVar;
 import org.apache.ode.bpel.o.OFaultHandler;
 import org.apache.ode.bpel.o.OFlow;
 import org.apache.ode.bpel.o.OLValueExpression;
@@ -92,6 +94,7 @@
 import org.apache.ode.utils.stl.MemberOfFunction;
 import org.apache.ode.utils.stl.UnaryFunction;
 import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
 import javax.wsdl.Definition;
@@ -1341,12 +1344,16 @@
         ovar.name = src.getName();
         ovar.declaringScope = oscope;
         ovar.debugInfo = createDebugInfo(src, null);
+        
+        ovar.extVar = compileExtVar(src);
+
         oscope.addLocalVariable(ovar);
 
         if (__log.isDebugEnabled())
             __log.debug("Compiled variable " + ovar);
     }
 
+
     private void compile(TerminationHandler terminationHandler) {
         OScope oscope = _structureStack.topScope();
         oscope.terminationHandler = new OTerminationHandler(_oprocess, oscope);
@@ -1615,6 +1622,27 @@
         ArrayList<OActivity> rval = new ArrayList<OActivity>(_structureStack._stack);
         Collections.reverse(rval);
         return rval;
+    }
+
+    /**
+     * Compile external variable declaration.
+     * @param src variable object
+     * @return compiled {@link OExtVar} representation. 
+     */
+    private OExtVar compileExtVar(Variable src) {
+        if (!src.isExternal())
+            return null;
+
+        OExtVar oextvar = new OExtVar(_oprocess);
+        oextvar.externalVariableId = src.getExternalId();
+        oextvar.debugInfo = createDebugInfo(src, null);
+        for (ExtVarKeyMapping mapping : src.getExtVarMappings()) {
+            String key = mapping.getKey();
+            OExpression oexpr = compileExpr(mapping.getExpression());
+            oextvar.keyDeclaration.put(key, oexpr);
+        }
+        
+        return oextvar;
     }
 
     private static class StructureStack {

Modified: ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java (original)
+++ ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java Thu Nov  8 11:02:38 2007
@@ -187,6 +187,12 @@
     public static final String NS_RDF = "http://www.w3.org/2000/01/rdf-schema#";
     public static final QName RDF_LABEL = new QName(NS_RDF, "label");
 
+
+    
+    //
+    // utility functions
+    //
+    
     private static QName newQName(String localname) {
         return new QName(NS_WSBPEL2_0, localname);
     }

Modified: ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java (original)
+++ ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java Thu Nov  8 11:02:38 2007
@@ -255,6 +255,11 @@
         _mappings.put(ExtensibilityQNames.FAILURE_HANDLING_RETRY_FOR, FailureHandling.RetryFor.class);
         _mappings.put(ExtensibilityQNames.FAILURE_HANDLING_RETRY_DELAY, FailureHandling.RetryDelay.class);
         _mappings.put(ExtensibilityQNames.FAILURE_HANDLING_FAULT_ON, FailureHandling.FaultOnFailure.class);
+        
+        //
+        // External Variable Mappings
+        //
+        _mappings.put(ExtensibilityQNames.EXTVAR_MAPPING, ExtVarKeyMapping.class);
     }
 
     public static BpelObjectFactory getInstance() {

Modified: ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java (original)
+++ ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensibilityQNames.java Thu Nov  8 11:02:38 2007
@@ -22,7 +22,7 @@
 
 
 public abstract class ExtensibilityQNames {
-    /**
+    /*
      * Activity Recovery extensibility elements.
      */
     public static final String NS_ACTIVITY_RECOVERY         = "http://ode.apache.org/activityRecovery";
@@ -30,6 +30,21 @@
     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");
+
+
+
+    //
+    // External variables 
+    //
+    
+    /** Namespace for external variables. */
+    private static final String EXTVAR_NS = "http://www.apache.org/ode/extensions/externalVariables";
+    
+    /** Attribute name for external variable id. */
+    public static final QName EXTVAR_ATTR = new QName(EXTVAR_NS, "ext-var-id");
+    
+    /** Element name of external variable key mapping. */
+    public static final QName EXTVAR_MAPPING = new QName(EXTVAR_NS, "key-map");
 
 }
 

Modified: ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Variable.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Variable.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Variable.java (original)
+++ ode/branches/extvar/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Variable.java Thu Nov  8 11:02:38 2007
@@ -18,6 +18,8 @@
  */
 package org.apache.ode.bpel.compiler.bom;
 
+import java.util.List;
+
 import javax.xml.namespace.QName;
 
 import org.w3c.dom.Element;
@@ -87,4 +89,30 @@
 
     }
 
+    //
+    // Stuff related to external variables.
+    //
+    
+    /**
+     * Get the external variable identifier (each one will be defined in the deployment descriptor)
+     */
+    public String getExternalId() {
+        return getAttribute(ExtensibilityQNames.EXTVAR_ATTR, null);
+    }
+
+    /**
+     * Is this an external variable? It is if it has the above attribute.
+     * @return
+     */
+    public boolean isExternal() {
+        return null != getExternalId();
+    }
+    
+    /**
+     * Get the external variable mappings.
+     * @return
+     */
+    public List<ExtVarKeyMapping> getExtVarMappings() {
+        return getChildren(ExtVarKeyMapping.class);
+    }
 }

Modified: ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OBase.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OBase.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OBase.java (original)
+++ ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OBase.java Thu Nov  8 11:02:38 2007
@@ -18,8 +18,6 @@
  */
 package org.apache.ode.bpel.o;
 
-import org.apache.ode.utils.ObjectPrinter;
-
 import java.io.Serializable;
 
 

Modified: ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java (original)
+++ ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java Thu Nov  8 11:02:38 2007
@@ -21,6 +21,8 @@
 
 import java.util.*;
 
+import org.w3c.dom.Node;
+
 /**
  * Compiled representation of a BPEL scope. Instances of this class
  * are generated by the BPEL compiler.
@@ -169,6 +171,10 @@
         public OScope declaringScope;
         public OVarType type;
 
+        /** If not-null indicates that this variable has an external representation. */
+        public OExtVar extVar;
+        
+        
         public Variable(OProcess owner, OVarType type) {
             super(owner);
             this.type = type;

Modified: ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OVarType.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OVarType.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OVarType.java (original)
+++ ode/branches/extvar/bpel-obj/src/main/java/org/apache/ode/bpel/o/OVarType.java Thu Nov  8 11:02:38 2007
@@ -36,4 +36,5 @@
      */
     public abstract Node newInstance(Document doc);  
   
+    
 }

Modified: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java (original)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java Thu Nov  8 11:02:38 2007
@@ -45,6 +45,8 @@
 import org.apache.ode.bpel.dao.MessageRouteDAO;
 import org.apache.ode.bpel.dao.ProcessDAO;
 import org.apache.ode.bpel.dao.ProcessInstanceDAO;
+import org.apache.ode.bpel.engine.extvar.ExternalVariableConf;
+import org.apache.ode.bpel.engine.extvar.ExternalVariableManager;
 import org.apache.ode.bpel.evt.ProcessInstanceEvent;
 import org.apache.ode.bpel.evt.ScopeEvent;
 import org.apache.ode.bpel.explang.ConfigurationException;
@@ -69,6 +71,7 @@
 import org.apache.ode.bpel.intercept.MessageExchangeInterceptor;
 import org.apache.ode.bpel.memdao.BpelDAOConnectionFactoryImpl;
 import org.apache.ode.bpel.o.OExpressionLanguage;
+import org.apache.ode.bpel.o.OExtVar;
 import org.apache.ode.bpel.o.OPartnerLink;
 import org.apache.ode.bpel.o.OProcess;
 import org.apache.ode.bpel.o.Serializer;
@@ -142,13 +145,16 @@
 
     private final BpelDAOConnectionFactoryImpl _inMemDao;
 
-    private Random _random = new Random();
-
     final BpelServerImpl _server;
 
     /** Weak-reference cache of all the my-role message exchange objects. */
     final private MyRoleMessageExchangeCache _myRoleMexCache = new MyRoleMessageExchangeCache(this);
 
+    /** Deploy-time configuraton for external variables. */
+    private ExternalVariableConf _extVarConf;
+    
+    private ExternalVariableManager _evm;
+
     BpelProcess(BpelServerImpl server, ProcessConf conf, BpelEventListener debugger) {
         _server = server;
         _pid = conf.getProcessId();
@@ -168,12 +174,30 @@
         }
 
         _invocationStyles = Collections.unmodifiableSet(istyles);
+        
+    }
+
+    /**
+     * Intiialize the external variable configuration/engine manager. This is called from hydration logic, so it 
+     * is possible to change the external variable configuration at runtime.
+     * 
+     */
+    void initExternalVariables() {
+        List<Element> conf = _pconf.getExtensionElement(ExternalVariableConf.EXTVARCONF_ELEMENT);
+        _extVarConf = new ExternalVariableConf(conf);
+        _evm = new ExternalVariableManager(_pid, _extVarConf, _contexts.externalVariableEngines, _oprocess);
     }
+    
 
     public String toString() {
         return "BpelProcess[" + _pid + "]";
     }
 
+    public ExternalVariableManager getEVM() {
+        return _evm;
+    }
+   
+
     void recoverActivity(ProcessInstanceDAO instanceDAO, final String channel, final long activityId, final String action,
             final FaultData fault) {
         if (__log.isDebugEnabled())
@@ -1187,6 +1211,8 @@
 
             setRoles(_oprocess);
 
+            initExternalVariables();
+
             if (!_hydratedOnce) {
                 for (PartnerLinkPartnerRoleImpl prole : _partnerRoles.values()) {
                     PartnerRoleChannel channel = _contexts.bindingContext.createPartnerRoleChannel(_pid,
@@ -1359,5 +1385,7 @@
             throw new BpelEngineException(ex);
         }
     }
+
+
 
 }

Modified: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java (original)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java Thu Nov  8 11:02:38 2007
@@ -23,7 +23,9 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.wsdl.Operation;
 import javax.xml.namespace.QName;
@@ -42,7 +44,13 @@
 import org.apache.ode.bpel.dao.ProcessInstanceDAO;
 import org.apache.ode.bpel.dao.ScopeDAO;
 import org.apache.ode.bpel.dao.XmlDataDAO;
-import org.apache.ode.bpel.evt.*;
+import org.apache.ode.bpel.engine.extvar.ExternalVariableKeyMapSerializer;
+import org.apache.ode.bpel.evt.CorrelationSetWriteEvent;
+import org.apache.ode.bpel.evt.ProcessCompletionEvent;
+import org.apache.ode.bpel.evt.ProcessInstanceEvent;
+import org.apache.ode.bpel.evt.ProcessInstanceStateChangeEvent;
+import org.apache.ode.bpel.evt.ProcessMessageExchangeEvent;
+import org.apache.ode.bpel.evt.ProcessTerminationEvent;
 import org.apache.ode.bpel.iapi.BpelEngineException;
 import org.apache.ode.bpel.iapi.ContextException;
 import org.apache.ode.bpel.iapi.EndpointReference;
@@ -79,9 +87,11 @@
 import org.apache.ode.utils.GUID;
 import org.apache.ode.utils.Namespaces;
 import org.apache.ode.utils.ObjectPrinter;
+import org.apche.ode.bpel.evar.ExternalVariableModuleException;
+import org.apche.ode.bpel.evar.IncompleteKeyException;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.Document;
 
 /**
  * 
@@ -404,10 +414,52 @@
 
         if (dataDAO.isNull()) {
             throw new FaultException(_bpelProcess.getOProcess().constants.qnUninitializedVariable, "The variable "
-                    + variable.declaration.name + " isn't properly initialized.");
+                    + variable.declaration.name + " has not been properly initialized.");
         }
+        
+        if (variable.declaration.extVar != null) {
+            // Note, that when using external variables, the database will contain not the actual value of the 
+            // variable, but a name-value map used to uniquely identify the external variable instance.  
+            Map<String, String> keys = ExternalVariableKeyMapSerializer.toMap((Element)dataDAO.get());
+            try {
+                Node ret = _bpelProcess.getEVM().read(variable.declaration.extVar.externalVariableId, keys ,_iid);
+                if (ret == null) {
+                    throw new FaultException(_bpelProcess.getOProcess().constants.qnUninitializedVariable, 
+                            "The external variable \"" + variable.declaration.name + "\" has not been initialized.");
+                    
+                }
+                return ret;
+            } catch (IncompleteKeyException ike) {
+                // This indicates that the external variable needed to be written do, put has not been.
+                __log.error("External variable could not be read due to incomplete key; the following key " +
+                        "components were missing: " + ike.getMissing());
+                throw new FaultException(_bpelProcess.getOProcess().constants.qnUninitializedVariable, 
+                        "The extenral variable \"" + variable.declaration.name + "\" has not been properly initialized;" +
+                                "the following key compoenents were missing:" + ike.getMissing());
+            } catch (ExternalVariableModuleException e) {
+                __log.error("Unexpected EVM error.", e);
+                throw new BpelEngineException(e);
+            }
 
-        return dataDAO.get();
+        } else /* not external */ {
+            return dataDAO.get();
+        }
+        // unreachable;
+    }
+
+    /**
+     * Save the external variable keys that are evaluated at the time of scope instantiation.
+     */
+    public void initializeExternalVariable(VariableInstance variable, HashMap<String, String> keys) {
+        // Important to note here that the collection of keys that we are saving may not be
+        // the whole set required to retrieve the object. If that's the case then the variable
+        // will need to be assigned to before it can be read, at which point the keys will be
+        // updated. However if the key set is complete, then the variable can be read even if it
+        // was never written to in the process.
+        Element el = ExternalVariableKeyMapSerializer.toXML(keys);
+        ScopeDAO scopeDAO = _dao.getScope(variable.scopeInstance);
+        XmlDataDAO dataDAO = scopeDAO.getVariable(variable.declaration.name);
+        dataDAO.set(el);
     }
 
     public Node fetchVariableData(VariableInstance var, OMessageVarType.Part part, boolean forWriting) throws FaultException {
@@ -476,9 +528,35 @@
         ScopeDAO scopeDAO = _dao.getScope(variable.scopeInstance);
         XmlDataDAO dataDAO = scopeDAO.getVariable(variable.declaration.name);
 
-        dataDAO.set(initData);
-        writeProperties(variable, initData, dataDAO);        
-        return dataDAO.get();
+        Node ret;
+        
+        if (variable.declaration.extVar != null) /*external variable */ {
+            // Note, that when using external variables, the database will contain not the actual value of the 
+            // variable, but a name-value map used to uniquely identify the external variable instance. When 
+            // initializing the external variable, we need to:
+            // 1) call the ext-var subystem to initialize the variable
+            // 3) save the computed keys (modified by 1 above) in the database. 
+
+            Map<String, String> keys = ExternalVariableKeyMapSerializer.toMap((Element)dataDAO.get());
+            // Note that keys gets modified by initExternalVariable
+            try {
+                ret = _bpelProcess.getEVM().write(variable.declaration.extVar.externalVariableId, keys, initData, _iid);
+            } catch (ExternalVariableModuleException e) {
+                __log.error("External variable initialization error.", e);
+                // TODO: need to report this
+                throw new BpelEngineException("External varaible initialization error", e);
+            }
+            Element xmlkey = ExternalVariableKeyMapSerializer.toXML(keys);
+            dataDAO.set(xmlkey);
+                        
+        } else /* normal variable */ {
+            dataDAO.set(initData);
+            ret = dataDAO.get();
+        }
+        
+        writeProperties(variable, ret, dataDAO);        
+        
+        return ret;
     }
 
     public void writeEndpointReference(PartnerLinkInstance variable, Element data) throws FaultException {
@@ -1184,4 +1262,5 @@
     public void forceFlush() {
         _forceFlush = true;
     }
+
 }

Modified: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java (original)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelServerImpl.java Thu Nov  8 11:02:38 2007
@@ -64,6 +64,7 @@
 import org.apache.ode.utils.msg.MessageBundle;
 import org.apache.ode.utils.stl.CollectionsX;
 import org.apache.ode.utils.stl.MemberOfFunction;
+import org.apche.ode.bpel.evar.ExternalVariableModule;
 
 /**
  * <p>
@@ -103,6 +104,7 @@
     /** Mapping from myrole service name to active process. */
     private final HashMap<QName, BpelProcess> _serviceMap = new HashMap<QName, BpelProcess>();
 
+
     private State _state = State.SHUTDOWN;
 
     Contexts _contexts = new Contexts();
@@ -209,6 +211,11 @@
             _mngmtLock.writeLock().unlock();
         }
     }
+    
+    
+    public void registerExternalVariableEngine(ExternalVariableModule eve) {
+        _contexts.externalVariableEngines.put(eve.getName(), eve);
+    }
 
     /**
      * Register a global listener to receive {@link BpelEvent}s froom all processes.
@@ -419,7 +426,8 @@
             return true;
         if (_state == j)
             return false;
-        throw new IllegalStateException("Unexpected state: " + i);
+        return false;
+//        throw new IllegalStateException("Unexpected state: " + i);
     }
 
     /* TODO: We need to have a method of cleaning up old deployment data. */

Modified: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java (original)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/Contexts.java Thu Nov  8 11:02:38 2007
@@ -30,7 +30,9 @@
 import org.apache.ode.bpel.iapi.MessageExchangeContext;
 import org.apache.ode.bpel.iapi.Scheduler;
 import org.apache.ode.bpel.intercept.MessageExchangeInterceptor;
+import org.apche.ode.bpel.evar.ExternalVariableModule;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -39,6 +41,7 @@
 import javax.transaction.Synchronization;
 import javax.transaction.SystemException;
 import javax.transaction.TransactionManager;
+import javax.xml.namespace.QName;
 
 /**
  * Aggregation of all the contexts provided to the BPEL engine by the integration layer.
@@ -64,6 +67,9 @@
     /** Global event listeners. Must be copy-on-write!!! */
     final List<BpelEventListener> eventListeners = new CopyOnWriteArrayList<BpelEventListener>();
 
+    /** Mapping from external variable engine identifier to the engine implementation. */
+    final HashMap<QName, ExternalVariableModule> externalVariableEngines = new HashMap<QName, ExternalVariableModule>();
+    
     public boolean isTransacted() {
         try {
             return txManager.getStatus() == Status.STATUS_ACTIVE;

Added: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableConf.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableConf.java?rev=593256&view=auto
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableConf.java (added)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableConf.java Thu Nov  8 11:02:38 2007
@@ -0,0 +1,84 @@
+/*
+ * 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.engine.extvar;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ode.bpel.iapi.BpelEngineException;
+import org.apache.ode.utils.DOMUtils;
+import org.w3c.dom.Element;
+
+public class ExternalVariableConf {
+    public final static QName EXTVARCONF_ELEMENT = new QName("http://www.apache.org/ode/extensions/externalVariables", 
+            "externalVariable");
+    
+    
+    private final HashMap<String,Variable> _vars = new HashMap<String, Variable>();
+    
+    public ExternalVariableConf(List<Element> els) {
+        
+        for (Element el : els) {
+            String varId = el.getAttribute("id");
+            if (varId == null || "".equals(varId))
+                throw new BpelEngineException("Invalid external variable configuration; id not specified.");
+            if (_vars.containsKey(varId))
+                throw new BpelEngineException("Invalid external variable configuration; duplicate id \""+  varId + " \".");
+
+
+            Element child = DOMUtils.getFirstChildElement(el);
+            if (child == null)
+                throw new BpelEngineException("Invalid external variable configuration for id \"" + varId + "\"; no engine configuration!");
+            
+            QName engineQName = new QName(child.getNamespaceURI(), child.getLocalName());
+            
+            Variable var = new Variable(varId, engineQName, child);
+            _vars.put(varId,var);
+        }
+        
+    }
+
+    
+    public class Variable {
+        public final String extVariableId;
+        public final QName engineQName;
+        public final Element configuration; 
+        
+        Variable(String id, QName engine, Element config) {
+            this.extVariableId = id;
+            this.engineQName = engine;
+            this.configuration = config;
+            
+        }
+    }
+
+
+    public Variable getVariable(String id) {
+        return _vars.get(id);
+    }
+    
+    public Collection<Variable> getVariables() {
+        return _vars.values();
+    }
+
+
+}

Propchange: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableConf.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableKeyMapSerializer.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableKeyMapSerializer.java?rev=593256&view=auto
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableKeyMapSerializer.java (added)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableKeyMapSerializer.java Thu Nov  8 11:02:38 2007
@@ -0,0 +1,80 @@
+/*
+ * 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.engine.extvar;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ode.utils.DOMUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Provides methods to serialize (into XML) the name-value pairs of an external-variable key map. 
+ * 
+ * @author Maciej Szefler <mszefler at gmail dot com>
+ *
+ */
+public class ExternalVariableKeyMapSerializer {
+
+    /**
+     * Convert to XML from map.
+     * @param map
+     * @return
+     */
+    public static Element toXML(Map<String,String> map) {
+        Document doc = DOMUtils.newDocument();
+        Element el = doc.createElementNS(null,"external-variable-ref");
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            Element nvel = doc.createElementNS(null,"nvpair");
+            nvel.setAttribute("key", entry.getKey());
+            if (entry.getValue() != null)
+                nvel.setAttribute("value", entry.getValue());
+            el.appendChild(nvel);
+        }
+        return el;
+        
+    }
+    
+    /**
+     * Convert to map from XML.
+     * @param el
+     * @return
+     */
+    public static Map<String, String> toMap(Element el) {
+        HashMap<String,String> ret = new HashMap<String,String>();
+        if (el == null)
+            return ret;
+        NodeList nvs = el.getChildNodes();
+        for (int i = 0; i < nvs.getLength(); ++i) {
+            Node n = nvs.item(i);
+            if (n.getNodeType() != Node.ELEMENT_NODE)
+                continue;
+            if (!n.getLocalName().equals("nvpair"))
+                continue;
+            String key = ((Element)n).getAttribute("key");
+            String val = ((Element)n).getAttribute("value");
+            ret.put(key, val);
+        }
+        return ret;
+    }
+
+}

Propchange: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableKeyMapSerializer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableManager.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableManager.java?rev=593256&view=auto
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableManager.java (added)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableManager.java Thu Nov  8 11:02:38 2007
@@ -0,0 +1,184 @@
+/*
+ * 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.engine.extvar;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.iapi.BpelEngineException;
+import org.apache.ode.bpel.o.OBase;
+import org.apache.ode.bpel.o.OProcess;
+import org.apache.ode.bpel.o.OScope;
+import org.apche.ode.bpel.evar.ExternalVariableModule;
+import org.apche.ode.bpel.evar.ExternalVariableModuleException;
+import org.apche.ode.bpel.evar.IncompleteKeyException;
+import org.apche.ode.bpel.evar.ExternalVariableModule.Locator;
+import org.apche.ode.bpel.evar.ExternalVariableModule.Value;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Manager for external variable instances; used by {@link BpelProcess} to manage external variables.
+ * 
+ * @author Maciej Szefler <mszefler at gmail dot com>
+ *
+ */
+public class ExternalVariableManager {
+
+    private static final Log __log = LogFactory.getLog(ExternalVariableManager.class);
+
+    /** Mapping of engine names to engine. */
+    private Map<QName, ExternalVariableModule> _engines;
+
+    /** Mapping between external variable identifiers and the engines that are used to serve them up. */
+    private final Map<String, EVar> _externalVariables = new HashMap<String, EVar>();
+
+    /** The configuration. */
+    private final ExternalVariableConf _extVarConf;
+
+    /** Process ID */
+    private QName _pid;
+
+    public ExternalVariableManager(QName pid,
+            ExternalVariableConf evconf, 
+            Map<QName, ExternalVariableModule> engines, 
+            OProcess oprocess)
+            throws BpelEngineException {
+        _pid = pid;
+        _extVarConf = evconf;
+        _engines = engines;
+
+        boolean fatal = false;
+
+        // Walk the configuration and find all the variabless.
+        for (ExternalVariableConf.Variable var : _extVarConf.getVariables()) {
+            EVar evar = new EVar(var.extVariableId, _engines.get(var.engineQName), var.configuration);
+            if (evar._engine == null) {
+                __log.error("External variable engine \"" + var.engineQName 
+                        + "\" referenced by external variable \"" + var.extVariableId
+                        + "\" not registered.");
+                fatal = true;
+                continue;
+            }
+            
+            try {
+                evar._engine.configure(_pid, evar._extVarId, evar._config);
+            } catch (ExternalVariableModuleException eve) {
+                __log.error("External variable subsystem configuration error.", eve);
+                throw new BpelEngineException("External variable subsystem configuration error.",eve);
+            }
+            if (_externalVariables.containsKey(var.extVariableId)) {
+                __log.warn("Duplicate external variable configuration for \"" + var.extVariableId + "\" will be ignored!");
+            }
+            _externalVariables.put(var.extVariableId, evar);
+        }
+
+        // Walk down the process definition looking for any external variables.
+        for (OBase child : oprocess.getChildren()) {
+            if (!(child instanceof OScope))
+                continue;
+            OScope oscope = (OScope) child;
+            for (OScope.Variable var : oscope.variables.values()) {
+                if (var.extVar == null)
+                    continue;
+
+                EVar evar = _externalVariables.get(var.extVar.externalVariableId);
+                if (evar == null) {
+                    __log.error("The \"" + oscope.name + "\" scope declared an unknown external variable \""
+                            + var.extVar.externalVariableId + "\"; check the deployment descriptor.");
+                    fatal = true;
+                    continue;
+                }
+
+            }
+        }
+
+        if (fatal) {
+            String errmsg = "Error initializing external variables. See log for details.";
+            __log.error(errmsg);
+            throw new BpelEngineException(errmsg);
+        }
+
+    }
+
+
+    /**
+     * Read an external variable.
+     * @param externalVariableId
+     * @param keys
+     * 
+     * @return
+     * @throws BpelEngineException
+     */
+    public Node read(String externalVariableId, Map<String, String> keys, Long iid) throws ExternalVariableModuleException{
+        EVar evar = _externalVariables.get(externalVariableId);
+        if (evar == null) {
+            // Should not happen if constructor is working.
+            throw new BpelEngineException("InternalError: reference to unknown external variable " + externalVariableId);
+        }
+        
+        Locator locator = new Locator(externalVariableId, _pid,iid, keys);
+        Value newval;
+        newval = evar._engine.readValue(locator );
+        if (newval == null)
+            return null;
+        keys.clear();
+        keys.putAll(newval.locator);
+        return newval.value;
+    }
+
+    
+    public Node write(String externalVariableId, Map<String,String> keys, Node val, Long iid) throws ExternalVariableModuleException  {
+        EVar evar = _externalVariables.get(externalVariableId);
+        if (evar == null) {
+            // Should not happen if constructor is working.
+            throw new BpelEngineException("InternalError: reference to unknown external variable " + externalVariableId);
+        }
+        
+        Locator locator = new Locator(externalVariableId,_pid,iid,new HashMap<String,String>(keys));
+        Value newval = new Value(locator,val,null);
+        newval = evar._engine.writeValue(newval );
+        
+        keys.clear();
+        keys.putAll(newval.locator);
+        return newval.value;
+    }
+
+   
+    static final class EVar {
+        final ExternalVariableModule _engine;
+
+        final Element _config;
+
+        final String _extVarId;
+
+        EVar(String id, ExternalVariableModule engine, Element config) {
+            _extVarId = id;
+            _engine = engine;
+            _config = config;
+        }
+    }
+
+
+}

Propchange: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/extvar/ExternalVariableManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java (original)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelRuntimeContext.java Thu Nov  8 11:02:38 2007
@@ -37,6 +37,7 @@
 import javax.wsdl.Operation;
 import java.util.Collection;
 import java.util.Date;
+import java.util.HashMap;
 
 import javax.xml.namespace.QName;
 
@@ -140,7 +141,7 @@
     String readProperty(VariableInstance var, OProcess.OProperty property)
             throws FaultException;
 
-    Node initializeVariable(VariableInstance var, Node initData);
+    Node initializeVariable(VariableInstance var, Node initData) ;
 
     /**
      * Writes a partner EPR.
@@ -256,4 +257,6 @@
     String getSourceSessionId(String mexId);
 
     void releasePartnerMex(String mexId);
+
+    void initializeExternalVariable(VariableInstance instance, HashMap<String, String> keymap);
 }

Modified: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/FOREACH.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/FOREACH.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/FOREACH.java (original)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/FOREACH.java Thu Nov  8 11:02:38 2007
@@ -32,6 +32,7 @@
 import org.apache.ode.bpel.runtime.channels.TerminationChannelListener;
 import org.apache.ode.bpel.evt.ScopeEvent;
 import org.apache.ode.bpel.evt.VariableModificationEvent;
+import org.apache.ode.bpel.iapi.BpelEngineException;
 import org.apache.ode.jacob.ChannelListener;
 import org.apache.ode.jacob.SynchChannel;
 import org.apache.ode.utils.DOMUtils;
@@ -210,6 +211,7 @@
                 _oforEach.innerScope), _scopeFrame, null);
         VariableInstance vinst = newFrame.resolve(_oforEach.counterVariable);
         getBpelRuntimeContext().initializeVariable(vinst, counterNode);
+
         // Generating event
         ScopeEvent se = new VariableModificationEvent(vinst.declaration.name);
         if (_oforEach.debugInfo != null)

Modified: ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/SCOPE.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/SCOPE.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/SCOPE.java (original)
+++ ode/branches/extvar/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/SCOPE.java Thu Nov  8 11:02:38 2007
@@ -20,10 +20,12 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.evt.ScopeFaultEvent;
 import org.apache.ode.bpel.evt.ScopeStartEvent;
 import org.apache.ode.bpel.evt.ScopeEvent;
 import org.apache.ode.bpel.evt.VariableModificationEvent;
+import org.apache.ode.bpel.explang.EvaluationContext;
 import org.apache.ode.bpel.o.*;
 import org.apache.ode.bpel.runtime.channels.*;
 import org.apache.ode.jacob.ChannelListener;
@@ -54,6 +56,30 @@
     }
 
     public void run() {
+
+
+        for (OScope.Variable var : _oscope.variables.values()) {
+            if (var.extVar == null)
+                continue;
+            
+            HashMap<String,String> keymap = new HashMap<String,String>();
+            for (Map.Entry<String, OExpression> mapping : var.extVar.keyDeclaration.entrySet()) {
+                String val;
+                try {
+                    val = getBpelRuntimeContext().getExpLangRuntime().evaluateAsString(mapping.getValue(), getEvaluationContext());
+                } catch (FaultException e) {
+                    __log.error("Unable to initialize external variable key.", e);
+                    FaultData fd = createFault(e.getQName(), var.extVar, "Unable to initialize external variable key: " + e.getMessage());
+                    _self.parent.completed(fd,null);
+                    return;
+                }
+                keymap.put(mapping.getKey(),val);
+            }
+                            
+            getBpelRuntimeContext().initializeExternalVariable(_scopeFrame.resolve(var), keymap);
+        }
+        
+        
         // Start the child activity.
         _child = new ActivityInfo(genMonotonic(),
             _oscope.activity,

Modified: ode/branches/extvar/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java (original)
+++ ode/branches/extvar/bpel-runtime/src/test/java/org/apache/ode/bpel/runtime/CoreBpelTest.java Thu Nov  8 11:02:38 2007
@@ -49,6 +49,7 @@
 import java.io.ByteArrayOutputStream;
 import java.util.Collection;
 import java.util.Date;
+import java.util.HashMap;
 
 /**
  * Test core BPEL processing capabilities.
@@ -410,6 +411,11 @@
     }
 
     public void forceFlush() {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void initializeExternalVariable(VariableInstance instance, HashMap<String, String> keymap) {
         // TODO Auto-generated method stub
         
     }

Modified: ode/branches/extvar/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java (original)
+++ ode/branches/extvar/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java Thu Nov  8 11:02:38 2007
@@ -18,6 +18,24 @@
  */
 package org.apache.ode.store;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.wsdl.Definition;
+import javax.xml.namespace.QName;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ode.bpel.dd.TDeployment;
@@ -33,25 +51,11 @@
 import org.apache.ode.bpel.iapi.ProcessConf;
 import org.apache.ode.bpel.iapi.ProcessState;
 import org.apache.ode.store.DeploymentUnitDir.CBPInfo;
+import org.apache.ode.utils.DOMUtils;
 import org.apache.ode.utils.msg.MessageBundle;
+import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-
-import javax.wsdl.Definition;
-import javax.xml.namespace.QName;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.xml.sax.SAXException;
 
 /**
  * Implementation of the {@link org.apache.ode.bpel.iapi.ProcessConf} interface.
@@ -341,6 +345,14 @@
         String relative = cbpPath.substring(basePath.length());
         if (relative.startsWith(File.separator)) relative = relative.substring(1);
         return relative;
+    }
+
+    public List<Element> getExtensionElement(QName qname) {
+        try {
+            return DOMUtils.findChildrenByName(DOMUtils.stringToDOM(_pinfo.toString()), qname);
+        } catch (Exception e) {
+            return Collections.emptyList();
+        }
     }
 
 }

Modified: ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java (original)
+++ ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java Thu Nov  8 11:02:38 2007
@@ -38,13 +38,12 @@
 
 import org.apache.ode.bpel.dao.BpelDAOConnectionFactory;
 import org.apache.ode.bpel.engine.BpelServerImpl;
+import org.apache.ode.bpel.extvar.jdbc.JdbcExternalVariableModule;
 import org.apache.ode.bpel.iapi.InvocationStyle;
 import org.apache.ode.bpel.iapi.Message;
 import org.apache.ode.bpel.iapi.MessageExchange;
 import org.apache.ode.bpel.iapi.MyRoleMessageExchange;
 import org.apache.ode.bpel.iapi.ProcessStore;
-import org.apache.ode.bpel.iapi.ProcessStoreEvent;
-import org.apache.ode.bpel.iapi.ProcessStoreListener;
 import org.apache.ode.bpel.iapi.MessageExchange.AckType;
 import org.apache.ode.bpel.iapi.MessageExchange.Status;
 import org.apache.ode.bpel.iapi.MyRoleMessageExchange.CorrelationStatus;
@@ -55,6 +54,7 @@
 import org.apache.ode.store.ProcessStoreImpl;
 import org.apache.ode.utils.DOMUtils;
 import org.apache.ode.utils.GUID;
+import org.hsqldb.jdbc.jdbcDataSource;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;

Modified: ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BindingContextImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BindingContextImpl.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BindingContextImpl.java (original)
+++ ode/branches/extvar/bpel-test/src/main/java/org/apache/ode/test/BindingContextImpl.java Thu Nov  8 11:02:38 2007
@@ -18,6 +18,9 @@
  */
 package org.apache.ode.test;
 
+import javax.wsdl.PortType;
+import javax.xml.namespace.QName;
+
 import org.apache.ode.bpel.iapi.BindingContext;
 import org.apache.ode.bpel.iapi.Endpoint;
 import org.apache.ode.bpel.iapi.EndpointReference;
@@ -25,9 +28,6 @@
 import org.apache.ode.utils.DOMUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-
-import javax.wsdl.PortType;
-import javax.xml.namespace.QName;
 
 public class BindingContextImpl implements BindingContext {
 	

Added: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/ExtVar.xsd
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/ExtVar.xsd?rev=593256&view=auto
==============================================================================
--- ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/ExtVar.xsd (added)
+++ ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/ExtVar.xsd Thu Nov  8 11:02:38 2007
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<schema 
+	xmlns="http://www.w3.org/2001/XMLSchema" 
+	targetNamespace="http://foo/extvar" 
+	xmlns:tns="http://foo/extvar" elementFormDefault="qualified">
+
+    <complexType name="tRow">
+    	<sequence>
+    		<element name="pid" type="string"></element>
+    		<element name="foo" type="string"></element>
+    	</sequence>
+    </complexType>
+    
+    <element name="row" type="tns:tRow" />
+</schema>
\ No newline at end of file

Propchange: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/ExtVar.xsd
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.bpel
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.bpel?rev=593256&view=auto
==============================================================================
--- ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.bpel (added)
+++ ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.bpel Thu Nov  8 11:02:38 2007
@@ -0,0 +1,80 @@
+<!--
+  ~ 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.
+  -->
+<process name="HelloWorld2"
+    targetNamespace="http://ode/bpel/unit-test" 
+    xmlns:bpws="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
+    xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
+    xmlns:tns="http://ode/bpel/unit-test"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:test="http://ode/bpel/unit-test.wsdl"
+    xmlns:foo="http://foo/extvar"
+    xmlns:evar="http://www.apache.org/ode/extensions/externalVariables"
+    queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0"
+    expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0">
+
+  <import 
+  	namespace="http://foo/extvar" 
+  	location="ExtVar.xsd" 
+  	importType="http://www.w3.org/2001/XMLSchema"/>
+
+  <import location="HelloWorld2.wsdl"
+     namespace="http://ode/bpel/unit-test.wsdl"
+     importType="http://schemas.xmlsoap.org/wsdl/" />
+
+
+   <partnerLinks>
+      <partnerLink name="helloPartnerLink" 
+         partnerLinkType="test:HelloPartnerLinkType" 
+         myRole="me" />
+   </partnerLinks>
+    
+   <variables>
+     <variable name="myVar" messageType="test:HelloMessage"/>
+     <variable name="tmpVar" type="xsd:string"/>
+     <variable name="tmpDate" type="xsd:dateTime"/>     
+     <variable name="external" element="foo:row" evar:ext-var-id="evar1" />
+
+   </variables>
+        
+   <sequence>   
+       <receive 
+          name="start"
+          partnerLink="helloPartnerLink"
+          portType="test:HelloPortType"
+          operation="hello"
+          variable="myVar"
+          createInstance="yes"/>
+
+      <assign name="assign1">
+         <copy>
+            <from variable="myVar" part="TestPart"/>
+            <to variable="tmpVar"/>
+         </copy>
+         <copy>
+             <bpws:from xmlns="">concat($tmpVar, $external/row/pid)</bpws:from>
+             <to variable="myVar" part="TestPart"/>
+         </copy>
+      </assign>
+       <reply name="end"  
+              partnerLink="helloPartnerLink"
+              portType="test:HelloPortType" 
+              operation="hello"
+              variable="myVar"/>
+   </sequence>
+</process>

Added: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.wsdl
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.wsdl?rev=593256&view=auto
==============================================================================
--- ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.wsdl (added)
+++ ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.wsdl Thu Nov  8 11:02:38 2007
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+  ~ 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.
+  -->
+
+<wsdl:definitions 
+    targetNamespace="http://ode/bpel/unit-test.wsdl"
+    xmlns="http://schemas.xmlsoap.org/wsdl/"
+    xmlns:tns="http://ode/bpel/unit-test.wsdl"
+    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:bpws="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
+    xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype">
+
+    
+    <wsdl:message name="HelloMessage">
+        <wsdl:part name="TestPart" type="xsd:string"/>
+    </wsdl:message>
+    
+    <wsdl:portType name="HelloPortType">
+        <wsdl:operation name="hello">
+            <wsdl:input message="tns:HelloMessage" name="TestIn"/>
+            <wsdl:output message="tns:HelloMessage" name="TestOut"/>
+        </wsdl:operation>    
+    </wsdl:portType>
+    
+     <wsdl:binding name="HelloSoapBinding" type="tns:HelloPortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <wsdl:operation name="hello">
+            <soap:operation soapAction="" style="rpc"/>
+            <wsdl:input>
+                <soap:body
+                    namespace="http://ode/bpel/unit-test.wsdl"
+                    use="literal"/>
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body
+                    namespace="http://ode/bpel/unit-test.wsdl" 
+                    use="literal"/>
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="HelloService">
+		<wsdl:port name="HelloPort" binding="tns:HelloSoapBinding">
+     		<soap:address location="http://localhost:8080/ode/processes/helloWorld"/>
+		</wsdl:port>
+    </wsdl:service>
+    
+   <plnk:partnerLinkType name="HelloPartnerLinkType">
+       <plnk:role name="me" portType="tns:HelloPortType"/>
+       <plnk:role name="you" portType="tns:HelloPortType"/>
+   </plnk:partnerLinkType>
+</wsdl:definitions>
+

Propchange: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/HelloWorld2.wsdl
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/deploy.xml
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/deploy.xml?rev=593256&view=auto
==============================================================================
--- ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/deploy.xml (added)
+++ ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/deploy.xml Thu Nov  8 11:02:38 2007
@@ -0,0 +1,46 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<deploy xmlns="http://www.apache.org/ode/schemas/dd/2007/03"
+	xmlns:pns="http://ode/bpel/unit-test" 
+	xmlns:wns="http://ode/bpel/unit-test.wsdl"
+	xmlns:evar="http://www.apache.org/ode/extensions/externalVariables">
+
+
+	<process name="pns:HelloWorld2">
+		<active>true</active>
+		<provide partnerLink="helloPartnerLink">
+			<service name="wns:HelloService" port="HelloPort"/>
+		</provide>
+		
+		<evar:externalVariable id="evar1" >
+			<evar:jdbc xmlns="">				       
+				<datasource-ref>testds</datasource-ref>
+				<table>extvartable1</table>
+				<column name="pid" 
+				    key="yes"
+					generator="pid" />      
+				<column name="cts" 
+					generator="ctimestamp" />   
+				<column name="uts" 
+					generator="utimestamp" />   
+			</evar:jdbc>			
+		</evar:externalVariable>
+		
+	</process>
+</deploy>

Propchange: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/deploy.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/test.properties
URL: http://svn.apache.org/viewvc/ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/test.properties?rev=593256&view=auto
==============================================================================
--- ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/test.properties (added)
+++ ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/test.properties Thu Nov  8 11:02:38 2007
@@ -0,0 +1,23 @@
+#
+#    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.
+#
+
+namespace=http://ode/bpel/unit-test.wsdl
+service=HelloService
+operation=hello
+request1=<message><TestPart>Hello</TestPart></message>
+response1=.*Hello World.*
+

Propchange: ode/branches/extvar/bpel-test/src/test/resources/bpel/2.0/ExtVar/test.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: ode/branches/extvar/utils/src/main/java/org/apache/ode/utils/DOMUtils.java
URL: http://svn.apache.org/viewvc/ode/branches/extvar/utils/src/main/java/org/apache/ode/utils/DOMUtils.java?rev=593256&r1=593255&r2=593256&view=diff
==============================================================================
--- ode/branches/extvar/utils/src/main/java/org/apache/ode/utils/DOMUtils.java (original)
+++ ode/branches/extvar/utils/src/main/java/org/apache/ode/utils/DOMUtils.java Thu Nov  8 11:02:38 2007
@@ -26,6 +26,8 @@
 import java.io.StringWriter;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 
 import javax.xml.namespace.QName;
@@ -335,7 +337,7 @@
         HashMap<String,String> pref = new HashMap<String,String>();
         Map mine = getMyNamespaces(el);
         Node n = el.getParentNode();
-        do {
+        while (n != null && n.getNodeType() != Node.DOCUMENT_NODE) {
             if (n instanceof Element) {
                 Element l = (Element) n;
                 NamedNodeMap nnm = l.getAttributes();
@@ -352,7 +354,7 @@
                 }
             }
             n = n.getParentNode();
-        } while (n != null && n.getNodeType() != Node.DOCUMENT_NODE);
+        } 
         return pref;
     }
 
@@ -994,6 +996,29 @@
             __builders.set(builder);
         }
         return builder;
+    }
+
+    public static List<Element> findChildrenByName(Element parent, QName name) {
+        if (parent == null)
+            throw new IllegalArgumentException("null parent");
+        if (name == null)
+            throw new IllegalArgumentException("null name");
+
+        LinkedList<Element> ret = new LinkedList<Element>();
+        NodeList nl = parent.getChildNodes();
+        for (int i = 0; i < nl.getLength(); ++i) {
+            Node c = nl.item(i);
+            if(c.getNodeType() != Node.ELEMENT_NODE)
+                continue;
+            // For a reason that I can't fathom, when using in-mem DAO we actually get elements with
+            // no localname.
+            String nodeName = c.getLocalName() != null ? c.getLocalName() : c.getNodeName();
+            if (new QName(c.getNamespaceURI(),nodeName).equals(name))
+                ret.add((Element)c);
+        }
+
+        
+        return ret;
     }
 
 }