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/19 02:23:07 UTC

svn commit: r696869 - in /ode/sandbox/simpel: ./ src/main/antlr/org/apache/ode/simpel/antlr/ src/main/java/org/apache/ode/ src/main/java/org/apache/ode/embed/ src/main/java/org/apache/ode/embed/messaging/ src/main/java/org/apache/ode/simpel/omodel/ src...

Author: mriou
Date: Thu Sep 18 17:23:06 2008
New Revision: 696869

URL: http://svn.apache.org/viewvc?rev=696869&view=rev
Log:
One way block invokes. Shaping up the messaging side of the embedded IL.

Added:
    ode/sandbox/simpel/src/main/java/org/apache/ode/embed/MessageSender.java
    ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/
    ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/BindingContextImpl.java
      - copied, changed from r693540, ode/sandbox/simpel/src/main/java/org/apache/ode/embed/BindingContextImpl.java
    ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java
Removed:
    ode/sandbox/simpel/src/main/java/org/apache/ode/embed/BindingContextImpl.java
Modified:
    ode/sandbox/simpel/Rakefile
    ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g
    ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g
    ode/sandbox/simpel/src/main/java/org/apache/ode/EmbeddedServer.java
    ode/sandbox/simpel/src/main/java/org/apache/ode/Options.java
    ode/sandbox/simpel/src/main/java/org/apache/ode/embed/EmbeddedStore.java
    ode/sandbox/simpel/src/main/java/org/apache/ode/embed/ServerResources.java
    ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java
    ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/SimPELRuntimeTest.java
    ode/sandbox/simpel/src/test/resources/compile-tests-ok.simpel
    ode/sandbox/simpel/src/test/resources/loan-approval.simpel
    ode/sandbox/simpel/src/test/resources/task-manager.simpel

Modified: ode/sandbox/simpel/Rakefile
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/Rakefile?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/Rakefile (original)
+++ ode/sandbox/simpel/Rakefile Thu Sep 18 17:23:06 2008
@@ -40,7 +40,7 @@
 )
 LOG4J               = "log4j:log4j:jar:1.2.15"
 ODE                 = group("ode-bpel-api", "ode-bpel-compiler", "ode-bpel-dao", "ode-runtimes", 
-                            "ode-bpel-runtime", "ode-il-common", "ode-jacob", "ode-scheduler-simple", 
+                            "ode-engine", "ode-il-common", "ode-jacob", "ode-scheduler-simple", 
                             "ode-utils", :under=>"org.apache.ode", :version=>"1.3-SNAPSHOT")
 WSDL4J              = "wsdl4j:wsdl4j:jar:1.6.2"
 XERCES              = "xerces:xercesImpl:jar:2.9.0"

Modified: ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g (original)
+++ ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g Thu Sep 18 17:23:06 2008
@@ -94,7 +94,7 @@
 
 proc_stmt
 	:	pick | flow | if_ex | while_ex | until_ex | foreach | forall | try_ex | scope_ex | with_ex
-		| receive | ((invoke | reply | assign | throw_ex | wait_ex | exit | signal | join
+		| receive | invoke | ((reply | assign | throw_ex | wait_ex | exit | signal | join
 		| variables | partner_link) SEMI!);
 
 block	:	'{' proc_stmt+ '}' -> ^(SEQUENCE proc_stmt+);
@@ -136,21 +136,27 @@
 with_map:       ID ':' path_expr -> ^(MAP ID path_expr);
 
 // Simple activities
-invoke	:	'invoke' '(' p=ID ',' o=ID (',' in=ID)? ')' -> ^(INVOKE $p $o $in?);
+
+invoke
+options {backtrack=true;}
+        :	invoke_base SEMI -> ^(INVOKE invoke_base)
+            | invoke_base param_block -> ^(INVOKE invoke_base) param_block;
+invoke_base
+        :	'invoke' '(' p=ID ',' o=ID (',' in=ID)? ')' -> ^($p $o $in?);
 
 receive	
 options {backtrack=true;}
         :	receive_base SEMI -> ^(RECEIVE receive_base) |
-                receive_base param_block -> ^(RECEIVE receive_base) param_block;
+            receive_base param_block -> ^(RECEIVE receive_base) param_block;
 receive_base
-	:	'receive' '(' p=ID ',' o=ID (',' correlation)? ')' -> ^($p $o correlation?);
+	    :	'receive' '(' p=ID ',' o=ID (',' correlation)? ')' -> ^($p $o correlation?);
 
 reply	:	'reply' '(' ID (',' ID ',' ID)? ')' -> ^(REPLY ID (ID ID)?);
 
 assign	:	path_expr '=' rvalue -> ^(ASSIGN path_expr rvalue);
 rvalue
-	:	 receive_base -> ^(RECEIVE receive_base)
-		| invoke | expr | xml_literal;
+	    :	receive_base -> ^(RECEIVE receive_base)
+		    | invoke | expr | xml_literal;
 	
 throw_ex:	'throw' '('? ns_id ')'? -> ^(THROW ns_id);
 

Modified: ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g (original)
+++ ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g Thu Sep 18 17:23:06 2008
@@ -9,7 +9,7 @@
 }
 scope BPELScope { OScope oscope; }
 scope Parent { OBuilder.StructuredActivity activity; }
-scope ReceiveBlock { OPickReceive receive; }
+scope ReceiveBlock { OActivity activity; }
 scope ExprContext { SimPELExpr expr; }
 
 @header {
@@ -157,15 +157,19 @@
 try_ex
 scope BPELScope;
 	:	^(TRY {
-      OBuilder.StructuredActivity<OScope> oscope = builder.build(OScope.class, null, $Parent::activity);
-      $BPELScope::oscope = oscope.getOActivity();
-    }
-    body catch_ex*);
+            OBuilder.StructuredActivity<OScope> oscope = builder.build(OScope.class, null, $Parent::activity);
+            $BPELScope::oscope = oscope.getOActivity();
+        }
+        body catch_ex*);
 catch_ex:	^(CATCH ^(NS ID ID?) param_block);
 
 scope_ex
 scope BPELScope;
-	:	^(SCOPE ID? body scope_stmt*);
+	:	^(SCOPE {
+            OBuilder.StructuredActivity<OScope> oscope = builder.build(OScope.class, null, $Parent::activity);
+            $BPELScope::oscope = oscope.getOActivity();
+        }
+	    ID? body scope_stmt*);
 scope_stmt
 	:	event | alarm | compensation;
 
@@ -183,24 +187,31 @@
 with_map:       ^(MAP ID path_expr);
 
 // Simple activities
-invoke	:	^(INVOKE p=ID o=ID in=ID?);
 
+invoke
+scope ReceiveBlock;
+        :	^(INVOKE ^(p=ID o=ID in=ID?)) {
+                OBuilder.StructuredActivity<OInvoke> inv = builder.build(OInvoke.class, $BPELScope::oscope,
+                    $Parent::activity, text($p), text($o), text($in));
+		        $ReceiveBlock::activity = inv.getOActivity();
+		    }
+            (prb=(param_block))?;
 
 reply	
   :	^(REPLY msg=ID (pl=ID var=ID)?) {
       if (ReceiveBlock_stack.size() > 0)
         builder.build(OReply.class, $BPELScope::oscope, $Parent::activity,
-			      $ReceiveBlock::receive, text($msg), text($pl), text($var));
+			      $ReceiveBlock::activity, text($msg), text($pl), text($var));
       else
         builder.build(OReply.class, $BPELScope::oscope, $Parent::activity,
 			      null, text($msg), text($pl), text($var));
     };
 receive	
 scope ReceiveBlock;
-	:	^(RECEIVE ^(p=ID o=ID correlation?)) { 
+	:	^(RECEIVE ^(p=ID o=ID correlation?)) {
             OBuilder.StructuredActivity<OPickReceive> rec = builder.build(OPickReceive.class, $BPELScope::oscope,
                 $Parent::activity, text($p), text($o));
-		    $ReceiveBlock::receive = rec.getOActivity();
+		    $ReceiveBlock::activity = rec.getOActivity();
 		}
 		(prb=(param_block))?;
 

Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/EmbeddedServer.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/EmbeddedServer.java?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/EmbeddedServer.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/EmbeddedServer.java Thu Sep 18 17:23:06 2008
@@ -36,15 +36,19 @@
 public class EmbeddedServer {
     private static final Logger __log = Logger.getLogger(EmbeddedServer.class);
 
-    protected Options _options;
+    public Options options;
     protected ServerResources _resources;
 
+    public EmbeddedServer() {
+        this.options = new Options();
+    }
+
     public void start() {
-        start(new Options());
+        start(options);
     }
 
     public void start(Options options) {
-        _options = options;
+        this.options = options;
         _resources = new ServerResources(options);
     }
 

Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/Options.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/Options.java?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/Options.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/Options.java Thu Sep 18 17:23:06 2008
@@ -20,13 +20,15 @@
 
 import org.apache.ode.il.config.OdeConfigProperties;
 import org.apache.ode.bpel.iapi.BpelEventListener;
+import org.apache.ode.bpel.iapi.MessageExchangeContext;
+import org.apache.ode.embed.MessageSender;
 
 import java.io.File;
 import java.util.Properties;
 import java.util.List;
 
 /**
- * @author Matthieu Riou <mr...@apache.org>
+ * Used to customize the behavior of the server in several sort of ways.
  */
 public class Options {
 
@@ -72,7 +74,15 @@
         _eventListeners = listeners;
     }
 
+    public MessageSender getMessageSender() {
+        return (MessageSender) _backingProps.get(MessageSender.class.getName());
+    }
+    public void setMessageSender(MessageSender sender) {
+        _backingProps.put(MessageSender.class.getName(), sender);
+    }
+
     public Properties getProperties() {
         return _backingProps;
     }
+
 }

Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/embed/EmbeddedStore.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/embed/EmbeddedStore.java?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/embed/EmbeddedStore.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/embed/EmbeddedStore.java Thu Sep 18 17:23:06 2008
@@ -24,6 +24,7 @@
 import org.apache.ode.bpel.evt.BpelEvent;
 import org.apache.ode.bpel.iapi.*;
 import org.apache.ode.bpel.rapi.PartnerLinkModel;
+import org.apache.ode.bpel.rapi.Serializer;
 import org.apache.ode.simpel.SimPELCompiler;
 import org.w3c.dom.Node;
 import org.w3c.dom.Element;

Added: ode/sandbox/simpel/src/main/java/org/apache/ode/embed/MessageSender.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/embed/MessageSender.java?rev=696869&view=auto
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/embed/MessageSender.java (added)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/embed/MessageSender.java Thu Sep 18 17:23:06 2008
@@ -0,0 +1,8 @@
+package org.apache.ode.embed;
+
+import org.w3c.dom.Element;
+
+public interface MessageSender {
+
+    Element send(String recipient, String operation, Element elmt);
+}

Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/embed/ServerResources.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/embed/ServerResources.java?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/embed/ServerResources.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/embed/ServerResources.java Thu Sep 18 17:23:06 2008
@@ -3,6 +3,8 @@
 import org.apache.log4j.Logger;
 import org.apache.ode.EmbeddedServer;
 import org.apache.ode.Options;
+import org.apache.ode.embed.messaging.BindingContextImpl;
+import org.apache.ode.embed.messaging.MessageExchangeContextImpl;
 import org.apache.ode.bpel.dao.BpelDAOConnectionFactory;
 import org.apache.ode.bpel.engine.BpelServerImpl;
 import org.apache.ode.bpel.engine.CountLRUDehydrationPolicy;
@@ -70,7 +72,7 @@
 
         _server.setDaoConnectionFactory(_daoCF);
 //        _server.setEndpointReferenceContext(new EndpointReferenceContextImpl(this));
-//        _server.setMessageExchangeContext(new MessageExchangeContextImpl(this));
+        _server.setMessageExchangeContext(new MessageExchangeContextImpl(_options.getMessageSender()));
         _server.setBindingContext(new BindingContextImpl());
         _server.setScheduler(_scheduler);
         _server.setTransactionManager(_txMgr);

Copied: ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/BindingContextImpl.java (from r693540, ode/sandbox/simpel/src/main/java/org/apache/ode/embed/BindingContextImpl.java)
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/BindingContextImpl.java?p2=ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/BindingContextImpl.java&p1=ode/sandbox/simpel/src/main/java/org/apache/ode/embed/BindingContextImpl.java&r1=693540&r2=696869&rev=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/embed/BindingContextImpl.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/BindingContextImpl.java Thu Sep 18 17:23:06 2008
@@ -1,4 +1,4 @@
-package org.apache.ode.embed;
+package org.apache.ode.embed.messaging;
 
 import org.apache.ode.bpel.iapi.*;
 import org.apache.ode.il.epr.WSDL11Endpoint;

Added: ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java?rev=696869&view=auto
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java (added)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java Thu Sep 18 17:23:06 2008
@@ -0,0 +1,100 @@
+package org.apache.ode.embed.messaging;
+
+import org.apache.ode.bpel.iapi.*;
+import org.apache.ode.embed.MessageSender;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+import javax.wsdl.Operation;
+import javax.wsdl.Fault;
+import javax.xml.namespace.QName;
+import java.util.Set;
+import java.util.HashSet;
+
+public class MessageExchangeContextImpl implements MessageExchangeContext {
+
+    private static final Logger __log = Logger.getLogger(MessageExchangeContextImpl.class);
+
+    MessageSender _sender;
+
+    public MessageExchangeContextImpl(MessageSender sender) {
+        _sender  = sender;
+    }
+
+    public void invokePartnerUnreliable(PartnerRoleMessageExchange partnerMex) throws ContextException {
+        if (_sender == null) {
+            partnerMex.replyWithFailure(MessageExchange.FailureType.ABORTED,
+                    "No sender configured, can't send the message.", partnerMex.getRequest().getMessage());
+            __log.warn("No sender configured, can't send the message:\n"
+                    + DOMUtils.domToString(partnerMex.getRequest().getMessage()));
+        }
+
+        Operation invokedOp = partnerMex.getPortType().getOperation(partnerMex.getOperationName(), null, null);
+        try {
+            // We're placing ourselves in the doc/lit case for now, assuming a single part
+            Element message = partnerMex.getRequest().getMessage();
+            Element response = _sender.send(partnerMex.getPortType().getQName().getLocalPart(), invokedOp.getName(), 
+                    DOMUtils.getFirstChildElement(DOMUtils.getFirstChildElement(message)));
+
+            if (invokedOp.getOutput() != null) {
+                Document responseDoc = DOMUtils.newDocument();
+                Element messageElmt = responseDoc.createElement("message");
+                responseDoc.appendChild(messageElmt);
+                // Pretty hard to get the part name huh?
+                String partName = (String) invokedOp.getOutput().getMessage().getParts().keySet().iterator().next();
+                Element partElmt = responseDoc.createElement(partName);
+                messageElmt.appendChild(partElmt);
+                if (response != null) partElmt.appendChild(responseDoc.importNode(response, true));
+
+                Message responseMsg = partnerMex.createMessage(invokedOp.getOutput().getMessage().getQName());
+                responseMsg.setMessage(messageElmt);
+            } else {
+                partnerMex.replyOneWayOk();
+            }
+        } catch (RuntimeException re) {
+            __log.warn("The service called threw a runtime exception:\n"
+                    + DOMUtils.domToString(partnerMex.getRequest().getMessage()), re);
+            // Runtimes are considered failures
+            partnerMex.replyWithFailure(MessageExchange.FailureType.COMMUNICATION_ERROR,
+                    "The service called threw a runtime exception: " + re.toString(),
+                    partnerMex.getRequest().getMessage());
+        } catch (Exception e) {
+            __log.warn("The service called threw a checked exception:\n"
+                    + DOMUtils.domToString(partnerMex.getRequest().getMessage()), e);
+            // checked exceptions are considered faults
+            Fault fault = invokedOp.getFault(e.getClass().getName());
+            Message faultMsg = partnerMex.createMessage(fault.getMessage().getQName());
+            Document faultDoc = DOMUtils.newDocument();
+            Element faultElmt = faultDoc.createElement("exception");
+            faultElmt.setTextContent(e.getMessage());
+            faultMsg.setMessage(faultElmt);
+            partnerMex.replyWithFault(new QName(
+                    partnerMex.getPortType().getQName().getNamespaceURI(), fault.getName()), faultMsg);
+        }
+    }
+
+    public void invokePartnerReliable(PartnerRoleMessageExchange partnerRoleMessageExchange) throws ContextException {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void invokePartnerTransacted(PartnerRoleMessageExchange partnerRoleMessageExchange) throws ContextException {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void cancel(PartnerRoleMessageExchange partnerRoleMessageExchange) throws ContextException {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void onMyRoleMessageExchangeStateChanged(MyRoleMessageExchange myRoleMessageExchange) throws BpelEngineException {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public Set<InvocationStyle> getSupportedInvocationStyle(PartnerRoleChannel partnerRoleChannel, EndpointReference endpointReference) {
+        HashSet<InvocationStyle> styles = new HashSet<InvocationStyle>();
+        // TODO only unreliable for now, we might want to do transactional at a point
+        styles.add(InvocationStyle.UNRELIABLE);
+        return styles;
+    }
+}

Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java Thu Sep 18 17:23:06 2008
@@ -18,9 +18,11 @@
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.HashSet;
 
 /**
- * @author Matthieu Riou <mr...@apache.org>
+ * TODO foo = receive(...) expressions
+ * TODO e4x templates
  */
 public class OBuilder extends BaseCompiler {
     private static final Logger __log = Logger.getLogger(OBuilder.class);
@@ -32,6 +34,7 @@
     private HashMap<String,String> namespaces = new HashMap<String,String>();
     private HashMap<String, OPartnerLink> partnerLinks = new HashMap<String,OPartnerLink>();
     private HashMap<String,OScope.Variable> variables = new HashMap<String,OScope.Variable>();
+    private HashSet<String> typedVariables = new HashSet<String>();
     private boolean firstReceive = true;
 
     public OBuilder() {
@@ -133,7 +136,7 @@
 
     public SimpleActivity buildPickReceive(OPickReceive receive, OScope oscope, String partnerLink, String operation) {
         OPickReceive.OnMessage onMessage = new OPickReceive.OnMessage(_oprocess);
-        onMessage.partnerLink = buildPartnerLink(oscope, partnerLink, operation, true);
+        onMessage.partnerLink = buildPartnerLink(oscope, partnerLink, operation, true, true);
         onMessage.operation = onMessage.partnerLink.myRolePortType.getOperation(operation, null, null);
 
         if (firstReceive) {
@@ -148,6 +151,16 @@
         return new SimpleActivity<OPickReceive>(receive);
     }
 
+    public SimpleActivity buildInvoke(OInvoke invoke, OScope oscope, String partnerLink,
+                                      String operation, String incomingMsg) {
+
+        invoke.partnerLink = buildPartnerLink(oscope, partnerLink, operation, false, incomingMsg != null);
+        invoke.operation = invoke.partnerLink.partnerRolePortType.getOperation(operation, null, null);
+        if (incomingMsg != null) invoke.inputVar = resolveVariable(oscope, incomingMsg, operation, true);
+
+        return new SimpleActivity<OInvoke>(invoke);
+    }
+
     public StructuredActivity buildSequence(final OSequence seq, OScope oscope) {
         return new StructuredActivity<OSequence>(seq) {
             public void run(OActivity child) {
@@ -163,8 +176,9 @@
         OAssign.VariableRef vref = new OAssign.VariableRef(_oprocess);
         String lvar = lexpr.split("\\.")[0];
         vref.variable = resolveVariable(oscope, lvar);
-        vref.part = new OMessageVarType.Part(_oprocess, "payload",
-                new OElementVarType(_oprocess, new QName(_processNS, "simpelWrapper")));
+        ((OMessageVarType)vref.variable.type).parts.values().iterator();
+        // Don't worry, it's all type safe, therefore it's correct
+        vref.part = ((OMessageVarType)vref.variable.type).parts.values().iterator().next();
         ocopy.to = vref;
 
         rexpr.setLValue(lexpr);
@@ -182,13 +196,12 @@
                     " has no partnerLink/operation information.");
             oreply.partnerLink = oreceive.onMessages.get(0).partnerLink;
             oreply.operation = oreceive.onMessages.get(0).operation;
+            buildPartnerLink(oscope, oreply.partnerLink.name, oreply.operation.getName(), true, false);
         } else {
-            oreply.partnerLink = buildPartnerLink(oscope, partnerLink, operation, true);
+            oreply.partnerLink = buildPartnerLink(oscope, partnerLink, operation, true, false);
             oreply.operation = oreply.partnerLink.myRolePortType.getOperation(operation, null, null); 
         }
         // Adding partner role
-        buildPartnerLink(oscope, oreply.partnerLink.name, oreply.operation.getName(), false);
-        oreply.operation.setOutput(new SimPELOutput(new QName(_processNS, operation + "Response")));
         return new SimpleActivity<OReply>(oreply);
     }
 
@@ -204,6 +217,9 @@
         if (oact instanceof OPickReceive) {
             OPickReceive.OnMessage rec = ((OPickReceive)oact).onMessages.get(0);
             rec.variable = resolveVariable(oscope, varName, rec.operation.getName(), true);
+        } else if (oact instanceof OInvoke) {
+            OInvoke inv = (OInvoke)oact;
+            inv.outputVar = resolveVariable(oscope, varName, inv.operation.getName(), false);
         } else __log.warn("Can't set block parameter on activity " + oact);
     }
 
@@ -220,7 +236,7 @@
         return _oprocess;
     }
 
-    private OPartnerLink buildPartnerLink(OScope oscope, String name, String operation, boolean myRole) {
+    private OPartnerLink buildPartnerLink(OScope oscope, String name, String operation, boolean myRole, Boolean input) {
         // TODO Handle partnerlinks declared with an associated endpoint
         OPartnerLink resolved = partnerLinks.get(name);
         // TODO this will not work in case of variable name conflicts in different scopes
@@ -232,19 +248,34 @@
             _oprocess.allPartnerLinks.add(resolved);
             oscope.partnerLinks.put(name, resolved);
         }
+        PortType pt;
         if (myRole) {
-            PortType pt = resolved.myRolePortType;
-            if (pt == null) pt = resolved.myRolePortType = new SimPELPortType();
-            SimPELOperation op = new SimPELOperation(operation);
-            op.setInput(new SimPELInput(new QName(_processNS, operation + "Request")));
-            pt.addOperation(op);
+            pt = resolved.myRolePortType;
+            if (pt == null) {
+                pt = resolved.myRolePortType = new SimPELPortType();
+                pt.setQName(new QName(SIMPEL_NS, name));
+            }
         } else {
-            PortType pt = resolved.partnerRolePortType;
-            if (pt == null) pt = resolved.partnerRolePortType = new SimPELPortType();
-            SimPELOperation op = new SimPELOperation(operation);
-            op.setOutput(new SimPELOutput(new QName(_processNS, operation + "Response")));
+            pt = resolved.partnerRolePortType;
+            if (pt == null) {
+                pt = resolved.partnerRolePortType = new SimPELPortType();
+                pt.setQName(new QName(SIMPEL_NS, name));
+            }
+        }
+
+        SimPELOperation op = (SimPELOperation) pt.getOperation(operation, null, null);
+        if (op == null) {
+            op = new SimPELOperation(operation);
             pt.addOperation(op);
         }
+        // Java's three-way boolean
+        if (input != null) {
+            if (input) {
+                op.setInput(new SimPELInput(new QName(_processNS, operation + "Request")));
+            } else {
+                op.setOutput(new SimPELOutput(new QName(_processNS, operation + "Response")));
+            }
+        }
         return resolved;
     }
 
@@ -268,12 +299,13 @@
 
         // If an operation name has been provided with which to associate this variable, we
         // use a better naming for the part element.
-        if (operation != null) {
+        if (operation != null && !typedVariables.contains(name)) {
             String elmtName = operation + (request ? "Request" : "Response");
             LinkedList<OMessageVarType.Part> parts = new LinkedList<OMessageVarType.Part>();
             parts.add(new OMessageVarType.Part(_oprocess, elmtName,
                     new OElementVarType(_oprocess, new QName(_processNS, elmtName))));
-            resolved.type = new OMessageVarType(_oprocess, new QName(_processNS, operation), parts); 
+            resolved.type = new OMessageVarType(_oprocess, new QName(_processNS, operation), parts);
+            typedVariables.add(name);
         }
         return resolved;
     }

Modified: ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/SimPELRuntimeTest.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/SimPELRuntimeTest.java?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/SimPELRuntimeTest.java (original)
+++ ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/SimPELRuntimeTest.java Thu Sep 18 17:23:06 2008
@@ -2,6 +2,7 @@
 
 import junit.framework.TestCase;
 import org.apache.ode.EmbeddedServer;
+import org.apache.ode.embed.MessageSender;
 import org.apache.ode.utils.DOMUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -21,29 +22,7 @@
             "   }\n" +
             "}";
 
-    private static final String XML_DATA_MANIPULATION =
-            "process XmlData {\n" +
-            "    receive(dataPl, dataOp) { |msgIn|\n" +
-            "        friendInfo = <friend></friend>;\n" + // TODO check template style E4X
-            "        friendInfo.name = msgIn.person.firstName + \" \" + msgIn.person.lastName;\n" +
-            "        friendInfo.phone = msgIn.person.phone;\n" +
-            "        reply(friendInfo);\n" +
-            "    }\n" +
-            "}";
-
-    private static final String SIMPLE_IF =
-            "process SimpleIf {\n" +
-            "    receive(ifPl, ifOp) { |quantity|\n" +
-            "        if (quantity > 20) {\n" +
-            "            status = 0; \n" +
-            "        } else { \n" +
-            "            status = 1; \n" +
-            "        }\n" +
-            "        reply(status);\n" +
-            "    }\n" +
-            "}";
-
-    public void testHelloWorldComplete() throws Exception {
+    public void testHelloWorld() throws Exception {
         EmbeddedServer server = new EmbeddedServer();
         server.start();
         server.deploy(HELLO_WORLD);
@@ -56,6 +35,16 @@
         assertTrue(DOMUtils.domToString(result).indexOf("Hello World") > 0);
     }
 
+    private static final String XML_DATA_MANIPULATION =
+            "process XmlData {\n" +
+            "    receive(dataPl, dataOp) { |msgIn|\n" +
+            "        friendInfo = <friend></friend>;\n" +
+            "        friendInfo.name = msgIn.person.firstName + \" \" + msgIn.person.lastName;\n" +
+            "        friendInfo.phone = msgIn.person.phone;\n" +
+            "        reply(friendInfo);\n" +
+            "    }\n" +
+            "}";
+
     public void testXmlData() throws Exception {
         EmbeddedServer server = new  EmbeddedServer();
         server.start();
@@ -78,6 +67,18 @@
         assertEquals("John Doe", DOMUtils.findChildByName(result, new QName(null, "name")).getTextContent());
     }
 
+    private static final String SIMPLE_IF =
+            "process SimpleIf {\n" +
+            "    receive(ifPl, ifOp) { |quantity|\n" +
+            "        if (quantity > 20) {\n" +
+            "            status = 0; \n" +
+            "        } else { \n" +
+            "            status = 1; \n" +
+            "        }\n" +
+            "        reply(status);\n" +
+            "    }\n" +
+            "}";
+
     public void testSimpleIf() throws Exception {
         EmbeddedServer server = new  EmbeddedServer();
         server.start();
@@ -95,4 +96,35 @@
         assertNotNull(result);
         assertEquals(1.0f, Float.parseFloat(result.getTextContent()));
     }
+
+    public static final String INVOKE_ONE_WAY =
+            "process InvokeOneWay {\n" +
+            "    receive(iowPl, iowOp) { |status|\n" +
+            "        invoke(partnerPl, partnerOp, status);\n" +
+            "        status = \"ok\";\n" +
+            "        reply(status);\n" +
+            "    }\n" +
+            "}";
+
+    public void testInvokeOneWay() throws Exception {
+        final Boolean[] received = new Boolean[] { false };
+
+        EmbeddedServer server = new  EmbeddedServer();
+        server.options.setMessageSender(new MessageSender() {
+            public Element send(String recipient, String operation, Element elmt) {
+                received[0] = true;
+                return null;
+            }
+        });
+        server.start();
+        server.deploy(INVOKE_ONE_WAY);
+
+        Element wrapper = DOMUtils.stringToDOM(
+                "<xd:iowOpRequest xmlns:xd=\"http://ode.apache.org/simpel/1.0/definition/InvokeOneWay\">ok?</xd:iowOpRequest>");
+        Element result = server.sendMessage("iowPl", "iowOp", wrapper);
+        assertNotNull(result);
+        System.out.println(DOMUtils.domToString(result));
+        assertEquals("ok", result.getTextContent());
+        assertTrue(received[0]);
+    }
 }

Modified: ode/sandbox/simpel/src/test/resources/compile-tests-ok.simpel
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/resources/compile-tests-ok.simpel?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/resources/compile-tests-ok.simpel (original)
+++ ode/sandbox/simpel/src/test/resources/compile-tests-ok.simpel Thu Sep 18 17:23:06 2008
@@ -138,6 +138,19 @@
 }
 
 #=============================================================
+# Block invoke
+#
+
+process HelloWorld {
+  receive(my_pl, hello_op) { |msg_in|
+    invoke(other_pl, other_op, msg_in) { |resp|
+      if (resp != "Hello ") throw(WrongMsg);
+    }
+    reply(msg_in);
+  }
+}
+
+#=============================================================
 # Forced Hello World (if and throw)
 #
 

Modified: ode/sandbox/simpel/src/test/resources/loan-approval.simpel
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/resources/loan-approval.simpel?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/resources/loan-approval.simpel (original)
+++ ode/sandbox/simpel/src/test/resources/loan-approval.simpel Thu Sep 18 17:23:06 2008
@@ -11,9 +11,10 @@
       signal(receive-to-approval, [$request.amount >= 10000]);
     } and {
       join(receive-to-assess);
-      risk = invoke(assessor, check);
-      signal(assess-to-setMessage, [$risk.level = 'low']);
-      signal(assess-to-approval, [$risk.level != 'low']);
+      invoke(assessor, check) { |risk|
+        signal(assess-to-setMessage, [$risk.level = 'low']);
+        signal(assess-to-approval, [$risk.level != 'low']);
+      }
     } and {
       join(assess-to-setMessage);
       approval.accept = "yes";

Modified: ode/sandbox/simpel/src/test/resources/task-manager.simpel
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/resources/task-manager.simpel?rev=696869&r1=696868&r2=696869&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/resources/task-manager.simpel (original)
+++ ode/sandbox/simpel/src/test/resources/task-manager.simpel Thu Sep 18 17:23:06 2008
@@ -58,7 +58,7 @@
   createRequest.createRequest = [bpws:doXslTransform("actions.xsl", $createRequest.createRequest,
       "metadata", $createTaskRequest.root/b4p:taskMetaData)];
 
-  createResponse = invoke(TMSPartnerLink, create, createRequest);
+  invoke(TMSPartnerLink, create, createRequest);
 
   if (createTaskRequest.root.b4p::taskMetaData.b4p::isChainedBefore == "true") {
     nextTaskReady.root = <b4p:chainedExecution><b4p:previousTaskId/><b4p:nextTaskId/>
@@ -90,7 +90,7 @@
           oc.tms::participantToken = completeTaskRequest.root.b4p::participantToken;
         }
 
-        setOutputAndCompleteRespons = invoke(TMSPartnerLink, setOutputAndComplete, setOutputAndCompleteRequest);
+        invoke(TMSPartnerLink, setOutputAndComplete, setOutputAndCompleteRequest);
 
         notifyTaskCompletionRequest.root = <b4p:notifyTaskCompletionRequest><b4p:taskMetaData>
             <b4p:taskId/><b4p:processId/><b4p:userProcessEndpoint/><b4p:userProcessNamespaceURI/>
@@ -107,15 +107,15 @@
         }
         notifyTaskCompletionRequest.root.b4p::taskOutput = completeTaskRequest.root.b4p::taskOutput;
 
-        notifyTaskCompletionResponse = invoke(userProcessPartnerLink, notifyTaskCompletion, notifyTaskCompletionRequest);
-
-        if (notifyTaskCompletionResponse.root.b4p::isChainedAfter == true) {
-          receive(nextTaskManagerPartnerLink, nextTaskReady) { |nextTaskReady|
-            completeTaskResponse.root = <b4p:response><b4p:taskMetaData><b4p:nextTaskId/>
-                <b4p:nextTaskURL/></b4p:taskMetaData><b4p:status>OK</b4p:status></b4p:response>;
-            with(ct: completeTaskResponse.root.b4p::taskMetaData) {
-              ct.b4p::nextTaskId = nextTaskReady.root.b4p::nextTaskId;
-              ct.b4p::nextTaskURL = nextTaskReady.root.b4p::nextTaskURL;
+        invoke(userProcessPartnerLink, notifyTaskCompletion, notifyTaskCompletionRequest) { |notifyTaskCompletionResponse|
+          if (notifyTaskCompletionResponse.root.b4p::isChainedAfter == true) {
+            receive(nextTaskManagerPartnerLink, nextTaskReady) { |nextTaskReady|
+              completeTaskResponse.root = <b4p:response><b4p:taskMetaData><b4p:nextTaskId/>
+                  <b4p:nextTaskURL/></b4p:taskMetaData><b4p:status>OK</b4p:status></b4p:response>;
+              with(ct: completeTaskResponse.root.b4p::taskMetaData) {
+                ct.b4p::nextTaskId = nextTaskReady.root.b4p::nextTaskId;
+                ct.b4p::nextTaskURL = nextTaskReady.root.b4p::nextTaskURL;
+              }
             }
           }
         }
@@ -133,7 +133,7 @@
           rr.tms::roleOwner = etr.b4p::roleOwner;
         }
 
-        reassignRequest = invoke(TMSPartnerLink, reassign, reassignRequest);
+        invoke(TMSPartnerLink, reassign, reassignRequest);
 
         taskClaimed = false;
         escalateTaskResponse.root = <b4p:escalateTaskResponse><b4p:status>OK</b4p:status></b4p:escalateTaskResponse>;
@@ -164,7 +164,7 @@
           rr.tms::participantToken = ct.b4p::participantToken;
         }
 
-        reassignResponse = invoke(TMSPartnerLink, reassign, reassignRequest);
+        invoke(TMSPartnerLink, reassign, reassignRequest);
         taskClaimed = true;
         claimTaskResponse.root = <b4p:claimTaskResponse><b4p:status>OK</b4p:status></b4p:claimTaskResponse>;
         reply(claimTaskResponse);
@@ -184,7 +184,7 @@
           rr.tms::participantToken = rt.b4p::participantToken;
         }
 
-        reassignResponse = invoke(TMSPartnerLink, reassign, reassignRequest);
+        invoke(TMSPartnerLink, reassign, reassignRequest);
         taskClaimed = false;
         revokeTaskResponse.root = <b4p:revokeTaskResponse><b4p:status>OK</b4p:status></b4p:revokeTaskResponse>;
         reply(revokeTaskResponse);