From 6ebf8d913e3715b79a5c26599b5c8c6a125254bb Mon Sep 17 00:00:00 2001 From: "esteban.robles" Date: Thu, 9 Sep 2010 17:35:49 +0000 Subject: [PATCH] ACT-119: Add web service - Create message, structure classes. - Improve parsing to handle itemDefinitions and structures. - Add a first version of the test for the web service example. - Refactor WebServiceActivity class. --- .../engine/impl/bpmn/ClassStructure.java | 38 +++++++ .../engine/impl/bpmn/ItemDefinition.java | 60 ++++++++++ .../activiti/engine/impl/bpmn/ItemKind.java | 24 ++++ .../activiti/engine/impl/bpmn/Message.java | 38 +++++++ .../activiti/engine/impl/bpmn/Operation.java | 55 ++++----- .../engine/impl/bpmn/SimpleStructure.java | 57 ++++++++++ .../engine/impl/bpmn/SoapStructure.java | 38 +++++++ .../activiti/engine/impl/bpmn/Structure.java | 35 ++++++ ...y.java => WebServiceActivityBehavior.java} | 59 ++++++++-- .../engine/impl/bpmn/parser/BpmnParse.java | 104 ++++++++++++++++-- .../bpmn/servicetask/WebServiceTaskTest.java | 28 +++++ ...va => WebServiceActivityBehaviorTest.java} | 86 +++++++++++---- ...erviceInvocationWithoutDataFlow.bpmn20.xml | 8 +- 13 files changed, 547 insertions(+), 83 deletions(-) create mode 100644 modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ClassStructure.java create mode 100644 modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ItemDefinition.java create mode 100644 modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ItemKind.java create mode 100644 modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Message.java create mode 100644 modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/SimpleStructure.java create mode 100644 modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/SoapStructure.java create mode 100644 modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Structure.java rename modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/{WebServiceActivity.java => WebServiceActivityBehavior.java} (65%) create mode 100644 modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/servicetask/WebServiceTaskTest.java rename modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/webservice/{WebServiceActivityTest.java => WebServiceActivityBehaviorTest.java} (68%) diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ClassStructure.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ClassStructure.java new file mode 100644 index 0000000000..ebec522a0a --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ClassStructure.java @@ -0,0 +1,38 @@ +/* Licensed 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.activiti.engine.impl.bpmn; + +/** + * Represents a structure encapsulated in a class + * + * @author Esteban Robles Luna + */ +public class ClassStructure implements Structure { + + protected Class classStructure; + + public ClassStructure(Class classStructure) { + this.classStructure = classStructure; + } + + @Override + public String getId() { + return this.classStructure.getName(); + } + + @Override + public int getFieldSize() { + //TODO + return 0; + } +} diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ItemDefinition.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ItemDefinition.java new file mode 100644 index 0000000000..4ea51aeab8 --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ItemDefinition.java @@ -0,0 +1,60 @@ +/* Licensed 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.activiti.engine.impl.bpmn; + +/** + * Implementation of the BPMN 2.0 'itemDefinition' + * + * @author Esteban Robles Luna + */ +public class ItemDefinition { + + protected String id; + + protected Structure structure; + + protected boolean isCollection; + + protected ItemKind itemKind; + + private ItemDefinition() { + this.isCollection = false; + this.itemKind = ItemKind.Information; + } + + public ItemDefinition(String id, Structure structure) { + this(); + this.id = id; + this.structure = structure; + } + + public Structure getStructure() { + return this.structure; + } + + public boolean isCollection() { + return isCollection; + } + + public void setCollection(boolean isCollection) { + this.isCollection = isCollection; + } + + public ItemKind getItemKind() { + return itemKind; + } + + public void setItemKind(ItemKind itemKind) { + this.itemKind = itemKind; + } +} diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ItemKind.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ItemKind.java new file mode 100644 index 0000000000..ecc99b1d51 --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ItemKind.java @@ -0,0 +1,24 @@ +/* Licensed 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.activiti.engine.impl.bpmn; + +/** + * Implementation of the BPMN 2.0 'itemKind' + * + * @author Esteban Robles Luna + */ +public enum ItemKind { + + Information, + Physical +} diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Message.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Message.java new file mode 100644 index 0000000000..8deddf8566 --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Message.java @@ -0,0 +1,38 @@ +/* Licensed 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.activiti.engine.impl.bpmn; + +/** + * Implementation of the BPMN 2.0 'message' + * + * @author Esteban Robles Luna + */ +public class Message { + + protected String id; + + protected ItemDefinition itemDefinition; + + public Message(String id, ItemDefinition itemDefinition) { + this.id = id; + this.itemDefinition = itemDefinition; + } + + public ItemDefinition getItemDefinition() { + return this.itemDefinition; + } + + public Structure getStructure() { + return this.itemDefinition.getStructure(); + } +} diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Operation.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Operation.java index 090aba1ad9..de2449e3d8 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Operation.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Operation.java @@ -12,10 +12,6 @@ */ package org.activiti.engine.impl.bpmn; -import java.util.ArrayList; -import java.util.List; - - /** * An Operation is part of an {@link BpmnInterface} and it defines Messages that are consumed and * (optionally) produced when the Operation is called. @@ -28,9 +24,9 @@ public class Operation { protected String name; - protected List inArguments; + protected Message inMessage; - protected List outArguments; + protected Message outMessage; /** * The interface to which this operations belongs @@ -41,39 +37,13 @@ public class Operation { } - public Operation(String id, String name, BpmnInterface bpmnInterface) { - this.inArguments = new ArrayList(); - this.outArguments = new ArrayList(); - + public Operation(String id, String name, BpmnInterface bpmnInterface, Message inMessage) { setId(id); setName(name); setInterface(bpmnInterface); + setInMessage(inMessage); } - public void addInArgument(String argument) { - this.inArguments.add(argument); - } - - public void addOutArgument(String argument) { - this.outArguments.add(argument); - } - - public int getInArgumentsSize() { - return this.inArguments.size(); - } - - public int getOutArgumentsSize() { - return this.outArguments.size(); - } - - public String getInArgument(int index) { - return this.inArguments.get(index); - } - - public String getOutArgument(int index) { - return this.outArguments.get(index); - } - public String getId() { return id; } @@ -97,5 +67,20 @@ public class Operation { public void setInterface(BpmnInterface bpmnInterface) { this.bpmnInterface = bpmnInterface; } - + + public Message getInMessage() { + return inMessage; + } + + public void setInMessage(Message inMessage) { + this.inMessage = inMessage; + } + + public Message getOutMessage() { + return outMessage; + } + + public void setOutMessage(Message outMessage) { + this.outMessage = outMessage; + } } diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/SimpleStructure.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/SimpleStructure.java new file mode 100644 index 0000000000..2147d291e6 --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/SimpleStructure.java @@ -0,0 +1,57 @@ +/* Licensed 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.activiti.engine.impl.bpmn; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Represents a simple in memory structure + * + * @author Esteban Robles Luna + */ +public class SimpleStructure implements Structure { + + protected String id; + + protected List fieldNames; + + public SimpleStructure(String id) { + this.id = id; + this.fieldNames = new ArrayList(); + } + + @Override + public int getFieldSize() { + return this.fieldNames.size(); + } + + @Override + public String getId() { + return this.id; + } + + public void setFieldName(int index, String fieldName) { + this.growFieldNamesToContain(index); + this.fieldNames.set(index, fieldName); + } + + private void growFieldNamesToContain(int index) { + if (!(this.fieldNames.size() - 1 >= index)) { + for (int i = this.fieldNames.size(); i <= index; i++) { + this.fieldNames.add(null); + } + } + } +} diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/SoapStructure.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/SoapStructure.java new file mode 100644 index 0000000000..22762f7e6d --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/SoapStructure.java @@ -0,0 +1,38 @@ +/* Licensed 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.activiti.engine.impl.bpmn; + +/** + * Represents a Soap structure + * + * @author Esteban Robles Luna + */ +public class SoapStructure implements Structure { + + protected String id; + + public SoapStructure(String id) { + this.id = id; + } + + @Override + public String getId() { + return this.id; + } + + @Override + public int getFieldSize() { + //TODO + return 0; + } +} diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Structure.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Structure.java new file mode 100644 index 0000000000..4d3df1d672 --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/Structure.java @@ -0,0 +1,35 @@ +/* Licensed 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.activiti.engine.impl.bpmn; + +/** + * Represents a structure used to exchange information + * + * @author Esteban Robles Luna + */ +public interface Structure { + + /** + * Obtains the id of this structure + * + * @return the id of this structure + */ + String getId(); + + /** + * Obtains the number of fields that this structure has + * + * @return the number of fields that this structure has + */ + int getFieldSize(); +} diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/WebServiceActivity.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/WebServiceActivityBehavior.java similarity index 65% rename from modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/WebServiceActivity.java rename to modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/WebServiceActivityBehavior.java index ab3a064a09..9390ae70af 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/WebServiceActivity.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/WebServiceActivityBehavior.java @@ -19,29 +19,36 @@ import org.activiti.engine.ActivitiException; import org.activiti.engine.impl.transformer.Identity; import org.activiti.engine.impl.transformer.Transformer; import org.activiti.engine.impl.webservice.SyncWebServiceClient; +import org.activiti.pvm.activity.ActivityBehavior; import org.activiti.pvm.activity.ActivityExecution; /** - * An activity that allows calling Web services + * An activity behavior that allows calling Web services * * @author Esteban Robles Luna */ -public class WebServiceActivity extends BpmnActivityBehavior { +public class WebServiceActivityBehavior implements ActivityBehavior { protected Operation operation; protected SyncWebServiceClient client; + protected List inVariableNames; + + protected List outVariableNames; + protected List inTransformers; protected List outTransformers; - public WebServiceActivity(SyncWebServiceClient client, Operation operation) { + public WebServiceActivityBehavior(SyncWebServiceClient client, Operation operation) { this.client = client; this.operation = operation; this.inTransformers = new ArrayList(); this.outTransformers = new ArrayList(); + this.inVariableNames = new ArrayList(); + this.outVariableNames = new ArrayList(); } /** @@ -54,19 +61,23 @@ public class WebServiceActivity extends BpmnActivityBehavior { Object[] arguments = this.getArguments(execution); Object[] transformedArguments = this.transform(arguments); Object[] results = this.send(transformedArguments); + + this.verifyResultsAccordingToOutMessage(results); + Object[] transformedResults = this.transformResults(results); this.store(transformedResults, execution); } private void fillTransformersIfEmpty() { - if (this.inTransformers.isEmpty() && this.operation.getInArgumentsSize() > 0) { - for (int i = 0; i < this.operation.getInArgumentsSize(); i++) { + if (this.inTransformers.isEmpty() && this.getInStructure().getFieldSize() > 0) { + for (int i = 0; i < this.getInStructure().getFieldSize(); i++) { this.inTransformers.add(Identity.getInstance()); } } - if (this.outTransformers.isEmpty() && this.operation.getOutArgumentsSize() > 0) { - for (int i = 0; i < this.operation.getOutArgumentsSize(); i++) { + if (this.getOutStructure() != null && this.outTransformers.isEmpty() + && this.getOutStructure().getFieldSize() > 0) { + for (int i = 0; i < this.getOutStructure().getFieldSize(); i++) { this.outTransformers.add(Identity.getInstance()); } } @@ -80,20 +91,34 @@ public class WebServiceActivity extends BpmnActivityBehavior { this.outTransformers.add(transformer); } + public void addInVariable(String variableName) { + this.inVariableNames.add(variableName); + } + + public void addOutVariable(String variableName) { + this.outVariableNames.add(variableName); + } + private void verifySameSizeOfTransformersAndArguments() { - if (this.operation.getInArgumentsSize() != this.inTransformers.size()) { + if (this.getInStructure().getFieldSize() != this.inTransformers.size()) { throw new ActivitiException("The size of IN arguments and transformers does not match"); } - if (this.operation.getOutArgumentsSize() != this.outTransformers.size()) { + if (this.getOutStructure() != null && this.getOutStructure().getFieldSize() != this.outTransformers.size()) { throw new ActivitiException("The size of OUT arguments and transformers does not match"); } } + + private void verifyResultsAccordingToOutMessage(Object[] results) { + if (this.getOutStructure() != null && results.length != this.getOutStructure().getFieldSize()) { + throw new ActivitiException("The result of the Web service call has different size according to the expected message"); + } + } private void store(Object[] transformedResults, ActivityExecution execution) { for (int i = 0; i < transformedResults.length; i++) { Object transformedResult = transformedResults[i]; - String outVariable = this.operation.getOutArgument(i); + String outVariable = this.outVariableNames.get(i); execution.setVariable(outVariable, transformedResult); } } @@ -121,11 +146,21 @@ public class WebServiceActivity extends BpmnActivityBehavior { } private Object[] getArguments(ActivityExecution execution) { - Object[] arguments = new Object[this.operation.getInArgumentsSize()]; + Object[] arguments = new Object[this.getInStructure().getFieldSize()]; for (int i = 0; i < arguments.length; i++) { - String inVariable = this.operation.getInArgument(i); + String inVariable = this.inVariableNames.get(i); arguments[i] = execution.getVariable(inVariable); } return arguments; } + + private Structure getInStructure() { + return this.operation.getInMessage().getStructure(); + } + + private Structure getOutStructure() { + return this.operation.getOutMessage() == null + ? null + : this.operation.getOutMessage().getStructure(); + } } diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java index c389e56a56..b98d2ec93e 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java @@ -26,9 +26,13 @@ import org.activiti.engine.ActivitiException; import org.activiti.engine.impl.bpmn.BoundaryTimerEventActivity; import org.activiti.engine.impl.bpmn.BpmnInterface; import org.activiti.engine.impl.bpmn.CallActivityBehaviour; +import org.activiti.engine.impl.bpmn.ClassStructure; import org.activiti.engine.impl.bpmn.Condition; import org.activiti.engine.impl.bpmn.ExclusiveGatewayActivity; +import org.activiti.engine.impl.bpmn.ItemDefinition; +import org.activiti.engine.impl.bpmn.ItemKind; import org.activiti.engine.impl.bpmn.ManualTaskActivity; +import org.activiti.engine.impl.bpmn.Message; import org.activiti.engine.impl.bpmn.NoneEndEventActivity; import org.activiti.engine.impl.bpmn.NoneStartEventActivity; import org.activiti.engine.impl.bpmn.Operation; @@ -38,9 +42,12 @@ import org.activiti.engine.impl.bpmn.ScriptTaskActivity; import org.activiti.engine.impl.bpmn.ServiceTaskDelegateActivityBehaviour; import org.activiti.engine.impl.bpmn.ServiceTaskMethodExpressionActivityBehavior; import org.activiti.engine.impl.bpmn.ServiceTaskValueExpressionActivityBehavior; +import org.activiti.engine.impl.bpmn.SoapStructure; +import org.activiti.engine.impl.bpmn.Structure; import org.activiti.engine.impl.bpmn.SubProcessActivity; import org.activiti.engine.impl.bpmn.TaskActivity; import org.activiti.engine.impl.bpmn.UserTaskActivity; +import org.activiti.engine.impl.bpmn.WebServiceActivityBehavior; import org.activiti.engine.impl.el.ActivitiValueExpression; import org.activiti.engine.impl.el.ExpressionManager; import org.activiti.engine.impl.el.UelMethodExpressionCondition; @@ -80,6 +87,16 @@ public class BpmnParse extends Parse { */ protected List processDefinitions = new ArrayList(); + /** + * Map containing the BPMN 2.0 messages, stored during the first phase + * of parsing since other elements can reference these messages. + * + * Messages are defined outside the process definition(s), which means + * that this map doesn't need to be re-initialized for each new process + * definition. + */ + protected Map messages = new HashMap(); + /** * Map containing the BPMN 2.0 item definitions, stored during the first phase * of parsing since other elements can reference these item definitions. @@ -88,7 +105,7 @@ public class BpmnParse extends Parse { * that this map doesn't need to be re-initialized for each new process * definition. */ - protected Map itemDefinitions = new HashMap(); + protected Map itemDefinitions = new HashMap(); /** * Map containing the the {@link BpmnInterface}s defined in the XML file. The @@ -147,6 +164,7 @@ public class BpmnParse extends Parse { // Item definitions and interfaces/operations are not part of any process definition // They need to be parsed before the process definitions since they will refer to them parseItemDefinitions(rootElement); + parseMessages(rootElement); parseInterfaces(rootElement); parseProcessDefinitions(rootElement); @@ -163,7 +181,49 @@ public class BpmnParse extends Parse { */ public void parseItemDefinitions(Element definitionsElement) { for (Element itemDefinitionElement : definitionsElement.elements("itemDefinition")) { - itemDefinitions.put(itemDefinitionElement.attribute("id"), itemDefinitionElement); + String id = itemDefinitionElement.attribute("id"); + String structureRef = itemDefinitionElement.attribute("structureRef"); + String itemKind = itemDefinitionElement.attribute("itemKind"); + Structure structure = null; + + try { + //it is a class + Class classStructure = this.getClass().getClassLoader().loadClass(structureRef); + structure = new ClassStructure(classStructure); + } catch (ClassNotFoundException e) { + //it is a reference to a different structure + //TODO + structure = new SoapStructure(id); + } + + ItemDefinition itemDefinition = new ItemDefinition(id, structure); + if (itemKind != null) { + itemDefinition.setItemKind(ItemKind.valueOf(itemKind)); + } + itemDefinitions.put(id, itemDefinition); + } + } + + /** + * Parses the messages of the given definitions file. Messages + * are not contained within a process element, but they can be referenced from + * inner process elements. + * + * @param definitionsElement + * The root element of the XML file/ + */ + public void parseMessages(Element definitionsElement) { + for (Element messageElement : definitionsElement.elements("message")) { + String id = messageElement.attribute("id"); + String itemRef = messageElement.attribute("itemRef"); + + if (!this.itemDefinitions.containsKey(itemRef)) { + addProblem(itemRef + " does not exist", messageElement); + } else { + ItemDefinition itemDefinition = this.itemDefinitions.get(itemRef); + Message message = new Message(id, itemDefinition); + this.messages.put(id, message); + } } } @@ -192,12 +252,26 @@ public class BpmnParse extends Parse { } public Operation parseOperation(Element operationElement, BpmnInterface bpmnInterface) { - String id = operationElement.attribute("id"); - String name = operationElement.attribute("name"); - Operation operation = new Operation(id, name, bpmnInterface); + Element inMessageRefElement = operationElement.element("inMessageRef"); - operations.put(id, operation); - return operation; + if (!this.messages.containsKey(inMessageRefElement.getText())) { + addProblem(inMessageRefElement.getText() + " does not exist", inMessageRefElement); + return null; + } else { + Message inMessage = this.messages.get(inMessageRefElement.getText()); + String id = operationElement.attribute("id"); + String name = operationElement.attribute("name"); + Operation operation = new Operation(id, name, bpmnInterface, inMessage); + + Element outMessageRefElement = operationElement.element("outMessageRef"); + if (this.messages.containsKey(outMessageRefElement.getText())) { + Message outMessage = this.messages.get(outMessageRefElement.getText()); + operation.setOutMessage(outMessage); + } + + operations.put(id, operation); + return operation; + } } /** @@ -437,6 +511,8 @@ public class BpmnParse extends Parse { String className = serviceTaskElement.attributeNS(BpmnParser.BPMN_EXTENSIONS_NS, "class"); String methodExpr = serviceTaskElement.attributeNS(BpmnParser.BPMN_EXTENSIONS_NS, "method-expr"); String valueExpr = serviceTaskElement.attributeNS(BpmnParser.BPMN_EXTENSIONS_NS, "value-expr"); + String implementation = serviceTaskElement.attribute("implementation"); + String operationRef = serviceTaskElement.attribute("operationRef"); if (className != null && className.trim().length() > 0) { activity.setActivityBehavior(new ServiceTaskDelegateActivityBehaviour(expressionManager.createValueExpression(className))); @@ -447,6 +523,13 @@ public class BpmnParse extends Parse { } else if (valueExpr != null && valueExpr.trim().length() > 0) { activity.setActivityBehavior(new ServiceTaskValueExpressionActivityBehavior(expressionManager.createValueExpression(valueExpr))); + } else if (implementation != null && operationRef != null && implementation.equalsIgnoreCase("##WebService")) { + if (!this.operations.containsKey(operationRef)) { + addProblem(operationRef + " does not exist" , serviceTaskElement); + } else { + Operation operation = this.operations.get(operationRef); + activity.setActivityBehavior(new WebServiceActivityBehavior(null, operation)); + } } else { throw new ActivitiException("'class' or 'expr' attribute is mandatory on serviceTask"); } @@ -859,9 +942,10 @@ public class BpmnParse extends Parse { String itemSubjectRef = propertyElement.attribute("itemSubjectRef"); String type = null; if (itemSubjectRef != null) { - Element itemDefinitionRef = itemDefinitions.get(itemSubjectRef); - if (itemDefinitionRef != null) { - type = itemDefinitionRef.attribute("structureRef"); + ItemDefinition itemDefinition = itemDefinitions.get(itemSubjectRef); + if (itemDefinition != null) { + Structure structure = itemDefinition.getStructure(); + type = structure.getId(); } else { throw new ActivitiException("Invalid itemDefinition reference: " + itemSubjectRef + " not found"); } diff --git a/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/servicetask/WebServiceTaskTest.java b/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/servicetask/WebServiceTaskTest.java new file mode 100644 index 0000000000..2b7eab900f --- /dev/null +++ b/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/servicetask/WebServiceTaskTest.java @@ -0,0 +1,28 @@ +/* Licensed 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.activiti.engine.test.bpmn.servicetask; + +import org.activiti.engine.test.Deployment; +import org.activiti.engine.test.ProcessEngineTestCase; + + +/** + * @author Esteban Robles Luna + */ +public class WebServiceTaskTest extends ProcessEngineTestCase { + + @Deployment + public void testWebServiceInvocationWithoutDataFlow() { + //TODO start process + } +} diff --git a/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/webservice/WebServiceActivityTest.java b/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/webservice/WebServiceActivityBehaviorTest.java similarity index 68% rename from modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/webservice/WebServiceActivityTest.java rename to modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/webservice/WebServiceActivityBehaviorTest.java index 2150a0cc42..35b0ab7901 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/webservice/WebServiceActivityTest.java +++ b/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/webservice/WebServiceActivityBehaviorTest.java @@ -18,8 +18,11 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import org.activiti.engine.ActivitiException; +import org.activiti.engine.impl.bpmn.ItemDefinition; +import org.activiti.engine.impl.bpmn.Message; import org.activiti.engine.impl.bpmn.Operation; -import org.activiti.engine.impl.bpmn.WebServiceActivity; +import org.activiti.engine.impl.bpmn.SimpleStructure; +import org.activiti.engine.impl.bpmn.WebServiceActivityBehavior; import org.activiti.engine.impl.transformer.Transformer; import org.activiti.engine.impl.webservice.SyncWebServiceClient; import org.activiti.pvm.activity.ActivityExecution; @@ -33,14 +36,18 @@ import org.junit.Test; * * @author Esteban Robles Luna */ -public class WebServiceActivityTest { +public class WebServiceActivityBehaviorTest { private SyncWebServiceClient client; private ActivityExecution execution; private Transformer inTransformer; private Transformer outTransformer; private Operation operation; - private WebServiceActivity activity; + private WebServiceActivityBehavior activity; + private SimpleStructure inStructure; + private Message inMessage; + private SimpleStructure outStructure; + private Message outMessage; @Before public void setUp() { @@ -48,8 +55,17 @@ public class WebServiceActivityTest { execution = mock(ActivityExecution.class); inTransformer = mock(Transformer.class); outTransformer = mock(Transformer.class); - operation = new Operation("idSetTo", "setTo", null); - activity = new WebServiceActivity(client, operation); + + inStructure = new SimpleStructure("id"); + ItemDefinition inItemDefinition = new ItemDefinition("id", inStructure); + inMessage = new Message("id", inItemDefinition); + + outStructure = new SimpleStructure("id"); + ItemDefinition outItemDefinition = new ItemDefinition("id", outStructure); + outMessage = new Message("id", outItemDefinition); + + operation = new Operation("idSetTo", "setTo", null, inMessage); + activity = new WebServiceActivityBehavior(client, operation); } @After @@ -62,9 +78,13 @@ public class WebServiceActivityTest { @Test public void testWebServiceCallWithNeitherInNorOutTransformers() throws Exception { - operation.addInArgument("valueToSet"); - operation.addOutArgument("resultOfCall"); - + activity.addInVariable("valueToSet"); + activity.addOutVariable("resultOfCall"); + + inStructure.setFieldName(0, "f1"); + outStructure.setFieldName(0, "fo1"); + operation.setOutMessage(outMessage); + when(execution.getVariable("valueToSet")).thenReturn("11"); when(client.send("setTo", new Object[] { "11" })).thenReturn(new Object[] { 33 }); @@ -77,8 +97,12 @@ public class WebServiceActivityTest { @Test public void testWebServiceCallWithNoOutTransformers() throws Exception { - operation.addInArgument("valueToSet"); - operation.addOutArgument("resultOfCall"); + activity.addInVariable("valueToSet"); + activity.addOutVariable("resultOfCall"); + + inStructure.setFieldName(0, "f1"); + outStructure.setFieldName(0, "fo1"); + operation.setOutMessage(outMessage); activity.addInTransformer(inTransformer); @@ -96,8 +120,12 @@ public class WebServiceActivityTest { @Test public void testWebServiceCallWithNoInTransformers() throws Exception { - operation.addInArgument("valueToSet"); - operation.addOutArgument("resultOfCall"); + activity.addInVariable("valueToSet"); + activity.addOutVariable("resultOfCall"); + + inStructure.setFieldName(0, "f1"); + outStructure.setFieldName(0, "fo1"); + operation.setOutMessage(outMessage); activity.addOutTransformer(outTransformer); @@ -115,8 +143,12 @@ public class WebServiceActivityTest { @Test public void testWebServiceCallWithInAndOutTransformers() throws Exception { - operation.addInArgument("valueToSet"); - operation.addOutArgument("resultOfCall"); + activity.addInVariable("valueToSet"); + activity.addOutVariable("resultOfCall"); + + inStructure.setFieldName(0, "f1"); + outStructure.setFieldName(0, "fo1"); + operation.setOutMessage(outMessage); activity.addInTransformer(inTransformer); activity.addOutTransformer(outTransformer); @@ -138,10 +170,15 @@ public class WebServiceActivityTest { @Test public void testInArgumentsSizeDoesNotMatch() { - operation.addInArgument("valueToSet"); - operation.addInArgument("valueToSet2"); - operation.addOutArgument("resultOfCall"); - + activity.addInVariable("valueToSet"); + activity.addInVariable("valueToSet2"); + activity.addOutVariable("resultOfCall"); + + inStructure.setFieldName(0, "f1"); + inStructure.setFieldName(1, "f2"); + outStructure.setFieldName(0, "fo1"); + operation.setOutMessage(outMessage); + activity.addInTransformer(inTransformer); try { @@ -156,9 +193,14 @@ public class WebServiceActivityTest { @Test public void testOutArgumentsSizeDoesNotMatch() { - operation.addInArgument("valueToSet"); - operation.addOutArgument("resultOfCall"); - operation.addOutArgument("resultOfCall2"); + activity.addInVariable("valueToSet"); + activity.addOutVariable("resultOfCall"); + activity.addOutVariable("resultOfCall2"); + + inStructure.setFieldName(0, "f1"); + outStructure.setFieldName(0, "fo1"); + outStructure.setFieldName(1, "fo2"); + operation.setOutMessage(outMessage); activity.addOutTransformer(outTransformer); @@ -171,4 +213,4 @@ public class WebServiceActivityTest { Assert.fail("Should have thrown an ActivitiException"); } } -} +} \ No newline at end of file diff --git a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/servicetask/WebServiceTaskTest.testWebServiceInvocationWithoutDataFlow.bpmn20.xml b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/servicetask/WebServiceTaskTest.testWebServiceInvocationWithoutDataFlow.bpmn20.xml index 7bc7cbcbf9..9b77fa5668 100644 --- a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/servicetask/WebServiceTaskTest.testWebServiceInvocationWithoutDataFlow.bpmn20.xml +++ b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/servicetask/WebServiceTaskTest.testWebServiceInvocationWithoutDataFlow.bpmn20.xml @@ -38,13 +38,13 @@ - tns:incRequestMessage - tns:incResponseMessage + incRequestMessage + incResponseMessage - - + + -- GitLab