Commit ed42f3bd authored by Adrien's avatar Adrien Committed by GitHub

feat(data management) manage multiple documents with initial value (#1582)

* The operation generated for multiple documents with initial value is a
script, the idea is to add the new documents to the existing list
instead of replace the list.

closes [BST-91](https://bonitasoft.atlassian.net/browse/BST-91)
parent 09cd8257
......@@ -90,9 +90,14 @@ public class ExpressionHelper {
return generatedExp;
}
public static Expression createGroovyScriptExpression(final String expressionContent, final String returnType) {
final Expression exp = ExpressionFactory.eINSTANCE.createExpression();
exp.setName("ExpressionForEvaluation");
public static Expression createGroovyScriptExpression(String expressionContent, String returnType) {
return createGroovyScriptExpression(expressionContent, returnType, "ExpressionForEvaluation");
}
public static Expression createGroovyScriptExpression(String expressionContent, String returnType,
String scriptName) {
Expression exp = ExpressionFactory.eINSTANCE.createExpression();
exp.setName(scriptName);
exp.setInterpreter(ExpressionConstants.GROOVY);
exp.setType(ExpressionConstants.SCRIPT_TYPE);
exp.setContent(expressionContent);
......@@ -109,7 +114,6 @@ public class ExpressionHelper {
return exp;
}
public static Expression createConstantExpression(final String content, final String returnClassName) {
final Expression exp = ExpressionFactory.eINSTANCE.createExpression();
exp.setType(ExpressionConstants.CONSTANT_TYPE);
......@@ -185,7 +189,6 @@ public class ExpressionHelper {
return dataDependency;
}
public static void clearExpression(final Expression expr) {
Assert.isLegal(expr != null, "Expression cannot be null.");
expr.setName("");
......@@ -269,7 +272,6 @@ public class ExpressionHelper {
return returnType;
}
public static Expression createDocumentReferenceExpression(final Document d) {
final Expression exp = ExpressionFactory.eINSTANCE.createExpression();
exp.setType(ExpressionConstants.DOCUMENT_REF_TYPE);
......
package org.bonitasoft.studio.contract.core.mapping.operation;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.bonitasoft.studio.common.ExpressionConstants;
import org.bonitasoft.studio.model.expression.Expression;
import org.bonitasoft.studio.model.expression.Operation;
import org.bonitasoft.studio.model.process.ContractInput;
import org.bonitasoft.studio.model.process.ContractInputType;
import org.bonitasoft.studio.model.process.Document;
import org.bonitasoft.studio.model.process.builders.ContractInputBuilder;
import org.bonitasoft.studio.model.process.builders.DocumentBuilder;
import org.junit.Test;
public class DocumentUpdateOperationBuilderTest {
private static final String DOCUMENT_NAME = "documentName";
private static final String CONTRACT_INPUT_NAME = "documentNameDocumentInput";
@Test
public void should_create_operation_for_simple_document() {
ContractInput input = ContractInputBuilder.aContractInput()
.withName(CONTRACT_INPUT_NAME)
.withDataReference(DOCUMENT_NAME)
.withType(ContractInputType.FILE)
.single()
.build();
Document document = new DocumentBuilder()
.single()
.withName(DOCUMENT_NAME)
.build();
Operation operation = new DocumentUpdateOperationBuilder(input, document).toOperation();
Expression leftOperand = operation.getLeftOperand();
assertThat(leftOperand.getType()).isEqualTo(ExpressionConstants.DOCUMENT_REF_TYPE);
assertThat(leftOperand.getName()).isEqualTo(DOCUMENT_NAME);
assertThat(leftOperand.getContent()).isEqualTo(DOCUMENT_NAME);
assertThat(leftOperand.getReturnType()).isEqualTo(String.class.getName());
assertThat(operation.getOperator().getType()).isEqualTo(ExpressionConstants.SET_DOCUMENT_OPERATOR);
Expression rightOperand = operation.getRightOperand();
assertThat(rightOperand.getType()).isEqualTo(ExpressionConstants.CONTRACT_INPUT_TYPE);
assertThat(rightOperand.getName()).isEqualTo(CONTRACT_INPUT_NAME);
assertThat(rightOperand.getContent()).isEqualTo(CONTRACT_INPUT_NAME);
assertThat(rightOperand.getReturnType()).isEqualTo(input.getJavaType());
}
@Test
public void should_create_operation_for_multiple_document_without_data_ref() {
ContractInput input = ContractInputBuilder.aContractInput()
.withName(CONTRACT_INPUT_NAME)
.withType(ContractInputType.FILE)
.multiple()
.build();
Document document = new DocumentBuilder()
.multiple()
.withName(DOCUMENT_NAME)
.build();
Operation operation = new DocumentUpdateOperationBuilder(input, document).toOperation();
Expression leftOperand = operation.getLeftOperand();
assertThat(leftOperand.getType()).isEqualTo(ExpressionConstants.DOCUMENT_REF_TYPE);
assertThat(leftOperand.getName()).isEqualTo(DOCUMENT_NAME);
assertThat(leftOperand.getContent()).isEqualTo(DOCUMENT_NAME);
assertThat(leftOperand.getReturnType()).isEqualTo(List.class.getName());
assertThat(operation.getOperator().getType()).isEqualTo(ExpressionConstants.SET_LIST_DOCUMENT_OPERATOR);
Expression rightOperand = operation.getRightOperand();
assertThat(rightOperand.getType()).isEqualTo(ExpressionConstants.CONTRACT_INPUT_TYPE);
assertThat(rightOperand.getName()).isEqualTo(CONTRACT_INPUT_NAME);
assertThat(rightOperand.getContent()).isEqualTo(CONTRACT_INPUT_NAME);
assertThat(rightOperand.getReturnType()).isEqualTo(List.class.getName());
}
@Test
public void should_create_operation_for_multiple_document_with_data_ref() {
ContractInput input = ContractInputBuilder.aContractInput()
.withName(CONTRACT_INPUT_NAME)
.withType(ContractInputType.FILE)
.withDataReference(DOCUMENT_NAME)
.multiple()
.build();
Document document = new DocumentBuilder()
.multiple()
.withName(DOCUMENT_NAME)
.build();
DocumentUpdateOperationBuilder operationBuilder = new DocumentUpdateOperationBuilder(input, document);
Operation operation = operationBuilder.toOperation();
Expression leftOperand = operation.getLeftOperand();
assertThat(leftOperand.getType()).isEqualTo(ExpressionConstants.DOCUMENT_REF_TYPE);
assertThat(leftOperand.getName()).isEqualTo(DOCUMENT_NAME);
assertThat(leftOperand.getContent()).isEqualTo(DOCUMENT_NAME);
assertThat(leftOperand.getReturnType()).isEqualTo(List.class.getName());
assertThat(operation.getOperator().getType()).isEqualTo(ExpressionConstants.SET_LIST_DOCUMENT_OPERATOR);
Expression rightOperand = operation.getRightOperand();
assertThat(rightOperand.getType()).isEqualTo(ExpressionConstants.SCRIPT_TYPE);
assertThat(rightOperand.getName()).isEqualTo(String.format("update_%s", DOCUMENT_NAME));
assertThat(rightOperand.getReturnType()).isEqualTo(List.class.getName());
assertThat(rightOperand.getReferencedElements())
.filteredOn(Document.class::isInstance)
.extracting("name").containsExactly(DOCUMENT_NAME);
assertThat(rightOperand.getReferencedElements())
.filteredOn(ContractInput.class::isInstance)
.extracting("name").containsExactly(CONTRACT_INPUT_NAME);
assertThat(rightOperand.getReferencedElements())
.filteredOn(Expression.class::isInstance)
.extracting("name").containsExactly("apiAccessor");
String script = rightOperand.getContent();
assertThat(script).contains(DOCUMENT_NAME);
assertThat(script).contains(CONTRACT_INPUT_NAME);
}
}
/*******************************************************************************
* Copyright (C) 2019 BonitaSoft S.A.
* BonitaSoft is a trademark of BonitaSoft SA.
* This software file is BONITASOFT CONFIDENTIAL. Not For Distribution.
* For commercial licensing information, contact:
* BonitaSoft, 32 rue Gustave Eiffel – 38000 Grenoble
* or BonitaSoft US, 51 Federal Street, Suite 305, San Francisco, CA 94107
*******************************************************************************/
package org.bonitasoft.studio.contract.core.mapping.operation;
import org.bonitasoft.studio.common.ExpressionConstants;
import org.bonitasoft.studio.common.emf.tools.ExpressionHelper;
import org.bonitasoft.studio.document.core.export.DocumentGroovyScriptExpressionFactory;
import org.bonitasoft.studio.model.expression.Expression;
import org.bonitasoft.studio.model.expression.ExpressionFactory;
import org.bonitasoft.studio.model.expression.Operation;
import org.bonitasoft.studio.model.expression.Operator;
import org.bonitasoft.studio.model.process.ContractInput;
import org.bonitasoft.studio.model.process.Document;
public class DocumentUpdateOperationBuilder {
private ContractInput input;
private Document document;
public DocumentUpdateOperationBuilder(ContractInput input, Document document) {
this.input = input;
this.document = document;
}
public Operation toOperation() {
Operation operation = ExpressionFactory.eINSTANCE.createOperation();
Expression rightOperand = createRightOperand();
Expression leftOperand = ExpressionHelper.createDocumentReferenceExpression(document);
Operator operator = ExpressionFactory.eINSTANCE.createOperator();
if (document.isMultiple()) {
operator.setType(ExpressionConstants.SET_LIST_DOCUMENT_OPERATOR);
} else {
operator.setType(ExpressionConstants.SET_DOCUMENT_OPERATOR);
}
operation.setLeftOperand(leftOperand);
operation.setRightOperand(rightOperand);
operation.setOperator(operator);
return operation;
}
private Expression createRightOperand() {
if (document.isMultiple() && input.getDataReference() != null) {
return new DocumentGroovyScriptExpressionFactory().createUpdateDocumentListFromContractExpression(input,
document);
}
return ExpressionHelper.createExpressionFromEObject(input);
}
}
......@@ -23,8 +23,6 @@ import java.util.ArrayList;
import java.util.List;
import org.bonitasoft.studio.businessobject.core.repository.BusinessObjectModelRepositoryStore;
import org.bonitasoft.studio.common.ExpressionConstants;
import org.bonitasoft.studio.common.emf.tools.ExpressionHelper;
import org.bonitasoft.studio.common.emf.tools.ModelHelper;
import org.bonitasoft.studio.common.jface.BonitaErrorDialog;
import org.bonitasoft.studio.common.log.BonitaStudioLog;
......@@ -33,14 +31,12 @@ import org.bonitasoft.studio.contract.core.mapping.FieldToContractInputMapping;
import org.bonitasoft.studio.contract.core.mapping.FieldToContractInputMappingFactory;
import org.bonitasoft.studio.contract.core.mapping.RootContractInputGenerator;
import org.bonitasoft.studio.contract.core.mapping.expression.FieldToContractInputMappingExpressionBuilder;
import org.bonitasoft.studio.contract.core.mapping.operation.DocumentUpdateOperationBuilder;
import org.bonitasoft.studio.contract.core.mapping.operation.FieldToContractInputMappingOperationBuilder;
import org.bonitasoft.studio.contract.core.mapping.operation.OperationCreationException;
import org.bonitasoft.studio.contract.i18n.Messages;
import org.bonitasoft.studio.groovy.ui.viewer.GroovySourceViewerFactory;
import org.bonitasoft.studio.model.expression.Expression;
import org.bonitasoft.studio.model.expression.ExpressionFactory;
import org.bonitasoft.studio.model.expression.Operation;
import org.bonitasoft.studio.model.expression.Operator;
import org.bonitasoft.studio.model.process.AbstractProcess;
import org.bonitasoft.studio.model.process.BusinessObjectData;
import org.bonitasoft.studio.model.process.ContractContainer;
......@@ -284,20 +280,9 @@ public class ContractInputGenerationWizard extends Wizard {
return input;
}
private void createDocumentUpdateOperation(final Document document, final ContractInput input,
final CompoundCommand cc) {
final Operation operation = ExpressionFactory.eINSTANCE.createOperation();
final Expression rightOperand = ExpressionHelper.createExpressionFromEObject(input);
final Expression leftOperand = ExpressionHelper.createDocumentReferenceExpression(document);
final Operator operator = ExpressionFactory.eINSTANCE.createOperator();
if (document.isMultiple()) {
operator.setType(ExpressionConstants.SET_LIST_DOCUMENT_OPERATOR);
} else {
operator.setType(ExpressionConstants.SET_DOCUMENT_OPERATOR);
}
operation.setLeftOperand(leftOperand);
operation.setRightOperand(rightOperand);
operation.setOperator(operator);
private void createDocumentUpdateOperation(Document document, ContractInput input,
CompoundCommand cc) {
Operation operation = new DocumentUpdateOperationBuilder(input, document).toOperation();
cc.append(AddCommand.create(editingDomain, contractContainer,
ProcessPackage.Literals.OPERATION_CONTAINER__OPERATIONS, operation));
infoDialogFactory.openUpdateDocumentOperationWarning(document.getName(), getShell());
......
......@@ -32,7 +32,8 @@ Require-Bundle: org.eclipse.ui,
org.bonitasoft.studio.model.edit;bundle-version="6.4.0",
org.mockito;bundle-version="1.9.5";resolution:=optional,
org.eclipse.jdt.groovy.core;bundle-version="2.9.1",
org.bonitasoft.studio.engine
org.bonitasoft.studio.engine,
org.bonitasoft.studio.groovy
Bundle-Localization: plugin
Import-Package: org.bonitasoft.engine.bpm.bar,
org.bonitasoft.engine.bpm.contract,
......@@ -41,6 +42,7 @@ Import-Package: org.bonitasoft.engine.bpm.bar,
org.bonitasoft.engine.expression,
org.bonitasoft.studio.common
Export-Package: org.bonitasoft.studio.document,
org.bonitasoft.studio.document.core.export,
org.bonitasoft.studio.document.core.expression,
org.bonitasoft.studio.document.core.repository,
org.bonitasoft.studio.document.i18n,
......
......@@ -23,8 +23,11 @@ import java.util.List;
import org.bonitasoft.engine.bpm.contract.FileInputValue;
import org.bonitasoft.studio.common.emf.tools.ExpressionHelper;
import org.bonitasoft.studio.groovy.GroovyUtil;
import org.bonitasoft.studio.model.expression.Expression;
import org.bonitasoft.studio.model.process.ContractInput;
import org.bonitasoft.studio.model.process.Document;
import org.eclipse.emf.ecore.util.EcoreUtil;
import com.google.common.base.Joiner;
......@@ -73,4 +76,63 @@ public class DocumentGroovyScriptExpressionFactory {
return root;
}
public Expression createUpdateDocumentListFromContractExpression(ContractInput input, Document document) {
String script = createMergeDocumentScript(input);
String scriptName = String.format("update_%s", input.getDataReference());
Expression expression = ExpressionHelper.createGroovyScriptExpression(script, List.class.getName(), scriptName);
expression.getReferencedElements().add(EcoreUtil.copy(input));
expression.getReferencedElements().add(EcoreUtil.copy(document));
expression.getReferencedElements().add(EcoreUtil.copy(GroovyUtil.getEngineConstantExpression("apiAccessor")));
return expression;
}
private String createMergeDocumentScript(ContractInput input) {
StringBuilder scriptBuilder = new StringBuilder();
appendImport(scriptBuilder);
initVariables(scriptBuilder);
addExistingDocuments(scriptBuilder, input);
addNewDocuments(scriptBuilder, input);
addReturnStatement(scriptBuilder);
return scriptBuilder.toString();
}
private void appendImport(StringBuilder scriptBuilder) {
appendLine(scriptBuilder, "import org.bonitasoft.engine.api.ProcessAPI");
appendLine(scriptBuilder, "import org.bonitasoft.engine.bpm.document.DocumentValue");
appendLine(scriptBuilder, "");
}
private void initVariables(StringBuilder scriptBuilder) {
appendLine(scriptBuilder, "def filesOutput = []");
appendLine(scriptBuilder, "def pAPI = apiAccessor.getProcessAPI()");
appendLine(scriptBuilder, "");
}
private void addExistingDocuments(StringBuilder scriptBuilder, ContractInput input) {
appendLine(scriptBuilder, String.format("if (%s) {", input.getDataReference()));
appendLine(scriptBuilder, String.format(" %s", input.getDataReference()));
appendLine(scriptBuilder,
" .collect { doc -> new DocumentValue(pAPI.getDocumentContent(doc.getContentStorageId()),doc.getContentMimeType(), doc.getContentFileName()) }");
appendLine(scriptBuilder, " .each (filesOutput.&add)");
appendLine(scriptBuilder, "}");
appendLine(scriptBuilder, "");
}
private void addNewDocuments(StringBuilder scriptBuilder, ContractInput input) {
appendLine(scriptBuilder, String.format("if (%s) {", input.getName()));
appendLine(scriptBuilder, String.format(" %s", input.getName()));
appendLine(scriptBuilder, " .collect { doc -> new DocumentValue(doc.content,doc.contentType, doc.fileName)}");
appendLine(scriptBuilder, " .each (filesOutput.&add)");
appendLine(scriptBuilder, "}");
appendLine(scriptBuilder, "");
}
private void addReturnStatement(StringBuilder scriptBuilder) {
scriptBuilder.append("filesOutput");
}
private void appendLine(StringBuilder scriptBuilder, String content) {
scriptBuilder.append(content + "\n");
}
}
......@@ -14,7 +14,7 @@
<tychoExtrasVersion>1.3.0</tychoExtrasVersion>
<os-jvm-flags></os-jvm-flags>
<bundle.version>${project.version}</bundle.version>
<ui.designer.version>1.9.15</ui.designer.version>
<ui.designer.version>1.9.16</ui.designer.version>
<engine.version>${project.version}</engine.version>
<filters.version>${project.version}</filters.version>
<platform.version>${project.parent.version}</platform.version>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment