You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mr...@apache.org on 2008/09/10 21:07:05 UTC

svn commit: r693931 [5/12] - in /ode/trunk: bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/ bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/xpath10/ bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/xpath20/ runtimes/...

Added: ode/trunk/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/xpath20/XPath20ExpressionCompilerImpl.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/xpath20/XPath20ExpressionCompilerImpl.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/xpath20/XPath20ExpressionCompilerImpl.java (added)
+++ ode/trunk/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/xpath20/XPath20ExpressionCompilerImpl.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,165 @@
+/*
+ * 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.v1.xpath20;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.xpath.XPathExpressionException;
+
+import net.sf.saxon.xpath.XPathEvaluator;
+import net.sf.saxon.xpath.XPathFactoryImpl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.compiler.v1.ExpressionCompiler;
+import org.apache.ode.bpel.compiler.v1.CompilerContext;
+import org.apache.ode.bpel.compiler.v1.xpath10.XslCompilationErrorListener;
+import org.apache.ode.bpel.compiler.bom.Expression;
+import org.apache.ode.bpel.compiler.api.CompilationException;
+import org.apache.ode.bpel.compiler.XPathMessages;
+import org.apache.ode.bpel.compiler.WrappedResolverException;
+import org.apache.ode.bpel.rtrep.v1.OExpression;
+import org.apache.ode.bpel.rtrep.v1.OLValueExpression;
+import org.apache.ode.bpel.rtrep.v1.xpath20.OXPath20ExpressionBPEL20;
+import org.apache.ode.bpel.rtrep.common.Constants;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.msg.MessageBundle;
+import org.apache.ode.utils.xsl.XslTransformHandler;
+import org.w3c.dom.Node;
+
+/**
+ * XPath compiler based on the SAXON implementation.
+ * @author Matthieu Riou <mriou at apache dot org>
+ */
+public class XPath20ExpressionCompilerImpl implements ExpressionCompiler {
+
+    protected static final Log __log = LogFactory.getLog(XPath20ExpressionCompilerBPEL20.class);
+
+    protected String _bpelNS;
+    protected QName _qnLinkStatus;
+    protected QName _qnVarProp;
+    protected QName _qnVarData;
+    protected QName _qnXslTransform;
+
+    protected final XPathMessages __msgs = MessageBundle.getMessages(XPathMessages.class);
+    protected Map<String, String> _properties = new HashMap<String, String>();
+    protected CompilerContext _compilerContext;
+
+    public XPath20ExpressionCompilerImpl(String bpelNS) {
+        _bpelNS = bpelNS;
+        _qnLinkStatus = new QName(_bpelNS, Constants.EXT_FUNCTION_GETLINKSTATUS);
+        _qnVarProp = new QName(_bpelNS, Constants.EXT_FUNCTION_GETVARIABLEPROPRTY);
+        _qnVarData = new QName(_bpelNS, Constants.EXT_FUNCTION_GETVARIABLEDATA);
+        _qnXslTransform = new QName(_bpelNS, Constants.EXT_FUNCTION_DOXSLTRANSFORM);
+
+        _properties.put("runtime-class", "org.apache.ode.bpel.elang.xpath20.runtime.XPath20ExpressionRuntime");
+        TransformerFactory trsf = new net.sf.saxon.TransformerFactoryImpl();
+        XslTransformHandler.getInstance().setTransformerFactory(trsf);
+    }
+
+    public void setCompilerContext(CompilerContext compilerContext) {
+        _compilerContext = compilerContext;
+        XslCompilationErrorListener xe = new XslCompilationErrorListener(compilerContext);
+        XslTransformHandler.getInstance().setErrorListener(xe);
+    }
+
+    /**
+     * @see org.apache.ode.bpel.compiler.v1.api.ExpressionCompiler#compileJoinCondition(java.lang.Object)
+     */
+    public OExpression compileJoinCondition(Object source) throws CompilationException {
+        return _compile((Expression) source, true);
+    }
+
+    /**
+     * @see org.apache.ode.bpel.compiler.v1.api.ExpressionCompiler#compile(java.lang.Object)
+     */
+    public OExpression compile(Object source) throws CompilationException {
+        return _compile((Expression) source, false);
+    }
+
+    /**
+     * @see org.apache.ode.bpel.compiler.v1.api.ExpressionCompiler#compileLValue(java.lang.Object)
+     */
+    public OLValueExpression compileLValue(Object source) throws CompilationException {
+        return (OLValueExpression) _compile((Expression) source, false);
+    }
+
+    /**
+     * @see org.apache.ode.bpel.compiler.v1.api.ExpressionCompiler#compile(java.lang.Object)
+     */
+    private OExpression _compile(Expression xpath, boolean isJoinCondition)
+            throws CompilationException {
+        OXPath20ExpressionBPEL20 oexp = new OXPath20ExpressionBPEL20(_compilerContext.getOProcess(), _qnVarData,
+                _qnVarProp, _qnLinkStatus, _qnXslTransform, isJoinCondition);
+        oexp.namespaceCtx = xpath.getNamespaceContext();
+        doJaxpCompile(oexp, xpath);
+        return oexp;
+    }
+
+    private void doJaxpCompile(OXPath20ExpressionBPEL20 out, Expression source) throws CompilationException {
+        String xpathStr;
+        Node node = source.getExpression();
+        if (node == null) {
+            throw new IllegalStateException("XPath string and xpath node are both null");
+        }
+        if (node.getNodeType() != Node.TEXT_NODE) {
+            throw new CompilationException(__msgs.errUnexpectedNodeTypeForXPath(DOMUtils.domToString(node)));
+        }
+        xpathStr = node.getNodeValue();
+        xpathStr = xpathStr.trim();
+        if (xpathStr.length() == 0) {
+            throw new CompilationException(__msgs.warnXPath20Syntax(DOMUtils.domToString(node), "empty string"));
+        }
+
+        out.xpath = xpathStr;
+        try {
+            __log.debug("Compiling expression " + xpathStr);
+            XPathFactoryImpl xpf = new net.sf.saxon.xpath.XPathFactoryImpl();
+            JaxpFunctionResolver funcResolver = new JaxpFunctionResolver(
+                    _compilerContext, out, source.getNamespaceContext(), _bpelNS);
+            xpf.setXPathFunctionResolver(funcResolver);
+            JaxpVariableResolver varResolver = new JaxpVariableResolver(_compilerContext, out);
+            xpf.setXPathVariableResolver(varResolver);
+
+            XPathEvaluator xpe = (XPathEvaluator) xpf.newXPath();
+            xpe.setStaticContext(new SaxonContext(xpf.getConfiguration(), varResolver, funcResolver));
+            xpe.setXPathFunctionResolver(funcResolver);
+            xpe.setNamespaceContext(source.getNamespaceContext());
+            xpe.compile(xpathStr);
+        } catch (XPathExpressionException e) {
+            __log.debug(e);
+            __log.info("Couldn't validate properly expression " + xpathStr);
+        } catch (WrappedResolverException wre) {
+            if (wre._compilationMsg != null)
+                throw new CompilationException(wre._compilationMsg, wre);
+            if (wre.getCause() instanceof CompilationException)
+                throw (CompilationException) wre.getCause();
+            throw wre;
+        }
+    }
+
+    public Map<String, String> getProperties() {
+        return _properties;
+    }
+
+}

Modified: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/Serializers.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/Serializers.java?rev=693931&r1=693930&r2=693931&view=diff
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/Serializers.java (original)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/Serializers.java Wed Sep 10 12:06:59 2008
@@ -4,6 +4,8 @@
 
 import java.io.InputStream;
 import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 
 /**
  * Factory to instantiate OModel serializers/deserializers for a specific version of the model. It's
@@ -20,12 +22,22 @@
 
 
     public static Serializer getVersion(int version) {
-        // TODO switch on the version when we'll have more than one
-        return getLatest();
+        try {
+            Class serializerClass = Class.forName("org.apache.ode.bpel.rtrep.v" + version + ".Serializer");
+            Constructor cstrct = serializerClass.getConstructor(Long.TYPE);
+            return (Serializer) cstrct.newInstance(System.currentTimeMillis());
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't build an OModel serializer for version " + version);
+        }
     }
     public static Serializer getVersion(InputStream stream, int version) throws IOException {
-        // TODO switch on the version when we'll have more than one
-        return getLatest(stream);
+        try {
+            Class serializerClass = Class.forName("org.apache.ode.bpel.rtrep.v" + version + ".Serializer");
+            Constructor cstrct = serializerClass.getConstructor(InputStream.class);
+            return (Serializer) cstrct.newInstance(stream);
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't build an OModel serializer for version " + version);
+        }
     }
 
 }

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ACTIVITY.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ACTIVITY.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ACTIVITY.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ACTIVITY.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,185 @@
+/*
+ * 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.rtrep.v1;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+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.ActivityEvent;
+import org.apache.ode.bpel.evt.EventContext;
+import org.apache.ode.bpel.evt.ScopeEvent;
+import org.apache.ode.bpel.evt.VariableReadEvent;
+import org.apache.ode.bpel.rtrep.v1.OMessageVarType.Part;
+import org.apache.ode.jacob.IndexedObject;
+import org.apache.ode.bpel.evar.ExternalVariableModuleException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Base template for activities.
+ */
+abstract class ACTIVITY extends BpelJacobRunnable implements IndexedObject {
+	private static final Log __log = LogFactory.getLog(ACTIVITY.class);
+    protected ActivityInfo _self;
+
+    /**
+     * Permeability flag, if <code>false</code> we defer outgoing links until successful completion.
+     */
+    protected boolean _permeable = true;
+
+    protected ScopeFrame _scopeFrame;
+
+    protected LinkFrame _linkFrame;
+    
+    public ACTIVITY(ActivityInfo self, ScopeFrame scopeFrame, LinkFrame linkFrame) {
+        assert self != null;
+        assert scopeFrame != null;
+        assert linkFrame != null;
+
+        _self = self;
+        _scopeFrame = scopeFrame;
+        _linkFrame = linkFrame;
+    }
+
+    public Object getKey() {
+        return new Key(_self.o,_self.aId);
+    }
+
+    
+    protected void sendVariableReadEvent(VariableInstance var) {
+    	VariableReadEvent vre = new VariableReadEvent();
+    	vre.setVarName(var.declaration.name);
+    	sendEvent(vre);
+    }
+    
+    protected void sendEvent(ActivityEvent event) {
+        event.setActivityName(_self.o.name);
+        event.setActivityType(_self.o.getType());
+        event.setActivityDeclarationId(_self.o.getId());
+        event.setActivityId(_self.aId);
+        if (event.getLineNo() == -1) {
+            event.setLineNo(getLineNo());
+        }
+        sendEvent((ScopeEvent) event);
+    }
+
+    protected void sendEvent(ScopeEvent event) {
+        if (event.getLineNo() == -1 && _self.o.debugInfo != null) {
+            event.setLineNo(_self.o.debugInfo.startLine);
+        }
+        _scopeFrame.fillEventInfo(event);
+        fillEventContext(event);
+        getBpelRuntime().sendEvent(event);
+    }
+
+    /**
+     * Populate BpelEventContext, to be used by Registered Event Listeners
+     * @param event ScopeEvent
+     */
+    protected void fillEventContext(ScopeEvent event)
+    {
+        EventContext eventContext = new EventContextImpl(_scopeFrame.oscope,
+                                                            _scopeFrame.scopeInstanceId,
+                                                            getBpelRuntime());
+        event.eventContext = eventContext;
+    }
+
+    protected void dpe(Collection<OLink> links) {
+        // Dead path all of the outgoing links (nothing has been activated yet!)
+        for (OLink link : links) {
+            if (__log.isDebugEnabled()) __log.debug("DPE on link " + link.name);
+            _linkFrame.resolve(link).pub.linkStatus(false);
+        }
+    }
+    
+    protected OConstants getConstants() {
+    	return _self.o.getOwner().constants;
+    }
+
+    /**
+     * Perform dead-path elimination on an activity that was
+     * <em>not started</em>.
+     * 
+     * @param activity
+     */
+    protected void dpe(OActivity activity) {
+        dpe(activity.sourceLinks);
+        dpe(activity.outgoingLinks);
+        // TODO: register listeners for target / incoming links
+    }
+
+    protected EvaluationContext getEvaluationContext() {
+        return new ExprEvaluationContextImpl(_scopeFrame, getBpelRuntime());
+    }
+
+    private int getLineNo() {
+        if (_self.o.debugInfo != null && _self.o.debugInfo.startLine != -1) {
+            return _self.o.debugInfo.startLine;
+        }
+        return -1;
+    }
+
+    //
+    // Syntactic sugar for methods that used to be on BpelRuntimeContext.. 
+    //
+    
+    Node fetchVariableData(VariableInstance variable, boolean forWriting) 
+        throws FaultException {
+    	return getBpelRuntime().fetchVariableData(variable, _scopeFrame, forWriting);
+	}
+
+    Node fetchVariableData(VariableInstance var, OMessageVarType.Part part, boolean forWriting)
+        throws FaultException {
+      return getBpelRuntime().fetchVariableData(var, _scopeFrame, part, forWriting);
+    }
+    
+    Node initializeVariable(VariableInstance lvar, Node val) 
+        throws ExternalVariableModuleException {
+    	return getBpelRuntime().initializeVariable(lvar, _scopeFrame, val);
+    }
+
+    void commitChanges(VariableInstance lval, Node lvalue) throws ExternalVariableModuleException {
+    	getBpelRuntime().commitChanges(lval, _scopeFrame, lvalue);
+	}
+
+    //
+    // End syntactic sugar.
+    //
+    
+    public static final class Key implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        final OActivity type;
+
+        final long aid;
+
+        public Key(OActivity type, long aid) {
+            this.type = type;
+            this.aid = aid;
+        }
+
+        @Override
+        public String toString() {
+            return type + "::" + aid;
+        }
+    }
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ACTIVITYGUARD.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ACTIVITYGUARD.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ACTIVITYGUARD.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ACTIVITYGUARD.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,327 @@
+/*
+ * 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.rtrep.v1;
+
+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.ActivityEnabledEvent;
+import org.apache.ode.bpel.evt.ActivityExecEndEvent;
+import org.apache.ode.bpel.evt.ActivityExecStartEvent;
+import org.apache.ode.bpel.evt.ActivityFailureEvent;
+import org.apache.ode.bpel.evt.ActivityRecoveryEvent;
+import org.apache.ode.bpel.rtrep.v1.channels.FaultData;
+import org.apache.ode.bpel.rtrep.v1.channels.LinkStatusChannelListener;
+import org.apache.ode.bpel.rtrep.v1.channels.ParentScopeChannel;
+import org.apache.ode.bpel.rtrep.v1.channels.ParentScopeChannelListener;
+import org.apache.ode.bpel.rtrep.v1.channels.TerminationChannelListener;
+import org.apache.ode.bpel.rtrep.v1.channels.ActivityRecoveryChannel;
+import org.apache.ode.bpel.rtrep.v1.channels.ActivityRecoveryChannelListener;
+import org.apache.ode.bpel.rtrep.v1.channels.TimerResponseChannel;
+import org.apache.ode.bpel.rtrep.v1.channels.TimerResponseChannelListener;
+import org.apache.ode.bpel.rapi.InvalidProcessException;
+import org.apache.ode.jacob.ChannelListener;
+import org.apache.ode.jacob.SynchChannel;
+
+import org.w3c.dom.Element;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+class ACTIVITYGUARD extends ACTIVITY {
+    private static final long serialVersionUID = 1L;
+
+    private static final Log __log = LogFactory.getLog(ACTIVITYGUARD.class);
+
+    private static final ActivityTemplateFactory __activityTemplateFactory = new ActivityTemplateFactory();
+    private OActivity _oactivity;
+
+    /** Link values. */
+    private Map<OLink, Boolean> _linkVals = new HashMap<OLink, Boolean>();
+
+    /** Flag to prevent duplicate ActivityEnabledEvents */
+    private boolean _firstTime = true;
+
+    private ActivityFailure _failure;
+
+    public ACTIVITYGUARD(ActivityInfo self, ScopeFrame scopeFrame, LinkFrame linkFrame) {
+        super(self, scopeFrame, linkFrame);
+        _oactivity = self.o;
+    }
+
+    public void run() {
+        // Send a notification of the activity being enabled,
+        if (_firstTime) {
+            sendEvent(new ActivityEnabledEvent());
+            _firstTime = false;
+        }
+
+        if (_linkVals.keySet().containsAll(_oactivity.targetLinks)) {
+            if (evaluateJoinCondition()) {
+                ActivityExecStartEvent aese = new ActivityExecStartEvent();
+                sendEvent(aese);
+                // intercept completion channel in order to execute transition conditions.
+                ActivityInfo activity = new ActivityInfo(genMonotonic(),_self.o,_self.self, newChannel(ParentScopeChannel.class));
+                instance(createActivity(activity));
+                instance(new TCONDINTERCEPT(activity.parent));
+            } else {
+                if (_oactivity.suppressJoinFailure) {
+                    _self.parent.completed(null, CompensationHandler.emptySet());
+                    if (__log.isDebugEnabled())
+                        __log.debug("Join condition false, suppress join failure on activity " + _self.aId);
+                } else {
+                    FaultData fault = null;
+                    fault = createFault(_oactivity.getOwner().constants.qnJoinFailure,_oactivity);
+                    _self.parent.completed(fault, CompensationHandler.emptySet());
+                }
+
+                // Dead path activity.
+                dpe(_oactivity);
+            }
+        } else /* don't know all our links statuses */ {
+            Set<ChannelListener> mlset = new HashSet<ChannelListener>();
+            mlset.add(new TerminationChannelListener(_self.self) {
+                private static final long serialVersionUID = 5094153128476008961L;
+
+                public void terminate() {
+                    // Complete immediately, without faulting or registering any comps.
+                    _self.parent.completed(null, CompensationHandler.emptySet());
+                    // Dead-path activity
+                    dpe(_oactivity);
+                }
+            });
+            for (final OLink link : _oactivity.targetLinks) {
+                mlset.add(new LinkStatusChannelListener(_linkFrame.resolve(link).sub) {
+                    private static final long serialVersionUID = 1024137371118887935L;
+
+                    public void linkStatus(boolean value) {
+                        _linkVals.put(link, Boolean.valueOf(value));
+                        instance(ACTIVITYGUARD.this);
+                    }
+                });
+            }
+
+            object(false, mlset);
+        }
+    }
+
+
+    private boolean evaluateTransitionCondition(OExpression transitionCondition)
+            throws FaultException {
+        if (transitionCondition == null) return true;
+
+            return getBpelRuntime().getExpLangRuntime().evaluateAsBoolean(transitionCondition,
+                    new ExprEvaluationContextImpl(_scopeFrame, getBpelRuntime()));
+    }
+
+    /**
+     * Evaluate an activity's join condition.
+     * @return <code>true</code> if join condition evaluates to true.
+     */
+    private boolean evaluateJoinCondition() {
+        // For activities with no link targets, the join condition is always satisfied.
+        if (_oactivity.targetLinks.size() == 0)
+            return true;
+
+        // For activities with no join condition, an OR condition is assumed.
+        if (_oactivity.joinCondition == null)
+            return _linkVals.values().contains(Boolean.TRUE);
+
+        try {
+            return getBpelRuntime().getExpLangRuntime().evaluateAsBoolean(_oactivity.joinCondition,
+                    new ExprEvaluationContextImpl(null, null,_linkVals));
+        } catch (Exception e) {
+            String msg = "Unexpected error evaluating a join condition: " + _oactivity.joinCondition;
+            __log.error(msg,e);
+            throw new InvalidProcessException(msg,e);
+        }
+    }
+
+    private static ACTIVITY createActivity(ActivityInfo activity, ScopeFrame scopeFrame, LinkFrame linkFrame) {
+        return __activityTemplateFactory.createInstance(activity.o,activity, scopeFrame, linkFrame);
+    }
+
+    private ACTIVITY createActivity(ActivityInfo activity) {
+        return createActivity(activity,_scopeFrame, _linkFrame);
+    }
+
+    private void startGuardedActivity() {
+        ActivityInfo activity = new ActivityInfo(genMonotonic(),_self.o,_self.self, newChannel(ParentScopeChannel.class));
+        instance(createActivity(activity));
+        instance(new TCONDINTERCEPT(activity.parent));
+    }
+
+
+    /**
+     * Intercepts the
+     * {@link ParentScopeChannel#completed(org.apache.ode.bpel.rtrep.v1.channels.FaultData, java.util.Set<org.apache.ode.bpel.rtrep.v1.CompensationHandler>)}
+     * call, to evaluate transition conditions before returning to the parent.
+     */
+    private class TCONDINTERCEPT extends BpelJacobRunnable {
+        private static final long serialVersionUID = 4014873396828400441L;
+        ParentScopeChannel _in;
+
+        public TCONDINTERCEPT(ParentScopeChannel in) {
+            _in = in;
+        }
+
+        public void run() {
+            object(new ParentScopeChannelListener(_in) {
+                private static final long serialVersionUID = 2667359535900385952L;
+
+                public void compensate(OScope scope, SynchChannel ret) {
+                    _self.parent.compensate(scope,ret);
+                    instance(TCONDINTERCEPT.this);
+                }
+
+                public void completed(FaultData faultData, Set<CompensationHandler> compensations) {
+                    sendEvent(new ActivityExecEndEvent());
+                    if (faultData != null) {
+                        dpe(_oactivity.sourceLinks);
+                        _self.parent.completed(faultData, compensations);
+                    } else {
+                        FaultData fault = null;
+                        for (Iterator<OLink> i = _oactivity.sourceLinks.iterator();i.hasNext();) {
+                            OLink olink = i.next();
+                            LinkInfo linfo = _linkFrame.resolve(olink);
+                            try {
+                                boolean val = evaluateTransitionCondition(olink.transitionCondition);
+                                linfo.pub.linkStatus(val);
+                            } catch (FaultException e) {
+                                linfo.pub.linkStatus(false);
+                                __log.error(e);
+                                if (fault == null)
+                                    fault = createFault(e.getQName(),olink.transitionCondition);
+                            }
+                        }
+                        _self.parent.completed(fault, compensations);
+                    }
+                }
+
+                public void cancelled() {
+                    sendEvent(new ActivityExecEndEvent());
+                    dpe(_oactivity.outgoingLinks);
+                    dpe(_oactivity.sourceLinks);
+                    // Implicit scope can tell the difference between cancelled and completed.
+                    _self.parent.cancelled();
+                }
+
+                public void failure(String reason, Element data) {
+                    if (_failure == null)
+                        _failure = new ActivityFailure();
+                    _failure.dateTime = new Date();
+                    _failure.reason = reason;
+                    _failure.data = data;
+
+                    OFailureHandling failureHandling = _oactivity.getFailureHandling();
+                    if (failureHandling != null && failureHandling.faultOnFailure) {
+                      // No attempt to retry or enter activity recovery state, simply fault.
+                        if (__log.isDebugEnabled())
+                            __log.debug("ActivityRecovery: Activity " + _self.aId + " faulting on failure");
+                        FaultData faultData = createFault(OFailureHandling.FAILURE_FAULT_NAME, _oactivity, reason);
+                        completed(faultData, CompensationHandler.emptySet());
+                        return;
+                    }
+                    if (failureHandling == null || _failure.retryCount >= failureHandling.retryFor) {
+                        requireRecovery();
+                        return;
+                    }
+        
+                    if (__log.isDebugEnabled())
+                        __log.debug("ActivityRecovery: Retrying activity " + _self.aId);
+                    Date future = new Date(new Date().getTime() + 
+                        (failureHandling == null ? 0L : failureHandling.retryDelay * 1000));
+                    final TimerResponseChannel timerChannel = newChannel(TimerResponseChannel.class);
+                    getBpelRuntime().registerTimer(timerChannel, future);
+                    object(false, new TimerResponseChannelListener(timerChannel) {
+                        private static final long serialVersionUID = -261911108068231376L;
+                            public void onTimeout() {
+                                ++_failure.retryCount;
+                                startGuardedActivity();
+                            }
+                            public void onCancel() {
+                                requireRecovery();
+                            }
+                    });
+                }
+
+                private void requireRecovery() {
+                    if (__log.isDebugEnabled())
+                        __log.debug("ActivityRecovery: Activity " + _self.aId + " requires recovery");
+                    sendEvent(new ActivityFailureEvent(_failure.reason));
+                    final ActivityRecoveryChannel recoveryChannel = newChannel(ActivityRecoveryChannel.class);
+                    getBpelRuntime().registerActivityForRecovery(
+                        recoveryChannel, _self.aId, _failure.reason, _failure.dateTime, _failure.data,
+                        new String[] { "retry", "cancel", "fault" }, _failure.retryCount);
+                    object(false, new ActivityRecoveryChannelListener(recoveryChannel) {
+                        private static final long serialVersionUID = 8397883882810521685L;
+                        public void retry() {
+                            if (__log.isDebugEnabled())
+                                __log.debug("ActivityRecovery: Retrying activity " + _self.aId + " (user initiated)");
+                            sendEvent(new ActivityRecoveryEvent("retry"));
+                            getBpelRuntime().unregisterActivityForRecovery(recoveryChannel);
+                            ++_failure.retryCount;
+                            startGuardedActivity();
+                        }
+                        public void cancel() {
+                            if (__log.isDebugEnabled())
+                                __log.debug("ActivityRecovery: Cancelling activity " + _self.aId + " (user initiated)");
+                            sendEvent(new ActivityRecoveryEvent("cancel"));
+                            getBpelRuntime().unregisterActivityForRecovery(recoveryChannel);
+                            cancelled();
+                        }
+                        public void fault(FaultData faultData) {
+                            if (__log.isDebugEnabled())
+                                __log.debug("ActivityRecovery: Faulting activity " + _self.aId + " (user initiated)");
+                            sendEvent(new ActivityRecoveryEvent("fault"));
+                            getBpelRuntime().unregisterActivityForRecovery(recoveryChannel);
+                            if (faultData == null)
+                                faultData = createFault(OFailureHandling.FAILURE_FAULT_NAME, _self.o, _failure.reason);
+                            completed(faultData, CompensationHandler.emptySet());
+                        }
+                    }.or(new TerminationChannelListener(_self.self) {
+                        private static final long serialVersionUID = 2148587381204858397L;
+
+                        public void terminate() {
+                            if (__log.isDebugEnabled())
+                                __log.debug("ActivityRecovery: Cancelling activity " + _self.aId + " (terminated by scope)");
+                            getBpelRuntime().unregisterActivityForRecovery(recoveryChannel);
+                            cancelled();
+                        }
+                    }));
+                }
+            });
+
+        }
+    }
+
+    static class ActivityFailure implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        Date    dateTime;
+        String  reason;
+        Element data;
+        int     retryCount;
+    }
+    
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ASSIGN.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ASSIGN.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ASSIGN.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ASSIGN.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,680 @@
+/*
+ * 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.rtrep.v1;
+
+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.PartnerLinkModificationEvent;
+import org.apache.ode.bpel.evt.ScopeEvent;
+import org.apache.ode.bpel.evt.VariableModificationEvent;
+import org.apache.ode.bpel.rtrep.v1.OAssign.DirectRef;
+import org.apache.ode.bpel.rtrep.v1.OAssign.LValueExpression;
+import org.apache.ode.bpel.rtrep.v1.OAssign.PropertyRef;
+import org.apache.ode.bpel.rtrep.v1.OAssign.VariableRef;
+import org.apache.ode.bpel.rtrep.v1.OMessageVarType.Part;
+import org.apache.ode.bpel.rtrep.v1.OProcess.OProperty;
+import org.apache.ode.bpel.rtrep.v1.OScope.Variable;
+import org.apache.ode.bpel.rtrep.v1.channels.FaultData;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.Namespaces;
+import org.apache.ode.utils.msg.MessageBundle;
+import org.apache.ode.bpel.evar.ExternalVariableModuleException;
+import org.apache.ode.bpel.rapi.InvalidProcessException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import javax.xml.namespace.QName;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * Assign activity run-time template.
+ */
+class ASSIGN extends ACTIVITY {
+    private static final long serialVersionUID = 1L;
+
+    private static final Log __log = LogFactory.getLog(ASSIGN.class);
+
+    private static final ASSIGNMessages __msgs = MessageBundle
+            .getMessages(ASSIGNMessages.class);
+
+    public ASSIGN(ActivityInfo self, ScopeFrame scopeFrame, LinkFrame linkFrame) {
+        super(self, scopeFrame, linkFrame);
+    }
+
+    public void run() {
+        OAssign oassign = getOAsssign();
+
+        FaultData faultData = null;
+
+        for (OAssign.Copy aCopy : oassign.copy) {
+            try {
+                copy(aCopy);
+            } catch (FaultException fault) {
+            	if (aCopy.ignoreMissingFromData) {
+	            	if (fault.getQName().equals(getOAsssign().getOwner().constants.qnSelectionFailure) &&
+	            			(fault.getCause() != null && "ignoreMissingFromData".equals(fault.getCause().getMessage()))) {
+	            	continue;
+	            	}
+            	}
+            	if (aCopy.ignoreUninitializedFromVariable) {
+	            	if (fault.getQName().equals(getOAsssign().getOwner().constants.qnUninitializedVariable) &&
+	            			(fault.getCause() == null || !"throwUninitializedToVariable".equals(fault.getCause().getMessage()))) {
+	            	continue;
+	            	}
+            	}
+                faultData = createFault(fault.getQName(), aCopy, fault
+                        .getMessage());
+                break;
+            } catch (ExternalVariableModuleException e) {
+            	__log.error("Exception while initializing external variable", e);
+                _self.parent.failure(e.toString(), null);
+                return;
+            }
+        }
+
+        if (faultData != null) {
+            __log.error("Assignment Fault: " + faultData.getFaultName()
+                    + ",lineNo=" + faultData.getFaultLineNo()
+                    + ",faultExplanation=" + faultData.getExplanation());
+            _self.parent.completed(faultData, CompensationHandler.emptySet());
+        } else {
+            _self.parent.completed(null, CompensationHandler.emptySet());
+        }
+    }
+
+    protected Log log() {
+        return __log;
+    }
+
+    private OAssign getOAsssign() {
+        return (OAssign) _self.o;
+    }
+
+    private Node evalLValue(OAssign.LValue to) throws FaultException, ExternalVariableModuleException {
+        final OdeInternalInstance napi = getBpelRuntime();
+        Node lval = null;
+        if (!(to instanceof OAssign.PartnerLinkRef)) {
+            VariableInstance lvar = _scopeFrame.resolve(to.getVariable());
+            if (!napi.isVariableInitialized(lvar)) {
+                Document doc = DOMUtils.newDocument();
+                Node val = to.getVariable().type.newInstance(doc);
+                if (val.getNodeType() == Node.TEXT_NODE) {
+                    Element tempwrapper = doc.createElementNS(null, "temporary-simple-type-wrapper");
+                    doc.appendChild(tempwrapper);
+                    tempwrapper.appendChild(val);
+                    val = tempwrapper;
+                } else doc.appendChild(val);
+                // Only external variables need to be initialized, others are new and going to be overwtitten
+                if (lvar.declaration.extVar != null) lval = initializeVariable(lvar, val);
+                else lval = val;
+            } else
+                lval = fetchVariableData(lvar, true);
+        }
+        return lval;
+    }
+
+	/**
+     * Get the r-value. There are several possibilities:
+     * <ul>
+     * <li>a message is selected - an element representing the whole message is
+     * returned.</li>
+     * <li>a (element) message part is selected - the element is returned.
+     * </li>
+     * <li>a (typed) message part is select - a wrapper element is returned.
+     * </li>
+     * <li>an attribute is selected - an attribute node is returned. </li>
+     * <li>a text node/string expression is selected - a text node is returned.
+     * </li>
+     * </ul>
+     *
+     * @param from
+     *
+     * @return Either {@link Element}, {@link org.w3c.dom.Text}, or
+     *         {@link org.w3c.dom.Attr} node representing the r-value.
+     *
+     * @throws FaultException
+     *             DOCUMENTME
+     * @throws UnsupportedOperationException
+     *             DOCUMENTME
+     * @throws IllegalStateException
+     *             DOCUMENTME
+     */
+    private Node evalRValue(OAssign.RValue from) throws FaultException, ExternalVariableModuleException {
+        if (__log.isDebugEnabled())
+            __log.debug("Evaluating FROM expression \"" + from + "\".");
+
+        Node retVal;
+        if (from instanceof DirectRef) {
+            OAssign.DirectRef dref = (OAssign.DirectRef) from;
+            sendVariableReadEvent(_scopeFrame.resolve(dref.variable));
+            Node data = fetchVariableData(
+                    _scopeFrame.resolve(dref.variable), false);
+            retVal = DOMUtils.findChildByName((Element)data, dref.elName);
+        } else if (from instanceof OAssign.VariableRef) {
+            OAssign.VariableRef varRef = (OAssign.VariableRef) from;
+            sendVariableReadEvent(_scopeFrame.resolve(varRef.variable));
+            Node data = fetchVariableData(_scopeFrame.resolve(varRef.variable), false);
+            retVal = evalQuery(data, varRef.part != null ? varRef.part : varRef.headerPart, varRef.location, getEvaluationContext());
+        } else if (from instanceof OAssign.PropertyRef) {
+            OAssign.PropertyRef propRef = (OAssign.PropertyRef) from;
+            sendVariableReadEvent(_scopeFrame.resolve(propRef.variable));
+            Node data = fetchVariableData(_scopeFrame.resolve(propRef.variable), false);
+            retVal = evalQuery(data, propRef.propertyAlias.part,
+                    propRef.propertyAlias.location, getEvaluationContext());
+        } else if (from instanceof OAssign.PartnerLinkRef) {
+            OAssign.PartnerLinkRef pLinkRef = (OAssign.PartnerLinkRef) from;
+            PartnerLinkInstance pLink = _scopeFrame.resolve(pLinkRef.partnerLink);
+            Node tempVal =pLinkRef.isMyEndpointReference ?
+                    getBpelRuntime().fetchMyRoleEndpointReferenceData(pLink)
+                    : getBpelRuntime().fetchPartnerRoleEndpointReferenceData(pLink);
+            if (__log.isDebugEnabled())
+                __log.debug("RValue is a partner link, corresponding endpoint "
+                        + tempVal.getClass().getName() + " has value " + DOMUtils.domToString(tempVal));
+            retVal = tempVal;
+        } else if (from instanceof OAssign.Expression) {
+            OExpression expr = ((OAssign.Expression) from).expression;
+            List<Node> l = getBpelRuntime().getExpLangRuntime().evaluate(expr, getEvaluationContext());
+            if (l.size() == 0) {
+                String msg = __msgs.msgRValueNoNodesSelected(expr.toString());
+                if (__log.isDebugEnabled()) __log.debug(from + ": " + msg);
+                throw new FaultException(getOAsssign().getOwner().constants.qnSelectionFailure, msg, new Throwable("ignoreMissingFromData"));
+            } else if (l.size() > 1) {
+                String msg = __msgs.msgRValueMultipleNodesSelected(expr.toString());
+                if (__log.isDebugEnabled()) __log.debug(from + ": " + msg);
+                throw new FaultException(getOAsssign().getOwner().constants.qnSelectionFailure, msg);
+            }
+            retVal = (Node) l.get(0);
+        } else if (from instanceof OAssign.Literal) {
+            Element literalRoot = ((OAssign.Literal) from).getXmlLiteral().getDocumentElement();
+            assert literalRoot.getLocalName().equals("literal");
+            // We'd like a single text node...
+
+            literalRoot.normalize();
+            retVal = literalRoot.getFirstChild();
+
+            // Adjust for whitespace before an element.
+            if (retVal != null && retVal.getNodeType() == Node.TEXT_NODE
+                    && retVal.getTextContent().trim().length() == 0
+                    && retVal.getNextSibling() != null) {
+                retVal = retVal.getNextSibling();
+            }
+
+            if (retVal == null) {
+                // Special case, no children --> empty TII
+                retVal = literalRoot.getOwnerDocument().createTextNode("");
+            } else if (retVal.getNodeType() == Node.ELEMENT_NODE) {
+                // Make sure there is no more elements.
+                Node x = retVal.getNextSibling();
+                while (x != null) {
+                    if (x.getNodeType() == Node.ELEMENT_NODE) {
+                        String msg = __msgs.msgLiteralContainsMultipleEIIs();
+                        if (__log.isDebugEnabled())
+                            __log.debug(from + ": " + msg);
+                        throw new FaultException(
+                                getOAsssign().getOwner().constants.qnSelectionFailure,
+                                msg);
+
+                    }
+                    x = x.getNextSibling();
+                }
+            } else if (retVal.getNodeType() == Node.TEXT_NODE) {
+                // Make sure there are no elements following this text node.
+                Node x = retVal.getNextSibling();
+                while (x != null) {
+                    if (x.getNodeType() == Node.ELEMENT_NODE) {
+                        String msg = __msgs.msgLiteralContainsMixedContent();
+                        if (__log.isDebugEnabled())
+                            __log.debug(from + ": " + msg);
+                        throw new FaultException(
+                                getOAsssign().getOwner().constants.qnSelectionFailure,
+                                msg);
+
+                    }
+                    x = x.getNextSibling();
+                }
+
+            }
+
+            if (retVal == null) {
+                String msg = __msgs.msgLiteralMustContainTIIorEII();
+                if (__log.isDebugEnabled())
+                    __log.debug(from + ": " + msg);
+                throw new FaultException(
+                        getOAsssign().getOwner().constants.qnSelectionFailure,
+                        msg);
+            }
+        } else {
+            String msg = __msgs
+                    .msgInternalError("Unknown RVALUE type: " + from);
+            if (__log.isErrorEnabled())
+                __log.error(from + ": " + msg);
+            throw new FaultException(
+                    getOAsssign().getOwner().constants.qnSelectionFailure, msg);
+        }
+
+        // Now verify we got something.
+        if (retVal == null) {
+            String msg = __msgs.msgEmptyRValue();
+            if (__log.isDebugEnabled())
+                __log.debug(from + ": " + msg);
+            throw new FaultException(
+                    getOAsssign().getOwner().constants.qnSelectionFailure, msg);
+        }
+
+        // Now check that we got the right thing.
+        switch (retVal.getNodeType()) {
+            case Node.TEXT_NODE:
+            case Node.ATTRIBUTE_NODE:
+            case Node.ELEMENT_NODE:
+            case Node.CDATA_SECTION_NODE:
+                break;
+            default:
+                String msg = __msgs.msgInvalidRValue();
+                if (__log.isDebugEnabled())
+                    __log.debug(from + ": " + msg);
+
+                throw new FaultException(
+                        getOAsssign().getOwner().constants.qnSelectionFailure, msg);
+
+        }
+
+        return retVal;
+    }
+
+	private void copy(OAssign.Copy ocopy) throws FaultException, ExternalVariableModuleException {
+
+        if (__log.isDebugEnabled())
+            __log.debug("Assign.copy(" + ocopy + ")");
+        
+        ScopeEvent se;
+
+        // Check for message to message - copy, we can do this efficiently in
+        // the database.
+        if ((ocopy.to instanceof VariableRef && ((VariableRef) ocopy.to)
+                .isMessageRef())
+                || (ocopy.from instanceof VariableRef && ((VariableRef) ocopy.from)
+                .isMessageRef())) {
+
+            if ((ocopy.to instanceof VariableRef && ((VariableRef) ocopy.to)
+                    .isMessageRef())
+                    && ocopy.from instanceof VariableRef
+                    && ((VariableRef) ocopy.from).isMessageRef()) {
+
+                final VariableInstance lval = _scopeFrame.resolve(ocopy.to
+                        .getVariable());
+                final VariableInstance rval = _scopeFrame
+                        .resolve(((VariableRef) ocopy.from).getVariable());
+                Element lvalue = (Element) fetchVariableData(rval, false);
+                initializeVariable(lval, lvalue);
+                se = new VariableModificationEvent(lval.declaration.name);
+                ((VariableModificationEvent)se).setNewValue(lvalue);
+            } else {
+                // This really should have been caught by the compiler.
+                __log
+                        .fatal("Message/Non-Message Assignment, should be caught by compiler:"
+                                + ocopy);
+                throw new FaultException(
+                        ocopy.getOwner().constants.qnSelectionFailure,
+                        "Message/Non-Message Assignment:  " + ocopy);
+            }
+        } else {
+            // Conventional Assignment logic.
+            Node rvalue = evalRValue(ocopy.from);
+            Node lvalue = evalLValue(ocopy.to);
+            if (__log.isDebugEnabled()) {
+                __log.debug("lvalue after eval " + lvalue);
+                if (lvalue != null) __log.debug("content " + DOMUtils.domToString(lvalue));
+            }
+
+            // Get a pointer within the lvalue.
+            Node lvaluePtr = lvalue;
+            boolean headerAssign = false;
+            if (ocopy.to instanceof OAssign.DirectRef) {
+                DirectRef dref = ((DirectRef) ocopy.to);
+                Element el = DOMUtils.findChildByName((Element)lvalue, dref.elName);
+                if (el == null) {
+                    el = (Element) ((Element)lvalue).appendChild(lvalue.getOwnerDocument()
+                            .createElementNS(dref.elName.getNamespaceURI(), dref.elName.getLocalPart()));
+                }
+                lvaluePtr = el;
+            } else if (ocopy.to instanceof OAssign.VariableRef) {
+                VariableRef varRef = ((VariableRef) ocopy.to);
+                if (varRef.headerPart != null) headerAssign = true;
+                lvaluePtr = evalQuery(lvalue, varRef.part != null ? varRef.part : varRef.headerPart, varRef.location,
+                        new EvaluationContextProxy(varRef.getVariable(), lvalue));
+            } else if (ocopy.to instanceof OAssign.PropertyRef) {
+                PropertyRef propRef = ((PropertyRef) ocopy.to);
+                lvaluePtr = evalQuery(lvalue, propRef.propertyAlias.part,
+                        propRef.propertyAlias.location,
+                        new EvaluationContextProxy(propRef.getVariable(),
+                                lvalue));
+            } else if (ocopy.to instanceof OAssign.LValueExpression) {
+                LValueExpression lexpr = (LValueExpression) ocopy.to;
+                lvaluePtr = evalQuery(lvalue, null, lexpr.expression,
+                        new EvaluationContextProxy(lexpr.getVariable(), lvalue));
+                if (__log.isDebugEnabled())
+                    __log.debug("lvaluePtr expr res " + lvaluePtr);
+            }
+
+            // For partner link assignmenent, the whole content is assigned.
+            if (ocopy.to instanceof OAssign.PartnerLinkRef) {
+                OAssign.PartnerLinkRef pLinkRef = ((OAssign.PartnerLinkRef) ocopy.to);
+                PartnerLinkInstance plval = _scopeFrame
+                        .resolve(pLinkRef.partnerLink);
+                replaceEndpointRefence(plval, rvalue);
+                se = new PartnerLinkModificationEvent(((OAssign.PartnerLinkRef) ocopy.to).partnerLink.getName());
+            } else {
+                // Sneakily converting the EPR if it's not the format expected by the lvalue
+                if (ocopy.from instanceof OAssign.PartnerLinkRef) {
+                    rvalue = getBpelRuntime().convertEndpointReference((Element)rvalue, lvaluePtr);
+                    if (rvalue.getNodeType() == Node.DOCUMENT_NODE)
+                        rvalue = ((Document)rvalue).getDocumentElement();
+                }
+
+                if (headerAssign && lvaluePtr.getParentNode().getNodeName().equals("message") && rvalue.getNodeType()==Node.ELEMENT_NODE) {
+                    lvalue = copyInto((Element)lvalue, (Element) lvaluePtr, (Element) rvalue);
+                } else if (rvalue.getNodeType() == Node.ELEMENT_NODE && lvaluePtr.getNodeType() == Node.ELEMENT_NODE) {
+                    lvalue = replaceElement((Element)lvalue, (Element) lvaluePtr, (Element) rvalue,
+                            ocopy.keepSrcElementName);
+                } else {
+                    lvalue = replaceContent(lvalue, lvaluePtr, rvalue.getTextContent());
+                }
+                final VariableInstance lval = _scopeFrame.resolve(ocopy.to.getVariable());
+                if (__log.isDebugEnabled())
+                    __log.debug("ASSIGN Writing variable '" + lval.declaration.name +
+                                "' value '" + DOMUtils.domToString(lvalue) +"'");
+                commitChanges(lval, lvalue);
+                se = new VariableModificationEvent(lval.declaration.name);
+                ((VariableModificationEvent)se).setNewValue(lvalue);
+            }
+        }
+
+        if (ocopy.debugInfo != null)
+            se.setLineNo(ocopy.debugInfo.startLine);
+        sendEvent(se);
+    }
+
+	@Override
+	Node fetchVariableData(VariableInstance variable, boolean forWriting)
+			throws FaultException {
+		try {
+			return super.fetchVariableData(variable, forWriting);
+		} catch (FaultException fe) {
+			if (forWriting) {
+				fe = new FaultException(fe.getQName(), fe.getMessage(), new Throwable("throwUninitializedToVariable"));
+			}
+			throw fe;
+		}
+	}
+	
+	private void replaceEndpointRefence(PartnerLinkInstance plval, Node rvalue) throws FaultException {
+        // Eventually wrapping with service-ref element if we've been directly assigned some
+        // value that isn't wrapped.
+        if (rvalue.getNodeType() == Node.TEXT_NODE ||
+                (rvalue.getNodeType() == Node.ELEMENT_NODE && !rvalue.getLocalName().equals("service-ref"))) {
+            Document doc = DOMUtils.newDocument();
+            Element serviceRef = doc.createElementNS(Namespaces.WSBPEL2_0_FINAL_SERVREF, "service-ref");
+            doc.appendChild(serviceRef);
+            if (rvalue.getNodeType() == Node.TEXT_NODE) {
+                serviceRef.appendChild(doc.importNode(rvalue, true));
+            } else {
+                NodeList children = rvalue.getChildNodes();
+                for (int m = 0; m < children.getLength(); m++) {
+                    Node child = children.item(m);
+                    serviceRef.appendChild(doc.importNode(child, true));
+                }
+            }
+            rvalue = serviceRef;
+        }
+
+        getBpelRuntime().writeEndpointReference(plval, (Element)rvalue);
+    }
+
+    private Element replaceElement(Element lval, Element ptr, Element src,
+                                boolean keepSrcElement) {
+        Document doc = ptr.getOwnerDocument();
+        Node parent = ptr.getParentNode();
+        if (keepSrcElement) {
+            Element replacement = (Element)doc.importNode(src, true);
+            parent.replaceChild(replacement, ptr);
+            return (lval == ptr) ? replacement :  lval;
+        }
+
+        Element replacement = doc.createElementNS(ptr.getNamespaceURI(), ptr.getLocalName());
+        NodeList nl = src.getChildNodes();
+        for (int i = 0; i < nl.getLength(); ++i)
+            replacement.appendChild(doc.importNode(nl.item(i), true));
+        NamedNodeMap attrs = src.getAttributes();
+        for (int i = 0; i < attrs.getLength(); ++i) {
+            Attr attr = (Attr)attrs.item(i);
+            if (!attr.getName().startsWith("xmlns")) {
+                replacement.setAttributeNodeNS((Attr)doc.importNode(attrs.item(i), true));
+                // Case of qualified attribute values, we're forced to add corresponding namespace declaration manually
+                int colonIdx = attr.getValue().indexOf(":");
+                if (colonIdx > 0) {
+                    String prefix = attr.getValue().substring(0, colonIdx);
+                    String attrValNs = src.lookupPrefix(prefix);
+                    if (attrValNs != null)
+                       replacement.setAttributeNS(DOMUtils.NS_URI_XMLNS, "xmlns:"+ prefix, attrValNs);
+                }
+            }
+        }
+        parent.replaceChild(replacement, ptr);
+        DOMUtils.copyNSContext(ptr, replacement);
+        
+        return (lval == ptr) ? replacement :  lval;
+    }
+
+    private Element copyInto(Element lval, Element ptr, Element src) {
+        ptr.appendChild(ptr.getOwnerDocument().importNode(src, true));
+        return lval;
+    }
+
+    /**
+     * isInsert flag desginates this as an 'element' type insertion, which
+     * requires insert the actual element value, rather than it's children
+     *
+     * @return
+     * @throws FaultException
+     */
+    private Node replaceContent(Node lvalue, Node lvaluePtr, String rvalue)
+            throws FaultException {
+        Document d = lvaluePtr.getOwnerDocument();
+
+        if (__log.isDebugEnabled()) {
+            __log.debug("lvaluePtr type " + lvaluePtr.getNodeType());
+            __log.debug("lvaluePtr " + DOMUtils.domToString(lvaluePtr));
+            __log.debug("lvalue " + lvalue);
+            __log.debug("rvalue " + rvalue);
+        }
+
+        switch (lvaluePtr.getNodeType()) {
+            case Node.ELEMENT_NODE:
+
+                // Remove all the children.
+                while (lvaluePtr.hasChildNodes())
+                    lvaluePtr.removeChild(lvaluePtr.getFirstChild());
+
+                // Append a new text node.
+                lvaluePtr.appendChild(d.createTextNode(rvalue));
+
+                // If lvalue is a text, removing all lvaluePtr children had just removed it
+                // so we need to rebuild it as a child of lvaluePtr
+                if (lvalue instanceof Text)
+                    lvalue = lvaluePtr.getFirstChild();
+                break;
+
+            case Node.TEXT_NODE:
+
+                Node newval = d.createTextNode(rvalue);
+                // Replace ourselves .
+                lvaluePtr.getParentNode().replaceChild(newval, lvaluePtr);
+
+                // A little kludge, let our caller know that the root element has changed.
+                // (used for assignment to a simple typed variable)
+                if (lvalue.getNodeType() == Node.ELEMENT_NODE) {
+                    // No children, adding an empty text children to point to
+                    if (lvalue.getFirstChild() == null) {
+                        Text txt = lvalue.getOwnerDocument().createTextNode("");
+                        lvalue.appendChild(txt);
+                    }
+                    if (lvalue.getFirstChild().getNodeType() == Node.TEXT_NODE)
+                        lvalue = lvalue.getFirstChild();
+                }
+                if (lvalue.getNodeType() == Node.TEXT_NODE && ((Text) lvalue).getWholeText().equals(
+                        ((Text) lvaluePtr).getWholeText()))
+                    lvalue = lvaluePtr = newval;
+                break;
+
+            case Node.ATTRIBUTE_NODE:
+
+                ((Attr) lvaluePtr).setValue(rvalue);
+                break;
+
+            default:
+                // This could occur if the expression language selects something
+                // like
+                // a PI or a CDATA.
+                String msg = __msgs.msgInvalidLValue();
+                if (__log.isDebugEnabled())
+                    __log.debug(lvaluePtr + ": " + msg);
+                throw new FaultException(
+                        getOAsssign().getOwner().constants.qnSelectionFailure, msg);
+        }
+
+        return lvalue;
+    }
+
+    private Node evalQuery(Node data, OMessageVarType.Part part,
+                           OExpression expression, EvaluationContext ec) throws FaultException {
+        assert data != null;
+
+        if (part != null) {
+            QName partName = new QName(null, part.name);
+            Node qualLVal = DOMUtils.findChildByName((Element) data, partName);
+            if (part.type instanceof OElementVarType) {
+                QName elName = ((OElementVarType) part.type).elementType;
+                qualLVal = DOMUtils.findChildByName((Element) qualLVal, elName);
+            } else if (part.type == null) {
+                // Special case of header parts never referenced in the WSDL def
+                if (qualLVal != null && qualLVal.getNodeType() == Node.ELEMENT_NODE
+                        && ((Element)qualLVal).getAttribute("headerPart") != null
+                        && DOMUtils.getTextContent(qualLVal) == null)
+                    qualLVal = DOMUtils.getFirstChildElement((Element) qualLVal);
+                // The needed part isn't there, dynamically creating it
+                if (qualLVal == null) {
+                    qualLVal = data.getOwnerDocument().createElementNS(null, part.name);
+                    ((Element)qualLVal).setAttribute("headerPart", "true");
+                    data.appendChild(qualLVal);
+                }
+            }
+            data = qualLVal;
+        }
+
+        if (expression != null) {
+            // Neat little trick....
+            data = ec.evaluateQuery(data, expression);
+        }
+
+        return data;
+    }
+
+    private class EvaluationContextProxy implements EvaluationContext {
+
+        private Variable _var;
+
+        private Node _varNode;
+
+        private Node _rootNode;
+
+        private EvaluationContext _ctx;
+
+        private EvaluationContextProxy(Variable var, Node varNode) {
+            _var = var;
+            _varNode = varNode;
+            _ctx = getEvaluationContext();
+
+        }
+
+        public Node readVariable(OScope.Variable variable, OMessageVarType.Part part) throws FaultException {
+            if (variable.name.equals(_var.name)) {
+                if (part == null) return _varNode;
+                return _ctx.getPartData((Element)_varNode, part);
+
+            } else
+                return _ctx.readVariable(variable, part);
+
+        }		/**
+     * @see org.apache.ode.bpel.explang.EvaluationContext#readMessageProperty(org.apache.ode.bpel.rtrep.v1.OScope.Variable,
+     *      org.apache.ode.bpel.rtrep.v1.OProcess.OProperty)
+     */
+    public String readMessageProperty(Variable variable, OProperty property)
+            throws FaultException {
+        return _ctx.readMessageProperty(variable, property);
+    }
+
+        /**
+         * @see org.apache.ode.bpel.explang.EvaluationContext#isLinkActive(org.apache.ode.bpel.rtrep.v1.OLink)
+         */
+        public boolean isLinkActive(OLink olink) throws FaultException {
+            return _ctx.isLinkActive(olink);
+        }
+
+        /**
+         * @see org.apache.ode.bpel.explang.EvaluationContext#getRootNode()
+         */
+        public Node getRootNode() {
+            return _rootNode;
+        }
+
+        /**
+         * @see org.apache.ode.bpel.explang.EvaluationContext#evaluateQuery(org.w3c.dom.Node,
+         *      org.apache.ode.bpel.rtrep.v1.OExpression)
+         */
+        public Node evaluateQuery(Node root, OExpression expr)
+                throws FaultException {
+            _rootNode = root;
+            return getBpelRuntime().getExpLangRuntime().evaluateNode(expr, this);
+        }
+
+        public Node getPartData(Element message, Part part) throws FaultException {
+            return _ctx.getPartData(message,part);
+        }
+
+        public Long getProcessId() {
+            return _ctx.getProcessId();
+        }
+
+        public boolean narrowTypes() {
+            return false;
+        }
+
+		public URI getBaseResourceURI() {
+			return _ctx.getBaseResourceURI();
+		}
+    }
+
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ASSIGNMessages.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ASSIGNMessages.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ASSIGNMessages.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ASSIGNMessages.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,96 @@
+
+/*
+ * 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.rtrep.v1;
+
+import org.apache.ode.utils.msg.MessageBundle;
+
+/**
+ * Internationalization for messages related to assignment.
+ */
+public class ASSIGNMessages extends MessageBundle {
+
+  /** R-Value expression "{0}" returned multiple nodes. */
+  public String msgRValueMultipleNodesSelected(String rvalue) {
+    return this.format("R-Value expression \"{0}\" returned multiple nodes.", rvalue);
+  }
+
+  /** R-Value expression "{0}" did not select any nodes. */
+  public String msgRValueNoNodesSelected(String rvalue) {
+    return this.format("R-Value expression \"{0}\" did not select any nodes.", rvalue);
+  }
+
+  /** A literal must not contain more than one element information item (EII). */
+  public String msgLiteralContainsMultipleEIIs() {
+    return this
+        .format("A literal must not contain more than one element information item (EII).");
+  }
+
+  /** A literal must not contain mixed content. */
+  public String msgLiteralContainsMixedContent() {
+    return this.format("A literal must not contain mixed content.");
+  }
+
+  /**
+   * A literal must contain either a text information item (TII) or a single
+   * element information item (EII).
+   */
+  public String msgLiteralMustContainTIIorEII() {
+    return this.format("A literal must contain either a text information item (TII)"
+        + " or a single element information item (EII).");
+  }
+
+  /** InternalError: Unexpected selection failure (contact tech support): {0} */
+  public String msgInternalError(String msg) {
+    return this.format(
+        "InternalError: Unexpected selection failure (contact tech support): {0}", msg);
+  }
+
+  /**
+   * An exception occured while evaluating "{0}": {1}
+   */
+  public String msgEvalException(String expr, String msg) {
+    return this.format("An exception occured while evaluating \"{0}\": {1}", expr, msg);
+  }
+
+  /** The R-Value must select one item. */
+  public String msgEmptyRValue() {
+    return this.format("The R-Value must select one item.");
+  }
+
+  /**
+   * The R-Value must be a text information item (TII) or element information
+   * item (EII).
+   */
+  public String msgInvalidRValue() {
+    return this.format("The R-Value must be a text information item (TII) or"
+        + " element information item (EII)");
+  }
+
+  /**
+   * The L-Value must be a text information item (TII), element information item
+   * (EII), or attribute information item (AII).
+   */
+  public String msgInvalidLValue() {
+    return this.format("The L-Value must be a text information item (TII),"
+        + " element information item (EII), or attribute information item (AII).");
+  }
+
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ActivityInfo.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ActivityInfo.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ActivityInfo.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ActivityInfo.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,63 @@
+/*
+ * 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.rtrep.v1;
+
+import java.io.Serializable;
+
+import org.apache.ode.bpel.rtrep.v1.channels.ParentScopeChannel;
+import org.apache.ode.bpel.rtrep.v1.channels.TerminationChannel;
+
+class ActivityInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    /** Activity instance identifier */
+    long aId;
+    
+    /** Activity definition. */
+    OActivity o;
+    TerminationChannel self;
+    ParentScopeChannel parent;
+    
+    ActivityInfo(long aid, OActivity o, TerminationChannel self, ParentScopeChannel parent) {
+        assert o != null;
+        assert self != null;
+        assert parent != null;
+        
+        this.o = o;
+        this.self = self;
+        this.parent = parent;
+        this.aId = aid;
+    }
+
+    public String toString() {
+        StringBuffer buf = new StringBuffer("(");
+        buf.append(o);
+        buf.append(',');
+        buf.append(self);
+        buf.append(',');
+        buf.append(parent);
+        buf.append(')');
+        return buf.toString();
+    }
+    
+    public int hashCode() {
+        return (int)aId;
+    }
+
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ActivityTemplateFactory.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ActivityTemplateFactory.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ActivityTemplateFactory.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ActivityTemplateFactory.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,48 @@
+/*
+ * 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.rtrep.v1;
+
+/**
+ * Factory for creating activity template objects.
+ */
+public class ActivityTemplateFactory {
+  
+  public ACTIVITY createInstance(OActivity type, ActivityInfo ai, ScopeFrame scopeFrame, LinkFrame linkFrame) {
+    if (type instanceof OThrow) return new THROW(ai, scopeFrame, linkFrame);
+    if (type instanceof OEmpty) return new EMPTY(ai, scopeFrame, linkFrame);
+    if (type instanceof OAssign) return new ASSIGN(ai, scopeFrame, linkFrame);
+    if (type instanceof OCompensate) return new COMPENSATE(ai, scopeFrame, linkFrame);
+    if (type instanceof OFlow) return new FLOW(ai, scopeFrame, linkFrame);
+    if (type instanceof OInvoke) return new INVOKE(ai, scopeFrame, linkFrame);
+    if (type instanceof OPickReceive) return new PICK(ai, scopeFrame, linkFrame);
+    if (type instanceof OReply) return new REPLY(ai, scopeFrame, linkFrame);
+    if (type instanceof ORethrow) return new RETHROW(ai, scopeFrame, linkFrame);
+    if (type instanceof OScope) return new SCOPEACT(ai, scopeFrame, linkFrame);
+    if (type instanceof OSequence) return new SEQUENCE(ai, scopeFrame, linkFrame);
+    if (type instanceof OSwitch) return new SWITCH(ai, scopeFrame, linkFrame);
+    if (type instanceof OTerminate) return new TERMINATE(ai, scopeFrame, linkFrame);
+    if (type instanceof OWait) return new WAIT(ai, scopeFrame, linkFrame);
+    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);
+
+    throw new IllegalArgumentException("Unknown type: " + type);
+  }
+
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/BpelJacobRunnable.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/BpelJacobRunnable.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/BpelJacobRunnable.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/BpelJacobRunnable.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.rtrep.v1;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.CorrelationKey;
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.rtrep.v1.channels.FaultData;
+import org.apache.ode.bpel.rapi.OdeRTInstanceContext;
+import org.apache.ode.jacob.JacobRunnable;
+import org.apache.ode.jacob.vpu.JacobVPU;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Base class extended by all BPEL-related abstractions. Provides methods for
+ * manipulating the BPEL database, creating faults, and accessing the native
+ * facilities.
+ *
+ * Created on Jan 12, 2004 at 5:41:27 PM.
+ * @author Maciej Szefler
+ */
+public abstract class BpelJacobRunnable extends JacobRunnable {
+    private static final Log __log = LogFactory.getLog(BpelJacobRunnable.class);
+
+    protected OdeInternalInstance getBpelRuntime() {
+        OdeInternalInstance nativeApi = (OdeInternalInstance) JacobVPU.activeJacobThread().getExtension(OdeRTInstanceContext.class);
+        assert nativeApi != null;
+        return nativeApi;
+    }
+
+    protected Log log() {
+        return __log;
+    }
+    
+    protected final FaultData createFault(QName fault, Element faultMsg, OVarType faultType, OBase location){
+        return new FaultData(fault, faultMsg, faultType, location);
+    }
+    
+    protected final FaultData createFault(QName fault, OBase location, String faultExplanation) {
+        return new FaultData(fault, location,faultExplanation);
+    }
+
+    protected final FaultData createFault(QName fault, OBase location){
+        return createFault(fault, location, null);
+    }
+    
+
+    protected JacobRunnable createChild(ActivityInfo childInfo, ScopeFrame scopeFrame, LinkFrame linkFrame) {
+        return new ACTIVITYGUARD(childInfo, scopeFrame, linkFrame);
+    }
+
+    protected void initializeCorrelation(CorrelationSetInstance cset, VariableInstance variable)
+            throws FaultException {
+        if (__log.isDebugEnabled()) {
+          __log.debug("Initializing correlation set " + cset.declaration.name);
+        }
+        // if correlation set is already initialized,
+        // then skip
+        if (getBpelRuntime().isCorrelationInitialized(cset)) {
+          // if already set, we ignore
+            if (__log.isDebugEnabled()) {
+                __log.debug("OCorrelation set " + cset + " is already set: ignoring");
+            }
+
+            return;
+        }
+
+        String[] propNames = new String[cset.declaration.properties.size()];
+        String[] propValues = new String[cset.declaration.properties.size()];
+
+        for (int i = 0; i < cset.declaration.properties.size(); ++i) {
+            OProcess.OProperty property = cset.declaration.properties.get(i);
+            propValues[i] = getBpelRuntime().readProperty(variable, property);
+            propNames[i] = property.name.toString();
+            if (__log.isDebugEnabled())
+              __log.debug("Setting correlation property " + propNames[i] + "=" + propValues[i]);
+        }
+
+        CorrelationKey ckeyVal = new CorrelationKey(cset.declaration.getId(), propValues);
+        getBpelRuntime().writeCorrelation(cset,ckeyVal);
+    }
+    
+    protected long genMonotonic() {
+        return getBpelRuntime().genId();
+    }
+
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/COMPENSATE.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/COMPENSATE.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/COMPENSATE.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/COMPENSATE.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,49 @@
+/*
+ * 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.rtrep.v1;
+
+import org.apache.ode.jacob.SynchChannel;
+import org.apache.ode.jacob.SynchChannelListener;
+
+
+/**
+ * Runtime implementation of the <code>&lt;compensate&gt;</code> activity.
+ */
+class COMPENSATE extends ACTIVITY {
+    private static final long serialVersionUID = -467758076635337675L;
+    private OCompensate _ocompact;
+
+    public COMPENSATE(ActivityInfo self, ScopeFrame scopeFrame, LinkFrame linkFrame) {
+        super(self, scopeFrame, linkFrame);
+        _ocompact = (OCompensate) self.o;
+    }
+
+    public final void run() {
+        OScope scopeToCompensate = _ocompact.compensatedScope;
+        SynchChannel sc = newChannel(SynchChannel.class);
+        _self.parent.compensate(scopeToCompensate,sc);
+        object(new SynchChannelListener(sc) {
+            private static final long serialVersionUID = 3763991229748926216L;
+
+            public void ret() {
+                _self.parent.completed(null, CompensationHandler.emptySet());
+            }
+        });
+    }
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/COMPENSATIONHANDLER_.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/COMPENSATIONHANDLER_.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/COMPENSATIONHANDLER_.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/COMPENSATIONHANDLER_.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,115 @@
+/*
+ * 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.rtrep.v1;
+
+import org.apache.ode.bpel.evt.CompensationHandlerRegistered;
+import org.apache.ode.bpel.evt.ScopeEvent;
+import org.apache.ode.bpel.rtrep.v1.OScope;
+import org.apache.ode.bpel.rtrep.v1.channels.CompensationChannelListener;
+import org.apache.ode.bpel.rtrep.v1.channels.FaultData;
+import org.apache.ode.bpel.rtrep.v1.channels.ParentScopeChannel;
+import org.apache.ode.bpel.rtrep.v1.channels.ParentScopeChannelListener;
+import org.apache.ode.bpel.rtrep.v1.channels.TerminationChannel;
+import org.apache.ode.jacob.SynchChannel;
+
+import java.util.Iterator;
+import java.util.Set;
+import org.w3c.dom.Element;
+
+/**
+ * A scope that has completed succesfully, and may possibly have a compensation handler.
+ */
+class COMPENSATIONHANDLER_ extends BpelJacobRunnable {
+    private static final long serialVersionUID = 1L;
+    private CompensationHandler _self;
+    private Set<CompensationHandler> _completedChildren;
+
+    public COMPENSATIONHANDLER_(CompensationHandler self, Set<CompensationHandler> visibleCompensations) {
+        _self = self;
+        _completedChildren = visibleCompensations;
+    }
+
+    public void run() {
+        sendEvent(new CompensationHandlerRegistered());
+        object(new CompensationChannelListener(_self.compChannel) {
+            private static final long serialVersionUID = -477602498730810094L;
+
+            public void forget() {
+                // Tell all our completed children to forget.
+                for (Iterator<CompensationHandler> i = _completedChildren.iterator(); i.hasNext(); )
+                    i.next().compChannel.forget();
+            }
+
+            public void compensate(final SynchChannel ret) {
+                // Only scopes with compensation handlers can be compensated.
+                assert _self.compensated.oscope.compensationHandler != null;
+
+                ActivityInfo ai = new ActivityInfo(genMonotonic(),
+                    _self.compensated.oscope.compensationHandler,
+                    newChannel(TerminationChannel.class), newChannel(ParentScopeChannel.class));
+
+
+                ScopeFrame compHandlerScopeFrame = new ScopeFrame(
+                    _self.compensated.oscope.compensationHandler,
+                    getBpelRuntime().createScopeInstance(_self.compensated.scopeInstanceId, _self.compensated.oscope.compensationHandler),
+                    _self.compensated,
+                    _completedChildren);
+
+                // Create the compensation handler scope.
+                instance(new SCOPE(ai,compHandlerScopeFrame, new LinkFrame(null)));
+
+                object(new ParentScopeChannelListener(ai.parent) {
+                    private static final long serialVersionUID = 8044120498580711546L;
+
+                    public void compensate(OScope scope, SynchChannel ret) {
+                        throw new AssertionError("Unexpected.");
+                    }
+
+                    public void completed(FaultData faultData, Set<CompensationHandler> compensations) {
+                        // TODO: log faults.
+
+                        // Compensations registered in a compensation handler are unreachable.
+                        for (Iterator<CompensationHandler> i = compensations.iterator();i.hasNext(); ) {
+                          i.next().compChannel.forget();
+                        }
+
+                        // Notify synchronized waiter that we are done.
+                        ret.ret();
+                    }
+
+                    public void cancelled() { completed(null, CompensationHandler.emptySet()); }
+                    public void failure(String reason, Element data) { completed(null, CompensationHandler.emptySet()); }
+                });
+            }
+        });
+    }
+
+    private void sendEvent(ScopeEvent event) {
+        _self.compensated.fillEventInfo(event);
+        getBpelRuntime().sendEvent(event);
+    }
+
+    public String toString() {
+       return new StringBuffer(getClassName())
+        .append(":")
+        .append(_self.compensated)
+        .append("(...)")
+        .toString();
+    }
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ChildInfo.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ChildInfo.java?rev=693931&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ChildInfo.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/ChildInfo.java Wed Sep 10 12:06:59 2008
@@ -0,0 +1,42 @@
+/*
+ * 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.rtrep.v1;
+
+import java.io.Serializable;
+
+/**
+ * Infomration about a child.
+ */
+class ChildInfo implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/** Has it been completed? */
+  boolean completed;
+
+  /** The child agent. */
+  ActivityInfo activity;
+
+  /** a terminate message has been sent to child */
+  boolean terminated;
+
+  ChildInfo(ActivityInfo activity) {
+    this.activity = activity;
+  }
+
+}