This is an automated email from the ASF dual-hosted git repository.
egonzalez pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git
The following commit(s) were added to refs/heads/main by this push:
new 9cdc21afcc [incubator-kie-issues-1136] Add script onEntry, on Exit for
java (#3490)
9cdc21afcc is described below
commit 9cdc21afccd044669dfa8a7aedfeef87ce8553fc
Author: Enrique <[email protected]>
AuthorDate: Mon May 6 14:54:25 2024 +0200
[incubator-kie-issues-1136] Add script onEntry, on Exit for java (#3490)
* [incubator-kie-issues-1136] Add script onEntry, on Exit for java
---
.../java/org/jbpm/bpmn2/xml/GlobalHandler.java | 21 +++
.../compiler/canonical/AbstractNodeVisitor.java | 43 +++++
.../jbpm/compiler/canonical/AbstractVisitor.java | 3 +-
.../process/builder/action/ActionCompiler.java | 36 +++++
.../builder/action/ActionCompilerRegistry.java | 62 ++++++++
.../process/builder/action/JavaActionCompiler.java | 82 ++++++++++
.../process/builder/action/MVELActionCompiler.java | 50 ++++++
.../org.jbpm.process.builder.action.ActionCompiler | 2 +
.../core/factory/AbstractCompositeNodeFactory.java | 1 +
.../ruleflow/core/factory/ExtendedNodeFactory.java | 26 ---
.../jbpm/ruleflow/core/factory/NodeFactory.java | 28 ++++
.../core/validation/RuleFlowProcessValidator.java | 23 ---
.../jbpm/workflow/core/impl/ExtendedNodeImpl.java | 4 +
.../validation/RuleFlowProcessValidatorTest.java | 35 ----
.../src/test/java/org/jbpm/bpmn2/ActivityTest.java | 58 +++----
.../test/utils/EventTrackerProcessListener.java | 50 ++++++
.../org/jbpm/test/utils/ProcessTestHelper.java | 9 ++
.../BPMN2-SubProcessWithEntryExitScripts.bpmn2 | 177 +++++++++++++++++++++
18 files changed, 593 insertions(+), 117 deletions(-)
diff --git
a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/GlobalHandler.java
b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/GlobalHandler.java
index b91a7b931d..6f66de03e5 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/GlobalHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/GlobalHandler.java
@@ -18,13 +18,18 @@
*/
package org.jbpm.bpmn2.xml;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import org.jbpm.compiler.xml.Handler;
import org.jbpm.compiler.xml.Parser;
import org.jbpm.compiler.xml.core.BaseAbstractHandler;
+import org.jbpm.process.core.context.variable.Variable;
+import org.jbpm.process.core.context.variable.VariableScope;
+import org.jbpm.process.core.datatype.DataTypeResolver;
import org.jbpm.workflow.core.impl.WorkflowProcessImpl;
import org.kie.api.definition.process.Process;
import org.xml.sax.Attributes;
@@ -53,6 +58,7 @@ public class GlobalHandler extends BaseAbstractHandler
implements Handler {
final String identifier = attrs.getValue("identifier");
final String type = attrs.getValue("type");
+ process.addImports(Collections.singleton(type));
emptyAttributeCheck(localName, "identifier", identifier, parser);
emptyAttributeCheck(localName, "type", type, parser);
@@ -63,6 +69,21 @@ public class GlobalHandler extends BaseAbstractHandler
implements Handler {
}
map.put(identifier, type);
+ VariableScope variableScope = (VariableScope)
process.getDefaultContext(VariableScope.VARIABLE_SCOPE);
+ List<Variable> variables = variableScope.getVariables();
+ Variable variable = new Variable();
+ variable.setId(identifier);
+ variable.setType(DataTypeResolver.fromType(type,
parser.getClassLoader()));
+ // if name is given use it as variable name instead of id
+ if (identifier != null && identifier.length() > 0) {
+ variable.setName(identifier);
+ variable.setMetaData(identifier, variable.getName());
+ } else {
+ variable.setName(identifier);
+ }
+ variable.setMetaData(identifier, variable.getName());
+ variables.add(variable);
+
return null;
}
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractNodeVisitor.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractNodeVisitor.java
index c5cffb2e7b..e3429dcdbb 100644
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractNodeVisitor.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractNodeVisitor.java
@@ -20,8 +20,11 @@ package org.jbpm.compiler.canonical;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
+import org.jbpm.process.builder.action.ActionCompilerRegistry;
import org.jbpm.process.core.ContextContainer;
import org.jbpm.process.core.context.variable.Mappable;
import org.jbpm.process.core.context.variable.Variable;
@@ -33,6 +36,8 @@ import org.jbpm.ruleflow.core.factory.MappableNodeFactory;
import org.jbpm.workflow.core.impl.ConnectionImpl;
import org.jbpm.workflow.core.impl.DataAssociation;
import org.jbpm.workflow.core.impl.DataDefinition;
+import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
+import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
import org.jbpm.workflow.core.node.Assignment;
import org.jbpm.workflow.core.node.HumanTaskNode;
import org.jbpm.workflow.core.node.StartNode;
@@ -69,6 +74,7 @@ import static
org.jbpm.ruleflow.core.Metadata.CUSTOM_AUTO_START;
import static org.jbpm.ruleflow.core.Metadata.HIDDEN;
import static org.jbpm.ruleflow.core.factory.NodeFactory.METHOD_DONE;
import static org.jbpm.ruleflow.core.factory.NodeFactory.METHOD_NAME;
+import static org.kie.kogito.internal.utils.ConversionUtils.sanitizeString;
public abstract class AbstractNodeVisitor<T extends Node> extends
AbstractVisitor {
@@ -79,6 +85,43 @@ public abstract class AbstractNodeVisitor<T extends Node>
extends AbstractVisito
if (isAdHocNode(node) && !(node instanceof HumanTaskNode)) {
metadata.addSignal(node.getName(), null);
}
+ if (isExtendedNode(node)) {
+ ExtendedNodeImpl extendedNodeImpl = (ExtendedNodeImpl) node;
+ addScript(extendedNodeImpl, body, ON_ACTION_SCRIPT_METHOD,
ExtendedNodeImpl.EVENT_NODE_ENTER);
+ addScript(extendedNodeImpl, body, ON_ACTION_SCRIPT_METHOD,
ExtendedNodeImpl.EVENT_NODE_EXIT);
+ }
+ }
+
+ private void addScript(ExtendedNodeImpl extendedNodeImpl, BlockStmt body,
String factoryMethod, String actionType) {
+ if (!extendedNodeImpl.hasActions(actionType)) {
+ return;
+ }
+ List<DroolsConsequenceAction> scripts =
extendedNodeImpl.getActions(actionType).stream()
+ .filter(Predicate.not(Objects::isNull))
+ .filter(DroolsConsequenceAction.class::isInstance)
+ .map(DroolsConsequenceAction.class::cast)
+ .filter(e -> e.getConsequence() != null &&
!e.getConsequence().isBlank())
+ .toList();
+
+ for (DroolsConsequenceAction script : scripts) {
+ body.addStatement(getFactoryMethod(getNodeId((T)
extendedNodeImpl), factoryMethod,
+ new StringLiteralExpr(actionType),
+ new StringLiteralExpr(script.getDialect()),
+ new
StringLiteralExpr(sanitizeString(script.getConsequence())),
+ buildDroolsConsequenceAction(extendedNodeImpl,
script.getDialect(), script.getConsequence())));
+ ;
+ }
+ }
+
+ private Expression buildDroolsConsequenceAction(ExtendedNodeImpl
extendedNodeImpl, String dialect, String script) {
+ if (script == null) {
+ return new NullLiteralExpr();
+ }
+ return
ActionCompilerRegistry.instance().find(dialect).buildAction(extendedNodeImpl,
script);
+ }
+
+ private boolean isExtendedNode(T node) {
+ return node instanceof ExtendedNodeImpl;
}
private boolean isAdHocNode(Node node) {
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractVisitor.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractVisitor.java
index ce0168cfe0..17dd3cd9d3 100644
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractVisitor.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractVisitor.java
@@ -54,8 +54,9 @@ import static
org.kie.kogito.internal.utils.ConversionUtils.sanitizeString;
public abstract class AbstractVisitor {
+ protected static final String ON_ACTION_SCRIPT_METHOD = "onActionScript";
protected static final String FACTORY_FIELD_NAME = "factory";
- protected static final String KCONTEXT_VAR = "kcontext";
+ public static final String KCONTEXT_VAR = "kcontext";
protected MethodCallExpr
getWorkflowElementConstructor(WorkflowElementIdentifier identifier) {
Type type = new
ClassOrInterfaceType().setName(WorkflowElementIdentifierFactory.class.getName());
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/ActionCompiler.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/ActionCompiler.java
new file mode 100644
index 0000000000..16f476209a
--- /dev/null
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/ActionCompiler.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.process.builder.action;
+
+import java.util.Arrays;
+
+import org.jbpm.workflow.core.impl.NodeImpl;
+
+import com.github.javaparser.ast.expr.Expression;
+
+public interface ActionCompiler {
+
+ String[] dialects();
+
+ default boolean accept(String dialect) {
+ return Arrays.asList(dialect).contains(dialect);
+ }
+
+ Expression buildAction(NodeImpl nodeImpl, String scrtip);
+}
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/ActionCompilerRegistry.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/ActionCompilerRegistry.java
new file mode 100644
index 0000000000..9edb3e5d77
--- /dev/null
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/ActionCompilerRegistry.java
@@ -0,0 +1,62 @@
+/*
+ * 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.jbpm.process.builder.action;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+
+import org.jbpm.util.JbpmClassLoaderUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ActionCompilerRegistry {
+
+ private static final Logger logger =
LoggerFactory.getLogger(ActionCompilerRegistry.class);
+
+ private static ActionCompilerRegistry INSTANCE;
+
+ private List<ActionCompiler> registry;
+
+ public static ActionCompilerRegistry instance() {
+ if (INSTANCE == null) {
+ INSTANCE = new ActionCompilerRegistry();
+ }
+ return INSTANCE;
+ }
+
+ protected ActionCompilerRegistry() {
+ this.registry = new ArrayList<>();
+ ServiceLoader.load(ActionCompiler.class,
JbpmClassLoaderUtil.findClassLoader()).forEach(registry::add);
+ }
+
+ public void register(ActionCompiler actionCompiler) {
+ this.registry.add(actionCompiler);
+ logger.debug("Manual registration of scripting language {} with
instance {}", List.of(actionCompiler.dialects()), actionCompiler);
+ }
+
+ public ActionCompiler find(String language) {
+ for (ActionCompiler transformer : registry) {
+ if (transformer.accept(language)) {
+ return transformer;
+ }
+ }
+ throw new IllegalArgumentException("action compiler not support for
dialect " + language);
+ }
+}
\ No newline at end of file
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/JavaActionCompiler.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/JavaActionCompiler.java
new file mode 100644
index 0000000000..f2762126f2
--- /dev/null
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/JavaActionCompiler.java
@@ -0,0 +1,82 @@
+/*
+ * 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.jbpm.process.builder.action;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jbpm.compiler.canonical.AbstractNodeVisitor;
+import org.jbpm.process.core.context.variable.Variable;
+import org.jbpm.process.core.context.variable.VariableScope;
+import org.jbpm.workflow.core.impl.NodeImpl;
+
+import com.github.javaparser.StaticJavaParser;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.AssignExpr.Operator;
+import com.github.javaparser.ast.expr.CastExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+
+public class JavaActionCompiler implements ActionCompiler {
+
+ @Override
+ public String[] dialects() {
+ return new String[] { "java" };
+ }
+
+ @Override
+ public boolean accept(String dialect) {
+ return dialect.toLowerCase().contains("java");
+ }
+
+ @Override
+ public Expression buildAction(NodeImpl nodeImpl, String script) {
+ BlockStmt newDroolsConsequenceActionExpression = new BlockStmt();
+ newDroolsConsequenceActionExpression = StaticJavaParser.parseBlock("{"
+ script + "}");
+ Set<NameExpr> identifiers = new
HashSet<>(newDroolsConsequenceActionExpression.findAll(NameExpr.class));
+ for (NameExpr identifier : identifiers) {
+ VariableScope scope = (VariableScope)
nodeImpl.resolveContext(VariableScope.VARIABLE_SCOPE,
identifier.getNameAsString());
+ if (scope == null) {
+ continue;
+ }
+ Variable var = scope.findVariable(identifier.getNameAsString());
+ if (var == null) {
+ continue;
+ }
+ Type type =
StaticJavaParser.parseType(var.getType().getStringType());
+ VariableDeclarationExpr target = new VariableDeclarationExpr(type,
var.getName());
+ Expression source = new MethodCallExpr(new
NameExpr(AbstractNodeVisitor.KCONTEXT_VAR), "getVariable",
NodeList.nodeList(new StringLiteralExpr(var.getName())));
+ source = new CastExpr(type, source);
+ AssignExpr assign = new AssignExpr(target, source,
Operator.ASSIGN);
+ newDroolsConsequenceActionExpression.addStatement(0, assign);
+ }
+ ClassOrInterfaceType type =
StaticJavaParser.parseClassOrInterfaceType(org.kie.kogito.internal.process.runtime.KogitoProcessContext.class.getName());
+ return new LambdaExpr(NodeList.nodeList(new Parameter(type,
AbstractNodeVisitor.KCONTEXT_VAR)), newDroolsConsequenceActionExpression, true);
+ }
+
+}
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/MVELActionCompiler.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/MVELActionCompiler.java
new file mode 100644
index 0000000000..83124237af
--- /dev/null
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/action/MVELActionCompiler.java
@@ -0,0 +1,50 @@
+/*
+ * 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.jbpm.process.builder.action;
+
+import org.jbpm.compiler.canonical.AbstractNodeVisitor;
+import org.jbpm.workflow.core.impl.NodeImpl;
+
+import com.github.javaparser.StaticJavaParser;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+
+import static org.kie.kogito.internal.utils.ConversionUtils.sanitizeString;
+
+public class MVELActionCompiler implements ActionCompiler {
+
+ @Override
+ public String[] dialects() {
+ return new String[] { "mvel" };
+ }
+
+ @Override
+ public Expression buildAction(NodeImpl nodeImpl, String script) {
+ BlockStmt actionExpression = StaticJavaParser.parseBlock(
+ "{ org.mvel2.MVEL.eval(\"" + sanitizeString(script) +
+ "\", new
org.jbpm.workflow.instance.impl.NodeInstanceResolverFactory((org.jbpm.workflow.instance.NodeInstance)
kcontext.getNodeInstance())); }");
+ ClassOrInterfaceType type =
StaticJavaParser.parseClassOrInterfaceType(org.kie.kogito.internal.process.runtime.KogitoProcessContext.class.getName());
+ return new LambdaExpr(NodeList.nodeList(new Parameter(type,
AbstractNodeVisitor.KCONTEXT_VAR)), actionExpression, true);
+ }
+
+}
diff --git
a/jbpm/jbpm-flow-builder/src/main/resources/META-INF/services/org.jbpm.process.builder.action.ActionCompiler
b/jbpm/jbpm-flow-builder/src/main/resources/META-INF/services/org.jbpm.process.builder.action.ActionCompiler
new file mode 100644
index 0000000000..d9494beeea
--- /dev/null
+++
b/jbpm/jbpm-flow-builder/src/main/resources/META-INF/services/org.jbpm.process.builder.action.ActionCompiler
@@ -0,0 +1,2 @@
+org.jbpm.process.builder.action.JavaActionCompiler
+org.jbpm.process.builder.action.MVELActionCompiler
\ No newline at end of file
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractCompositeNodeFactory.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractCompositeNodeFactory.java
index 0befff9481..329534bbed 100644
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractCompositeNodeFactory.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractCompositeNodeFactory.java
@@ -109,4 +109,5 @@ public abstract class AbstractCompositeNodeFactory<T
extends RuleFlowNodeContain
}
return super.done();
}
+
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ExtendedNodeFactory.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ExtendedNodeFactory.java
index 0653d5f6df..0a22a65261 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ExtendedNodeFactory.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ExtendedNodeFactory.java
@@ -18,14 +18,9 @@
*/
package org.jbpm.ruleflow.core.factory;
-import java.util.ArrayList;
-import java.util.List;
-
import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
-import org.jbpm.workflow.core.DroolsAction;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.NodeContainer;
-import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
import org.kie.api.definition.process.WorkflowElementIdentifier;
@@ -39,25 +34,4 @@ public abstract class ExtendedNodeFactory<T extends
NodeFactory<T, P>, P extends
return (ExtendedNodeImpl) getNode();
}
- public T onEntryAction(String dialect, String action) {
- if (getExtendedNode().getActions(dialect) != null) {
- getExtendedNode().getActions(dialect).add(new
DroolsConsequenceAction(dialect, action));
- } else {
- List<DroolsAction> actions = new ArrayList<>();
- actions.add(new DroolsConsequenceAction(dialect, action));
- getExtendedNode().setActions(ExtendedNodeImpl.EVENT_NODE_ENTER,
actions);
- }
- return (T) this;
- }
-
- public T onExitAction(String dialect, String action) {
- if (getExtendedNode().getActions(dialect) != null) {
- getExtendedNode().getActions(dialect).add(new
DroolsConsequenceAction(dialect, action));
- } else {
- List<DroolsAction> actions = new ArrayList<>();
- actions.add(new DroolsConsequenceAction(dialect, action));
- getExtendedNode().setActions(ExtendedNodeImpl.EVENT_NODE_EXIT,
actions);
- }
- return (T) this;
- }
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/NodeFactory.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/NodeFactory.java
index bcbfb1f475..ba22a6d53b 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/NodeFactory.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/NodeFactory.java
@@ -18,10 +18,15 @@
*/
package org.jbpm.ruleflow.core.factory;
+import java.util.ArrayList;
+
import org.jbpm.process.core.context.variable.Mappable;
+import org.jbpm.process.instance.impl.Action;
import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.NodeContainer;
+import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
+import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
import org.kie.api.definition.process.WorkflowElementIdentifier;
public abstract class NodeFactory<T extends NodeFactory<T, P>, P extends
RuleFlowNodeContainerFactory<P, ?>> implements MappableNodeFactory<T> {
@@ -71,4 +76,27 @@ public abstract class NodeFactory<T extends NodeFactory<T,
P>, P extends RuleFlo
return (Mappable) node;
}
+ public T onEntryAction(String dialect, String action) {
+ return onActionScript(ExtendedNodeImpl.EVENT_NODE_ENTER, dialect,
action, null);
+ }
+
+ public T onExitAction(String dialect, String action) {
+ return onActionScript(ExtendedNodeImpl.EVENT_NODE_EXIT, dialect,
action, null);
+ }
+
+ public T onActionScript(String type, String dialect, String script, Action
compiledScript) {
+ DroolsConsequenceAction action = new DroolsConsequenceAction(dialect,
script);
+ if (compiledScript != null) {
+ action.setMetaData("Action", compiledScript);
+ }
+ if (getExtendedNode().getActions(type) == null) {
+ getExtendedNode().setActions(type, new ArrayList<>());
+ }
+ getExtendedNode().getActions(type).add(action);
+ return (T) this;
+ }
+
+ private ExtendedNodeImpl getExtendedNode() {
+ return (ExtendedNodeImpl) getNode();
+ }
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
index f1bb75950a..5319367af5 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
@@ -45,12 +45,10 @@ import
org.jbpm.process.core.validation.impl.ProcessValidationErrorImpl;
import org.jbpm.ruleflow.core.Metadata;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.Constraint;
-import org.jbpm.workflow.core.DroolsAction;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.WorkflowProcess;
import org.jbpm.workflow.core.impl.DataAssociation;
import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
-import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
import org.jbpm.workflow.core.impl.NodeImpl;
import org.jbpm.workflow.core.node.ActionNode;
import org.jbpm.workflow.core.node.BoundaryEventNode;
@@ -189,7 +187,6 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
errors);
} else if (node instanceof RuleSetNode) {
final RuleSetNode ruleSetNode = (RuleSetNode) node;
- validateOnEntryOnExitScripts(ruleSetNode, errors, process);
if (ruleSetNode.getFrom() == null &&
!acceptsNoIncomingConnections(node)) {
addErrorMessage(process,
node,
@@ -318,7 +315,6 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
}
} else if (node instanceof MilestoneNode) {
final MilestoneNode milestone = (MilestoneNode) node;
- validateOnEntryOnExitScripts(milestone, errors, process);
if (milestone.getFrom() == null &&
!acceptsNoIncomingConnections(node)) {
addErrorMessage(process,
node,
@@ -350,7 +346,6 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
}
} else if (node instanceof SubProcessNode) {
final SubProcessNode subProcess = (SubProcessNode) node;
- validateOnEntryOnExitScripts(subProcess, errors, process);
if (subProcess.getFrom() == null &&
!acceptsNoIncomingConnections(node)) {
addErrorMessage(process,
node,
@@ -429,7 +424,6 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
}
} else if (node instanceof WorkItemNode) {
final WorkItemNode workItemNode = (WorkItemNode) node;
- validateOnEntryOnExitScripts(workItemNode, errors, process);
if (workItemNode.getFrom() == null &&
!acceptsNoIncomingConnections(node)) {
addErrorMessage(process,
node,
@@ -469,7 +463,6 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
}
} else if (node instanceof ForEachNode) {
final ForEachNode forEachNode = (ForEachNode) node;
- validateOnEntryOnExitScripts(forEachNode, errors, process);
String variableName = forEachNode.getVariableName();
if (variableName == null || "".equals(variableName)) {
addErrorMessage(process,
@@ -513,7 +506,6 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
process);
} else if (node instanceof DynamicNode) {
final DynamicNode dynamicNode = (DynamicNode) node;
- validateOnEntryOnExitScripts(dynamicNode, errors, process);
if (dynamicNode.getDefaultIncomingConnections().isEmpty() &&
!acceptsNoIncomingConnections(dynamicNode)) {
addErrorMessage(process,
@@ -540,7 +532,6 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
process);
} else if (node instanceof CompositeNode) {
final CompositeNode compositeNode = (CompositeNode) node;
- validateOnEntryOnExitScripts(compositeNode, errors, process);
for (Map.Entry<String, NodeAndType> inType :
compositeNode.getLinkedIncomingNodes().entrySet()) {
if
(compositeNode.getIncomingConnections(inType.getKey()).isEmpty() &&
!acceptsNoIncomingConnections(node)) {
addErrorMessage(process,
@@ -949,20 +940,6 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
return validateProcess((RuleFlowProcess) process);
}
- //TODO To be removed once https://issues.redhat.com/browse/KOGITO-2067 is
fixed
- private void validateOnEntryOnExitScripts(Node node,
List<ProcessValidationError> errors, RuleFlowProcess process) {
- if (node instanceof ExtendedNodeImpl) {
- List<DroolsAction> actions = ((ExtendedNodeImpl)
node).getActions(ExtendedNodeImpl.EVENT_NODE_ENTER);
- if (actions != null && !actions.isEmpty()) {
- addErrorMessage(process, node, errors, "On Entry Action is not
yet supported in Kogito");
- }
- actions = ((ExtendedNodeImpl)
node).getActions(ExtendedNodeImpl.EVENT_NODE_EXIT);
- if (actions != null && !actions.isEmpty()) {
- addErrorMessage(process, node, errors, "On Exit Action is not
yet supported in Kogito");
- }
- }
- }
-
private void validateVariables(List<ProcessValidationError> errors,
RuleFlowProcess process) {
List<Variable> variables = process.getVariableScope().getVariables();
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ExtendedNodeImpl.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ExtendedNodeImpl.java
index 8a41d90e60..a0f4e21583 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ExtendedNodeImpl.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ExtendedNodeImpl.java
@@ -39,6 +39,10 @@ public class ExtendedNodeImpl extends NodeImpl {
this.actions.put(type, actions);
}
+ public boolean hasActions(String type) {
+ return this.actions.get(type) != null;
+ }
+
public List<DroolsAction> getActions(String type) {
return this.actions.get(type);
}
diff --git
a/jbpm/jbpm-flow/src/test/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidatorTest.java
b/jbpm/jbpm-flow/src/test/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidatorTest.java
index f6e52f25e7..a2d99b7a71 100755
---
a/jbpm/jbpm-flow/src/test/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidatorTest.java
+++
b/jbpm/jbpm-flow/src/test/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidatorTest.java
@@ -26,26 +26,17 @@ import
org.jbpm.process.core.datatype.impl.type.StringDataType;
import org.jbpm.process.core.validation.ProcessValidationError;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
-import org.jbpm.workflow.core.DroolsAction;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
-import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
import org.jbpm.workflow.core.node.ActionNode;
import org.jbpm.workflow.core.node.CompositeNode;
import org.jbpm.workflow.core.node.DynamicNode;
import org.jbpm.workflow.core.node.EndNode;
-import org.jbpm.workflow.core.node.ForEachNode;
-import org.jbpm.workflow.core.node.MilestoneNode;
-import org.jbpm.workflow.core.node.RuleSetNode;
import org.jbpm.workflow.core.node.StartNode;
-import org.jbpm.workflow.core.node.SubProcessNode;
-import org.jbpm.workflow.core.node.WorkItemNode;
-import org.jbpm.workflow.instance.rule.RuleType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.kie.api.definition.process.WorkflowElementIdentifier;
-import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -211,32 +202,6 @@ public class RuleFlowProcessValidatorTest {
assertThat(errors[0].getMessage()).isEqualTo("Node 'CompositeNode' [3]
Composite has no start node defined.");
}
- //TODO To be removed once https://issues.redhat.com/browse/KOGITO-2067 is
fixed
- @Test
- void testOnEntryOnExitValidation() {
- testNodeOnEntryOnExit(new MilestoneNode());
- RuleSetNode ruleSetNode = new RuleSetNode();
- ruleSetNode.setRuleType(mock(RuleType.class));
- testNodeOnEntryOnExit(ruleSetNode);
- testNodeOnEntryOnExit(new SubProcessNode());
- testNodeOnEntryOnExit(new WorkItemNode());
- testNodeOnEntryOnExit(new ForEachNode(one));
- testNodeOnEntryOnExit(new DynamicNode());
- testNodeOnEntryOnExit(new CompositeNode());
- }
-
- private void testNodeOnEntryOnExit(ExtendedNodeImpl node) {
- List<ProcessValidationError> errors = new ArrayList<>();
- node.setName("name");
- node.setId(node.getId());
- node.setActions(ExtendedNodeImpl.EVENT_NODE_ENTER, singletonList(new
DroolsAction()));
- node.setActions(ExtendedNodeImpl.EVENT_NODE_EXIT, singletonList(new
DroolsAction()));
- validator.validateNodes(new org.kie.api.definition.process.Node[] {
node }, errors, process);
- assertThat(errors).extracting("message").contains(
- "Node 'name' [" + node.getId().toExternalFormat() + "] On
Entry Action is not yet supported in Kogito",
- "Node 'name' [" + node.getId().toExternalFormat() + "] On Exit
Action is not yet supported in Kogito");
- }
-
@Test
void testScriptTaskDialect() {
StartNode startNode = new StartNode();
diff --git a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java
b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java
index 9af1206fb2..319595851d 100755
--- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java
+++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ActivityTest.java
@@ -34,6 +34,8 @@ import org.jbpm.bpmn2.objects.Address;
import org.jbpm.bpmn2.objects.HelloService;
import org.jbpm.bpmn2.objects.Person;
import org.jbpm.bpmn2.objects.TestWorkItemHandler;
+import org.jbpm.bpmn2.subprocess.SubProcessWithEntryExitScriptsModel;
+import org.jbpm.bpmn2.subprocess.SubProcessWithEntryExitScriptsProcess;
import org.jbpm.bpmn2.test.RequirePersistence;
import org.jbpm.process.builder.ActionBuilder;
import org.jbpm.process.builder.AssignmentBuilder;
@@ -49,6 +51,8 @@ import
org.jbpm.process.instance.event.listeners.TriggerRulesEventListener;
import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler;
import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler;
import org.jbpm.test.util.ProcessCompletedCountDownProcessEventListener;
+import org.jbpm.test.utils.EventTrackerProcessListener;
+import org.jbpm.test.utils.ProcessTestHelper;
import org.jbpm.workflow.core.impl.DataAssociation;
import org.jbpm.workflow.core.impl.DataDefinition;
import org.jbpm.workflow.core.node.ActionNode;
@@ -76,6 +80,7 @@ import org.kie.api.event.rule.MatchCancelledEvent;
import org.kie.api.event.rule.MatchCreatedEvent;
import org.kie.api.runtime.process.DataTransformer;
import org.kie.api.runtime.process.NodeInstance;
+import org.kie.kogito.Application;
import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener;
import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer;
import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
@@ -83,6 +88,7 @@ import
org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
import org.kie.kogito.internal.process.runtime.KogitoWorkItem;
import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance;
+import org.kie.kogito.process.ProcessInstance;
import org.kie.kogito.process.workitems.InternalKogitoWorkItem;
import static org.assertj.core.api.Assertions.assertThat;
@@ -426,39 +432,27 @@ public class ActivityTest extends JbpmBpmn2TestCase {
}
@Test
- @Disabled("On Exit not supported, see
https://issues.redhat.com/browse/KOGITO-2067")
public void testSubProcessWithEntryExitScripts() throws Exception {
- kruntime =
createKogitoProcessRuntime("subprocess/BPMN2-SubProcessWithEntryExitScripts.bpmn2");
- TestWorkItemHandler handler = new TestWorkItemHandler();
- kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human
Task", handler);
-
- KogitoProcessInstance processInstance =
kruntime.startProcess("com.sample.bpmn.hello");
-
- assertNodeTriggered(processInstance.getStringId(), "Task1");
- Object var1 = getProcessVarValue(processInstance, "var1");
- assertThat(var1).isNotNull().hasToString("10");
-
- assertNodeTriggered(processInstance.getStringId(), "Task2");
- Object var2 = getProcessVarValue(processInstance, "var2");
- assertThat(var2).isNotNull().hasToString("20");
-
- assertNodeTriggered(processInstance.getStringId(), "Task3");
- Object var3 = getProcessVarValue(processInstance, "var3");
- assertThat(var3).isNotNull().hasToString("30");
-
- assertNodeTriggered(processInstance.getStringId(), "SubProcess");
- Object var4 = getProcessVarValue(processInstance, "var4");
- assertThat(var4).isNotNull().hasToString("40");
-
- Object var5 = getProcessVarValue(processInstance, "var5");
- assertThat(var5).isNotNull().hasToString("50");
-
- org.kie.kogito.internal.process.runtime.KogitoWorkItem workItem =
handler.getWorkItem();
- assertThat(workItem).isNotNull();
-
-
kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(),
null);
-
- assertProcessInstanceCompleted(processInstance);
+ Application app = ProcessTestHelper.newApplication();
+ EventTrackerProcessListener listener = new
EventTrackerProcessListener();
+ ProcessTestHelper.registerProcessEventListener(app, listener);
+
+ org.kie.kogito.process.Process<SubProcessWithEntryExitScriptsModel>
process = SubProcessWithEntryExitScriptsProcess.newProcess(app);
+ ProcessInstance<SubProcessWithEntryExitScriptsModel> processInstance =
process.createInstance(process.createModel());
+ processInstance.start();
+
+
assertThat(listener.tracked()).anyMatch(ProcessTestHelper.triggered("Task1"));
+
assertThat(processInstance.variables().getVar1()).isNotNull().hasToString("10");
+
assertThat(listener.tracked()).anyMatch(ProcessTestHelper.triggered("Task2"));
+
assertThat(processInstance.variables().getVar2()).isNotNull().hasToString("20");
+
assertThat(listener.tracked()).anyMatch(ProcessTestHelper.triggered("Task3"));
+
assertThat(processInstance.variables().getVar3()).isNotNull().hasToString("30");
+
assertThat(listener.tracked()).anyMatch(ProcessTestHelper.triggered("SubProcess"));
+
assertThat(processInstance.variables().getVar4()).isNotNull().hasToString("40");
+
assertThat(processInstance.variables().getVar5()).isNotNull().hasToString("50");
+
+ ProcessTestHelper.completeWorkItem(processInstance, "john",
Collections.emptyMap());
+
assertThat(processInstance).extracting(ProcessInstance::status).isEqualTo(ProcessInstance.STATE_COMPLETED);
}
@Test
diff --git
a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/EventTrackerProcessListener.java
b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/EventTrackerProcessListener.java
new file mode 100644
index 0000000000..e88492b125
--- /dev/null
+++
b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/EventTrackerProcessListener.java
@@ -0,0 +1,50 @@
+/*
+ * 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.jbpm.test.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.kie.api.event.process.ProcessNodeEvent;
+import org.kie.api.event.process.ProcessNodeLeftEvent;
+import org.kie.api.event.process.ProcessNodeTriggeredEvent;
+import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener;
+
+public class EventTrackerProcessListener extends
DefaultKogitoProcessEventListener {
+
+ List<ProcessNodeEvent> nodeEvents;
+
+ public EventTrackerProcessListener() {
+ this.nodeEvents = new ArrayList<>();
+ }
+
+ @Override
+ public void afterNodeTriggered(ProcessNodeTriggeredEvent event) {
+ nodeEvents.add(event);
+ }
+
+ @Override
+ public void afterNodeLeft(ProcessNodeLeftEvent event) {
+ nodeEvents.add(event);
+ }
+
+ public List<ProcessNodeEvent> tracked() {
+ return nodeEvents;
+ }
+}
diff --git
a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java
b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java
index d191f06193..6c1d8ac54a 100644
--- a/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java
+++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/test/utils/ProcessTestHelper.java
@@ -21,7 +21,10 @@ package org.jbpm.test.utils;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
+import java.util.function.Predicate;
+import org.kie.api.event.process.ProcessNodeEvent;
+import org.kie.api.event.process.ProcessNodeTriggeredEvent;
import org.kie.kogito.Application;
import org.kie.kogito.Model;
import org.kie.kogito.StaticApplication;
@@ -76,4 +79,10 @@ public class ProcessTestHelper {
return workItems.stream().findFirst().get();
}
+ public static <T extends ProcessNodeEvent> Predicate<T> triggered(String
nodeName) {
+ return e -> {
+ return e instanceof ProcessNodeTriggeredEvent &&
nodeName.equals(((ProcessNodeTriggeredEvent)
e).getNodeInstance().getNodeName());
+ };
+ }
+
}
diff --git
a/jbpm/jbpm-tools/jbpm-tools-maven-plugin/src/test/resources/unit/project/src/main/bpmn/BPMN2-SubProcessWithEntryExitScripts.bpmn2
b/jbpm/jbpm-tools/jbpm-tools-maven-plugin/src/test/resources/unit/project/src/main/bpmn/BPMN2-SubProcessWithEntryExitScripts.bpmn2
new file mode 100755
index 0000000000..3dce9dac8c
--- /dev/null
+++
b/jbpm/jbpm-tools/jbpm-tools-maven-plugin/src/test/resources/unit/project/src/main/bpmn/BPMN2-SubProcessWithEntryExitScripts.bpmn2
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:tns="http://www.jboss.org/drools" xmlns="http://www.jboss.org/drools"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd
http://www.jboss.org/drools drools.xsd http://www.bpsi [...]
+ <bpmn2:itemDefinition id="_String" structureRef="String"/>
+ <bpmn2:itemDefinition id="_Integer" structureRef="Integer"/>
+ <bpmn2:process id="SubProcessWithEntryExitScripts" tns:version="1"
tns:packageName="org.jbpm.bpmn2.subprocess" name="Hello World"
isExecutable="true" processType="Private">
+ <bpmn2:extensionElements/>
+ <bpmn2:property id="var2" itemSubjectRef="_Integer"/>
+ <bpmn2:property id="var3" itemSubjectRef="_Integer"/>
+ <bpmn2:property id="var1" itemSubjectRef="_Integer"/>
+ <bpmn2:property id="var4" itemSubjectRef="_Integer"/>
+ <bpmn2:property id="var5" itemSubjectRef="_Integer"/>
+ <bpmn2:scriptTask id="_2" name="Task1"
scriptFormat="http://www.java.com/java">
+ <bpmn2:incoming>_1-_2</bpmn2:incoming>
+ <bpmn2:outgoing>SequenceFlow_11</bpmn2:outgoing>
+ <bpmn2:script>System.err.println("Task 1, var1 = 10");
+kcontext.setVariable("var1", new Integer(10));
+</bpmn2:script>
+ </bpmn2:scriptTask>
+ <bpmn2:startEvent id="_1" name="">
+ <bpmn2:outgoing>_1-_2</bpmn2:outgoing>
+ </bpmn2:startEvent>
+ <bpmn2:sequenceFlow id="_1-_2" tns:priority="1" sourceRef="_1"
targetRef="_2"/>
+ <bpmn2:scriptTask id="ScriptTask_2" name="Task3">
+ <bpmn2:incoming>SequenceFlow_12</bpmn2:incoming>
+ <bpmn2:outgoing>SequenceFlow_7</bpmn2:outgoing>
+ <bpmn2:script>System.err.println("Task 3, var3 = 30");
+kcontext.setVariable("var3",30);
+</bpmn2:script>
+ </bpmn2:scriptTask>
+ <bpmn2:sequenceFlow id="SequenceFlow_7" tns:priority="1" name=""
sourceRef="ScriptTask_2" targetRef="UserTask_2"/>
+ <bpmn2:endEvent id="_3" name="">
+ <bpmn2:incoming>SequenceFlow_8</bpmn2:incoming>
+ <bpmn2:terminateEventDefinition id="TerminateEventDefinition_1"/>
+ </bpmn2:endEvent>
+ <bpmn2:userTask id="UserTask_2" name="User Task 2">
+ <bpmn2:incoming>SequenceFlow_7</bpmn2:incoming>
+ <bpmn2:outgoing>SequenceFlow_8</bpmn2:outgoing>
+ <bpmn2:ioSpecification id="_InputOutputSpecification_24">
+ <bpmn2:dataInput id="_DataInput_150" name="TaskName"/>
+ <bpmn2:dataInput id="_DataInput_151" name="Priority"/>
+ <bpmn2:dataInput id="_DataInput_152" name="Comment"/>
+ <bpmn2:dataInput id="_DataInput_153" name="GroupId"/>
+ <bpmn2:dataInput id="_DataInput_154" name="Skippable"/>
+ <bpmn2:dataInput id="_DataInput_155" name="Content"/>
+ <bpmn2:dataInput id="_DataInput_156" name="Locale"/>
+ <bpmn2:inputSet id="_InputSet_24" name="New Input Set">
+ <bpmn2:dataInputRefs>_DataInput_150</bpmn2:dataInputRefs>
+ <bpmn2:dataInputRefs>_DataInput_151</bpmn2:dataInputRefs>
+ <bpmn2:dataInputRefs>_DataInput_152</bpmn2:dataInputRefs>
+ <bpmn2:dataInputRefs>_DataInput_153</bpmn2:dataInputRefs>
+ <bpmn2:dataInputRefs>_DataInput_154</bpmn2:dataInputRefs>
+ <bpmn2:dataInputRefs>_DataInput_155</bpmn2:dataInputRefs>
+ <bpmn2:dataInputRefs>_DataInput_156</bpmn2:dataInputRefs>
+ </bpmn2:inputSet>
+ <bpmn2:outputSet id="_OutputSet_21" name="Output Set"/>
+ </bpmn2:ioSpecification>
+ <bpmn2:dataInputAssociation id="_DataInputAssociation_150">
+ <bpmn2:targetRef>_DataInput_150</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_DataInputAssociation_151">
+ <bpmn2:targetRef>_DataInput_151</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_DataInputAssociation_152">
+ <bpmn2:targetRef>_DataInput_152</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_DataInputAssociation_153">
+ <bpmn2:targetRef>_DataInput_153</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_DataInputAssociation_154">
+ <bpmn2:targetRef>_DataInput_154</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_DataInputAssociation_155">
+ <bpmn2:targetRef>_DataInput_155</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_DataInputAssociation_156">
+ <bpmn2:targetRef>_DataInput_156</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ </bpmn2:userTask>
+ <bpmn2:sequenceFlow id="SequenceFlow_8" tns:priority="1" name=""
sourceRef="UserTask_2" targetRef="_3"/>
+ <bpmn2:subProcess id="SubProcess_1" name="SubProcess">
+ <bpmn2:extensionElements>
+ <tns:onEntry-script scriptFormat="http://www.java.com/java">
+ <tns:script>System.err.println("SubProcess, var4 = 40");
+kcontext.setVariable("var4",40);
+</tns:script>
+ </tns:onEntry-script>
+ <tns:onExit-script scriptFormat="http://www.java.com/java">
+ <tns:script>System.err.println("SubProcess, var5 = 50");
+kcontext.setVariable("var5",50);
+</tns:script>
+ </tns:onExit-script>
+ </bpmn2:extensionElements>
+ <bpmn2:incoming>SequenceFlow_11</bpmn2:incoming>
+ <bpmn2:outgoing>SequenceFlow_12</bpmn2:outgoing>
+ <bpmn2:startEvent id="StartEvent_1" name="">
+ <bpmn2:outgoing>SequenceFlow_10</bpmn2:outgoing>
+ </bpmn2:startEvent>
+ <bpmn2:sequenceFlow id="SequenceFlow_10" tns:priority="1" name=""
sourceRef="StartEvent_1" targetRef="ScriptTask_1"/>
+ <bpmn2:scriptTask id="ScriptTask_1" name="Task2"
scriptFormat="http://www.java.com/java">
+ <bpmn2:incoming>SequenceFlow_10</bpmn2:incoming>
+ <bpmn2:outgoing>SequenceFlow_9</bpmn2:outgoing>
+ <bpmn2:script>System.err.println("Task 2, var2 = 20");
+kcontext.setVariable("var2",20);
+</bpmn2:script>
+ </bpmn2:scriptTask>
+ <bpmn2:sequenceFlow id="SequenceFlow_9" tns:priority="1"
sourceRef="ScriptTask_1" targetRef="EndEvent_1"/>
+ <bpmn2:endEvent id="EndEvent_1" name="">
+ <bpmn2:incoming>SequenceFlow_9</bpmn2:incoming>
+ </bpmn2:endEvent>
+ </bpmn2:subProcess>
+ <bpmn2:sequenceFlow id="SequenceFlow_11" tns:priority="1" name=""
sourceRef="_2" targetRef="SubProcess_1"/>
+ <bpmn2:sequenceFlow id="SequenceFlow_12" tns:priority="1" name=""
sourceRef="SubProcess_1" targetRef="ScriptTask_2"/>
+ </bpmn2:process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_Process_1"
bpmnElement="com.sample.bpmn.hello">
+ <bpmndi:BPMNShape id="BPMNShape_SubProcess_1" bpmnElement="SubProcess_1"
isExpanded="true">
+ <dc:Bounds height="111.0" width="274.0" x="290.0" y="6.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BPMNShape_StartEvent_1" bpmnElement="_1">
+ <dc:Bounds height="36.0" width="36.0" x="40.0" y="43.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BPMNShape_EndEvent_1" bpmnElement="_3">
+ <dc:Bounds height="36.0" width="36.0" x="990.0" y="43.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BPMNShape_ScriptTask_1" bpmnElement="_2">
+ <dc:Bounds height="48.0" width="80.0" x="120.0" y="39.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BPMNShape_ScriptTask_3" bpmnElement="ScriptTask_2">
+ <dc:Bounds height="50.0" width="110.0" x="630.0" y="35.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BPMNShape_UserTask_2" bpmnElement="UserTask_2">
+ <dc:Bounds height="50.0" width="110.0" x="820.0" y="35.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BPMNShape_EndEvent_2" bpmnElement="EndEvent_1">
+ <dc:Bounds height="36.0" width="36.0" x="508.0" y="44.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+ <dc:Bounds height="36.0" width="36.0" x="310.0" y="44.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="BPMNShape_ScriptTask_2" bpmnElement="ScriptTask_1">
+ <dc:Bounds height="50.0" width="110.0" x="373.0" y="37.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="_1-_2">
+ <di:waypoint xsi:type="dc:Point" x="76.0" y="61.0"/>
+ <di:waypoint xsi:type="dc:Point" x="120.0" y="63.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_8"
bpmnElement="SequenceFlow_7" sourceElement="BPMNShape_ScriptTask_3"
targetElement="BPMNShape_UserTask_2">
+ <di:waypoint xsi:type="dc:Point" x="740.0" y="60.0"/>
+ <di:waypoint xsi:type="dc:Point" x="820.0" y="60.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_9"
bpmnElement="SequenceFlow_8" sourceElement="BPMNShape_UserTask_2"
targetElement="BPMNShape_EndEvent_1">
+ <di:waypoint xsi:type="dc:Point" x="930.0" y="60.0"/>
+ <di:waypoint xsi:type="dc:Point" x="990.0" y="61.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_10"
bpmnElement="SequenceFlow_9" sourceElement="BPMNShape_ScriptTask_2"
targetElement="BPMNShape_EndEvent_2">
+ <di:waypoint xsi:type="dc:Point" x="483.0" y="62.0"/>
+ <di:waypoint xsi:type="dc:Point" x="494.0" y="62.0"/>
+ <di:waypoint xsi:type="dc:Point" x="494.0" y="62.0"/>
+ <di:waypoint xsi:type="dc:Point" x="508.0" y="62.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_11"
bpmnElement="SequenceFlow_10" sourceElement="BPMNShape_StartEvent_2"
targetElement="BPMNShape_ScriptTask_2">
+ <di:waypoint xsi:type="dc:Point" x="346.0" y="62.0"/>
+ <di:waypoint xsi:type="dc:Point" x="358.0" y="62.0"/>
+ <di:waypoint xsi:type="dc:Point" x="358.0" y="62.0"/>
+ <di:waypoint xsi:type="dc:Point" x="373.0" y="62.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_12"
bpmnElement="SequenceFlow_11" sourceElement="BPMNShape_ScriptTask_1"
targetElement="BPMNShape_SubProcess_1">
+ <di:waypoint xsi:type="dc:Point" x="200.0" y="63.0"/>
+ <di:waypoint xsi:type="dc:Point" x="290.0" y="61.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_13"
bpmnElement="SequenceFlow_12" sourceElement="BPMNShape_SubProcess_1"
targetElement="BPMNShape_ScriptTask_3">
+ <di:waypoint xsi:type="dc:Point" x="564.0" y="61.0"/>
+ <di:waypoint xsi:type="dc:Point" x="630.0" y="60.0"/>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]