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/24 02:46:56 UTC
svn commit: r698407 - in /ode/sandbox/simpel/src:
main/antlr/org/apache/ode/simpel/antlr/ main/java/org/apache/ode/simpel/
main/java/org/apache/ode/simpel/expr/
main/java/org/apache/ode/simpel/omodel/ test/java/org/apache/ode/simpel/
test/resources/
Author: mriou
Date: Tue Sep 23 17:46:55 2008
New Revision: 698407
URL: http://svn.apache.org/viewvc?rev=698407&view=rev
Log:
Javascript code declared before the process definition defines a global environment. Allows the reuse of JS functions and variable definitions in the process using assignment. Pretty sweet if you ask me.
Modified:
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/simpel/SimPELCompiler.java
ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.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/auction.simpel
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/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=698407&r1=698406&r2=698407&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 Tue Sep 23 17:46:55 2008
@@ -187,16 +187,16 @@
funct : 'function'^ f=ID '(' ID? (','! ID)* ')' js_block;
// Expressions
-expr : s_expr | EXT_EXPR | funct_call;
+expr : s_expr | EXT_EXPR;
funct_call
- : p+=ID '(' p+=ID* ')' -> ^(CALL ID+);
+ : fn=ID '(' (e+=expr)? (',' e+=expr)* ')' -> ^(CALL ID $e*);
// TODO add && || !
s_expr : condExpr;
condExpr: aexpr ( ('==' ^|'!=' ^|'<' ^|'>' ^|'<=' ^|'>=' ^) aexpr )?;
aexpr : mexpr (('+'|'-') ^ mexpr)*;
mexpr : atom (('*'|'/') ^ atom)* | STRING;
-atom : path_expr | INT | '(' s_expr ')' -> s_expr;
+atom : path_expr | INT | '(' s_expr ')' -> s_expr | funct_call;
path_expr
: pelmt+=ns_id ('.' pelmt+=ns_id)* -> ^(PATH $pelmt);
@@ -228,7 +228,7 @@
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\');
SL_COMMENTS
- : ('#'|'//') .* CR { $channel = HIDDEN; };
+ : '//' .* CR { $channel = HIDDEN; };
CR : ('\r' | '\n' )+ { $channel = HIDDEN; };
WS : ( ' ' | '\t' )+ { skip(); };
fragment DIGIT
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=698407&r1=698406&r2=698407&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 Tue Sep 23 17:46:55 2008
@@ -109,7 +109,6 @@
: ^(SEQUENCE ID+
{ OBuilder.StructuredActivity seq = builder.build(OSequence.class, $BPELScope::oscope, $Parent[-1]::activity);
$Parent::activity = seq;
- //builder.setBlockParam($BPELScope::oscope, (OActivity) $Parent[-1]::activity.getOActivity(), $ID.text);
builder.setBlockParam($BPELScope::oscope, (OSequence)seq.getOActivity(), $ID.text);
}
proc_stmt+);
@@ -265,10 +264,10 @@
: XML_COMMENT | XML_CDATA | XML_PI;
// Expressions
-expr : s_expr | EXT_EXPR | funct_call;
+expr : s_expr | EXT_EXPR;
funct_call
- : ^(CALL ID*);
+ : ^(CALL ID expr*);
path_expr
: ^(PATH ids=(ns_id*)) {
builder.addExprVariable($BPELScope::oscope, $ExprContext::expr, deepText($ids));
@@ -285,4 +284,4 @@
| ^('-' s_expr s_expr)
| ^('*' s_expr s_expr)
| ^('/' s_expr s_expr)
- | path_expr | INT | STRING;
+ | path_expr | INT | STRING | funct_call;
Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/SimPELCompiler.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/SimPELCompiler.java?rev=698407&r1=698406&r2=698407&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/SimPELCompiler.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/SimPELCompiler.java Tue Sep 23 17:46:55 2008
@@ -11,13 +11,19 @@
import org.apache.ode.simpel.antlr.SimPELParser;
import org.apache.ode.simpel.antlr.SimPELWalker;
import org.apache.ode.simpel.util.DefaultErrorListener;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.serialize.ScriptableOutputStream;
import uk.co.badgersinfoil.e4x.antlr.*;
import java.io.StringReader;
import java.io.IOException;
+import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
public class SimPELCompiler {
@@ -31,10 +37,49 @@
this.el = el;
}
- public OProcess compileProcess(String process) {
+ public OProcess compileProcess(String processDoc) {
+ // Isolating the process definition from the header containing global state definition (Javascript
+ // functions and shared objects)
+ Pattern p = Pattern.compile("process [a-zA-Z_]*", Pattern.MULTILINE);
+ Matcher m = p.matcher(processDoc);
+ if (!m.find()) throw new CompilationException("Couldn't find any process declaration.");
+ String header = processDoc.substring(0, m.start());
+ String processDef = processDoc.substring(m.start(), processDoc.length());
+
+ OProcess model = buildModel(processDef);
+ if (header.trim().length() > 0)
+ model.globalState = buildGlobalState(header);
+ return model;
+ }
+
+ private byte[] buildGlobalState(String header) {
+ Context cx = Context.enter();
+ cx.setOptimizationLevel(-1);
+ Scriptable sharedScope = cx.initStandardObjects();
+
+ Scriptable newScope = cx.newObject(sharedScope);
+ newScope.setPrototype(sharedScope);
+ newScope.setParentScope(null);
+
+ cx.evaluateString(newScope, header, "<cmd>", 1, null);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ScriptableOutputStream out = null;
+ try {
+ out = new ScriptableOutputStream(baos, sharedScope);
+ out.writeObject(newScope);
+ out.close();
+ } catch (IOException e) {
+ throw new CompilationException("Error when interpreting definitions in the process header.", e);
+ }
+
+ return baos.toByteArray();
+ }
+
+ private OProcess buildModel(String processDef) {
ANTLRReaderStream charstream = null;
try {
- charstream = new ANTLRReaderStream(new StringReader(process));
+ charstream = new ANTLRReaderStream(new StringReader(processDef));
} catch (IOException e) {
throw new CompilationException("Unable to read process string.", e);
}
Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java?rev=698407&r1=698406&r2=698407&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java Tue Sep 23 17:46:55 2008
@@ -11,6 +11,7 @@
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Delegator;
import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.serialize.ScriptableInputStream;
import org.mozilla.javascript.xmlimpl.XMLLibImpl;
import org.mozilla.javascript.xml.XMLLib;
import org.mozilla.javascript.xml.XMLObject;
@@ -20,11 +21,17 @@
import javax.xml.namespace.QName;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayInputStream;
/**
* @author Matthieu Riou <mr...@apache.org>
*/
public class E4XExprRuntime implements ExpressionLanguageRuntime {
+
+ private static ConcurrentHashMap<Integer, Scriptable> globalStateCache = new ConcurrentHashMap<Integer, Scriptable>();
+
public void initialize(Map map) throws ConfigurationException {
}
@@ -32,13 +39,13 @@
return null;
}
- public boolean evaluateAsBoolean(OExpression oExpression, EvaluationContext evaluationContext) throws FaultException {
+ public boolean evaluateAsBoolean(OExpression oexpr, EvaluationContext evaluationContext) throws FaultException {
// TODO context caching
Context cx = ContextFactory.getGlobal().enterContext();
- ODEDelegator scope = new ODEDelegator(cx.initStandardObjects(), evaluationContext, (SimPELExpr)oExpression, cx);
+ ODEDelegator scope = new ODEDelegator(cx.initStandardObjects(), evaluationContext, (SimPELExpr)oexpr, cx);
// First evaluating the assignment
- SimPELExpr expr = (SimPELExpr) oExpression;
+ SimPELExpr expr = (SimPELExpr) oexpr;
Object res = cx.evaluateString(scope, expr.getExpr(), "<expr>", 0, null);
if (res instanceof Boolean) return (Boolean)res;
else throw new FaultException(new QName("e4xEvalFailure"), "Failed to evaluate "
@@ -52,7 +59,27 @@
public List evaluate(OExpression oexpr, EvaluationContext evaluationContext) throws FaultException {
// TODO context caching
Context cx = ContextFactory.getGlobal().enterContext();
- ODEDelegator scope = new ODEDelegator(cx.initStandardObjects(), evaluationContext, (SimPELExpr)oexpr, cx);
+ cx.setOptimizationLevel(-1);
+
+ Scriptable parentScope;
+ if (oexpr.getOwner().globalState != null) {
+ parentScope = globalStateCache.get(oexpr.getOwner().getId());
+ if (parentScope == null) {
+ Scriptable sharedScope = cx.initStandardObjects();
+ try {
+ ObjectInputStream in = new ScriptableInputStream(new ByteArrayInputStream(oexpr.getOwner().globalState), sharedScope);
+ parentScope = (Scriptable) in.readObject();
+ in.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ globalStateCache.put(oexpr.getOwner().getId(), parentScope);
+ }
+ } else {
+ parentScope = cx.initStandardObjects();
+ }
+
+ ODEDelegator scope = new ODEDelegator(parentScope, evaluationContext, (SimPELExpr)oexpr, cx);
// First evaluating the assignment
SimPELExpr expr = (SimPELExpr) oexpr;
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=698407&r1=698406&r2=698407&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 Tue Sep 23 17:46:55 2008
@@ -207,12 +207,11 @@
public void setBlockParam(OScope oscope, OSequence blockActivity, String varName) {
// The AST for block activities is something like:
// (SEQUENCE (activity) (SEQUENCE varIds otherActivities))
- // The parent here is the first sequence so we just set the varIds on its first child activity
+ // The blockActivity here is the second sequence so we just set the varIds on the previous activity
if (blockActivity == null || !(blockActivity instanceof OSequence)) {
__log.warn("Can't set block parameter with block parent activity " + blockActivity);
return;
}
-// OActivity oact = ((OSequence)blockActivity).sequence.get(0);
List<OActivity> parentList = ((OSequence)blockActivity.getParent()).sequence;
OActivity oact = parentList.get(parentList.indexOf(blockActivity) - 1);
if (oact instanceof OPickReceive) {
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=698407&r1=698406&r2=698407&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 Tue Sep 23 17:46:55 2008
@@ -8,8 +8,18 @@
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ContextFactory;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.serialize.ScriptableOutputStream;
+import org.mozilla.javascript.serialize.ScriptableInputStream;
import javax.xml.namespace.QName;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayInputStream;
/**
* @author Matthieu Riou <mr...@apache.org>
@@ -113,7 +123,7 @@
public void testInvokeOneWay() throws Exception {
final Boolean[] received = new Boolean[] { false };
- EmbeddedServer server = new EmbeddedServer();
+ EmbeddedServer server = new EmbeddedServer();
server.options.setMessageSender(new MessageSender() {
public Node send(String recipient, String operation, Node message) {
if (recipient.equals("partnerPl") && operation.equals("partnerOp")
@@ -172,4 +182,42 @@
System.out.println(DOMUtils.domToString(result));
assertEquals("10", result.getTextContent());
}
+
+ private static final String JS_GLOBAL_STATE =
+ "var append = \" Yeeha!\"; \n" +
+ "function helloPrepend(p) { return \"Hello \" + p; }; \n" +
+ "\n" +
+ "process JsGlobalState {\n" +
+ " receive(myPl, helloOp) { |msgIn|\n" +
+ " msgOut = helloPrepend(msgIn) + append;\n" +
+ " reply(msgOut);\n" +
+ " }\n" +
+ "}";
+
+ public void testJSState() throws Exception {
+ EmbeddedServer server = new EmbeddedServer();
+ server.start();
+ server.deploy(JS_GLOBAL_STATE);
+
+ Document doc = DOMUtils.newDocument();
+ Element wrapper = doc.createElementNS("http://ode.apache.org/simpel/1.0/definition/JsGlobalState", "helloOpRequest");
+ wrapper.setTextContent("World.");
+
+ Element result = server.sendMessage("myPl", "helloOp", wrapper);
+ System.out.println(":: " + DOMUtils.domToString(result));
+ assertTrue(DOMUtils.domToString(result).indexOf("Hello World. Yeeha!") > 0);
+ }
+
+ private static final String SIMPLE_CORRELATION =
+ "var append = \" Yeeha!\"; \n" +
+ "function getCounterId(msg) { return msg.counterId; }; \n" +
+ "\n" +
+ "process SimpleCorrelation {\n" +
+ " var cid unique; \n" +
+ " receive(myPl, helloOp) { |msgIn|\n" +
+ " msgOut = helloPrepend(msgIn) + append;\n" +
+ " reply(msgOut);\n" +
+ " }\n" +
+ "}";
+
}
Modified: ode/sandbox/simpel/src/test/resources/auction.simpel
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/resources/auction.simpel?rev=698407&r1=698406&r2=698407&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/resources/auction.simpel (original)
+++ ode/sandbox/simpel/src/test/resources/auction.simpel Tue Sep 23 17:46:55 2008
@@ -1,7 +1,7 @@
-namespace sref=" http://docs.oasis-open.org/wsbpel/2.0/serviceref";
-namespace addr="http://example.com/addressing";
+var sref = new Namespace("http://docs.oasis-open.org/wsbpel/2.0/serviceref");
+var addr = new Namespace("http://example.com/addressing");
-# Correlation functions
+// Correlation functions
function auctionIdFromAnswer(answer) {
answer.auctionId;
}
@@ -12,13 +12,13 @@
seller.auctionId;
}
-# Auction process as defined in chapter 15.4 of the BPEL 2.0 specification
+// Auction as defined in chapter 15.4 of the BPEL 2.0 specification
process Auction {
partnerLink buyerOrSeller, auctionRegistrar, seller;
var auctionId unique, buyerData, sellerData;
- # The original BPEL spec example for the auctions process uses a join pattern which
- # we chose to not support in SimPEL. This is equivalent.
+ // The original BPEL spec example for the auctions process uses a join pattern which
+ // we chose to not support in SimPEL. This is equivalent.
receive(buyerOrSeller, submit) { |startData|
if (startData.buyer) {
buyerData = startData;
@@ -31,7 +31,7 @@
}
}
- # The endpoint hardcoded in the process is kind of evil but heck, that's the example.
+ // The endpoint hardcoded in the process is kind of evil but heck, that's the example.
auctionRegistrar = <sref:service-ref>
<addr:EndpointReference>
<addr:Address>http://example.com/auction/RegistrationService/</addr:Address>
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=698407&r1=698406&r2=698407&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/resources/compile-tests-ok.simpel (original)
+++ ode/sandbox/simpel/src/test/resources/compile-tests-ok.simpel Tue Sep 23 17:46:55 2008
@@ -183,8 +183,8 @@
# Namespaces
#
-namespace pns = "ns:process";
-namespace fns = "ns:fault";
+var pns = new Namespace("ns:process");
+var fns = new Namespace("ns:fault");
process pns::NamespacesProcess {
msg_in = receive(my_pl, start_op);
@@ -225,7 +225,7 @@
process SimpleCorrel {
orderMsg = receive(my_pl, start_op);
- # The correlation implies orderId(incoming_msg) == orderId(init_msg)
+ // The correlation implies orderId(incoming_msg) == orderId(init_msg)
var oid unique;
oid = orderId(orderMsg);
receive(my_pl, corr_op, {orderId: oid});
@@ -251,8 +251,8 @@
process DoubleCorrel {
orderMsg = receive(my_pl, start_op);
- # The correlation implies orderIdFromShippment(incoming_msg) == orderIdFromOrder(order_msg)
- # and shipIdFromShippment(incoming_msg) == shipIdFromOrder(order_msg),
+ // The correlation implies orderIdFromShippment(incoming_msg) == orderIdFromOrder(order_msg)
+ // and shipIdFromShippment(incoming_msg) == shipIdFromOrder(order_msg),
var oid unique, shipId unique;
oid = orderIdFromOrder(order_msg);
shipId = shipIdFromOrder(order_msg);
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=698407&r1=698406&r2=698407&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/resources/loan-approval.simpel (original)
+++ ode/sandbox/simpel/src/test/resources/loan-approval.simpel Tue Sep 23 17:46:55 2008
@@ -1,7 +1,7 @@
-namespace lns = "http://example.com/loan-approval/wsdl/";
-namespace pns = "http://example.com/loan-approval";
+var lns = new Namespace("http://example.com/loan-approval/wsdl/");
+var pns = new Namespace("http://example.com/loan-approval");
-# Loan approval process as defined in chapter 15.3 of the BPEL 2.0 specification
+// Loan approval as defined in chapter 15.3 of the BPEL 2.0 specification
process pns::LoanApproval {
partnerLink customer, assessor, approver;
try {
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=698407&r1=698406&r2=698407&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/resources/task-manager.simpel (original)
+++ ode/sandbox/simpel/src/test/resources/task-manager.simpel Tue Sep 23 17:46:55 2008
@@ -1,5 +1,5 @@
-namespace b4p = "http://tempo.intalio.org/workflow/ib4p_20051115";
-namespace tms = "http://tempo.intalio.org/workflow/TaskManagementServices-20051109/";
+var b4p = new Namespace("http://tempo.intalio.org/workflow/ib4p_20051115");
+var tms = new Namespace("http://tempo.intalio.org/workflow/TaskManagementServices-20051109/");
function taskIdFromB4P(c) {
return c.b4p::taskMetaData.b4p::taskId;