/** * Copyright (C) 2012 BonitaSoft S.A. * BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2.0 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.bonitasoft.test.toolkit.bpm; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.UUID; import org.apache.commons.io.IOUtils; import org.bonitasoft.engine.bpm.bar.BarResource; import org.bonitasoft.engine.bpm.bar.BusinessArchiveBuilder; import org.bonitasoft.engine.bpm.process.InvalidProcessDefinitionException; import org.bonitasoft.engine.bpm.process.ProcessActivationException; import org.bonitasoft.engine.bpm.process.ProcessDefinition; import org.bonitasoft.engine.bpm.process.impl.ProcessDefinitionBuilder; import org.bonitasoft.engine.expression.Expression; import org.bonitasoft.engine.expression.ExpressionBuilder; import org.bonitasoft.engine.expression.ExpressionType; import org.bonitasoft.engine.expression.InvalidExpressionException; import org.bonitasoft.test.toolkit.bpm.process.TestProcessConnector; import org.bonitasoft.test.toolkit.exception.TestToolkitException; import org.bonitasoft.test.toolkit.organization.TestUser; /** * @author Vincent Elcrin */ public class TestProcessFactory { public static final String CONTRACT_RULE_EXPLANATION = "explanation"; public static final String CONTRACT_RULE_EXPRESSION = " 1 == 1 "; public static final String CONTRACT_RULE_NAME = "ruleName"; public static final String CONTRACT_INPUT_DESCRIPTION = "description"; public static final String CONTRACT_INPUT_TYPE = String.class.getName(); public static final String CONTRACT_INPUT_NAME = "inputName"; protected static final String DEFAULT_HUMAN_TASK_PROCESS_NAME = "Default human task process"; protected static final String PROCESS_WITH_DOCUMENT_ATTACHED = "Process with document attached"; protected static final String PROCESS_MISCONFIGURED = "Process misconfigured"; protected static final String PROCESS_CALL_ACTIVTY = "Process call activity"; private final Map<String, TestProcess> processList; private static TestProcessFactory instance; /** * Default Constructor. */ public TestProcessFactory() { processList = new HashMap<String, TestProcess>(); } public static TestProcessFactory getInstance() { if (instance == null) { instance = new TestProcessFactory(); } return instance; } private static String getRandomString() { return String.valueOf(new Random().nextLong()); } public void clear() throws Exception { for (TestProcess testProcess : processList.values()) { clear(testProcess); } processList.clear(); } /** * @return the processList */ protected Map<String, TestProcess> getProcessList() { return processList; } // /////////////////////////////////////////////////////////////////////////////////// // / Process definitions // /////////////////////////////////////////////////////////////////////////////////// protected static ProcessDefinitionBuilder getDefaultProcessDefinitionBuilder(final String processName) { return getDefaultProcessDefinitionBuilder(processName, "1.0"); } public static ProcessDefinitionBuilder getDefaultProcessDefinitionBuilder(final String processName, final String version) { final ProcessDefinitionBuilder processDefinitionBuidler = new ProcessDefinitionBuilder().createNewInstance(processName, version); processDefinitionBuidler.addActor("Employees", true) .addDescription("This a default process") .addStartEvent("Start") .addUserTask("Activity 1", "Employees") .addEndEvent("Finish"); return processDefinitionBuidler; } protected static ProcessDefinitionBuilder getMisconfiguredProcessDefinitionBuilder(final String processName) { final ProcessDefinitionBuilder processDefinitionBuidler = new ProcessDefinitionBuilder().createNewInstance(processName, "1.0"); try { processDefinitionBuidler.addActor("Employees", true) .addDescription("This a default process") .addStartEvent("Start") .addUserTask("Activity 1", "Employees") .addData("FailedData", "FailedClassName", new ExpressionBuilder().createInputExpression("input", Boolean.class.getName())) .addEndEvent("Finish"); } catch (final InvalidExpressionException e) { throw new TestToolkitException("Invalid expression definition", e); } return processDefinitionBuidler; } protected static BusinessArchiveBuilder getBusinessArchiveWithDocumentBuilder(final String processName) { final ProcessDefinitionBuilder processDefinitionBuidler = new ProcessDefinitionBuilder().createNewInstance(processName, "1.0"); processDefinitionBuidler.addDocumentDefinition("Document 1667").addContentFileName("filename.txt").addFile("attachedfile.txt"); processDefinitionBuidler.addActor("Employees", true) .addStartEvent("Start") .addUserTask("Activity 1", "Employees") .addEndEvent("Finish"); try { return new BusinessArchiveBuilder().createNewBusinessArchive() .setFormMappings(TestProcess.createDefaultProcessFormMapping(processDefinitionBuidler.getProcess())) .addDocumentResource(new BarResource("attachedfile.txt", "thisisthecontentofthedocumentattached".getBytes())) .setProcessDefinition(processDefinitionBuidler.done()); } catch (final InvalidProcessDefinitionException e) { throw new TestToolkitException("Invalid process definition", e); } } /** * @param processCallActivty * @return */ private static ProcessDefinitionBuilder getCallActivityProcessDefinitionBuilder(final ProcessDefinition processToStartViaCallActivity) { Expression expressionName = null; Expression expressionVersion = null; try { expressionName = new ExpressionBuilder().createNewInstance("process name") .setExpressionType(ExpressionType.TYPE_CONSTANT) .setReturnType(String.class.getName()) .setContent(processToStartViaCallActivity.getName()).done(); expressionVersion = new ExpressionBuilder().createNewInstance("process version") .setExpressionType(ExpressionType.TYPE_CONSTANT) .setReturnType(String.class.getName()) .setContent(processToStartViaCallActivity.getVersion()).done(); } catch (final InvalidExpressionException e) { throw new TestToolkitException("Invalid expression definition", e); } final ProcessDefinitionBuilder processDefinitionBuidler = new ProcessDefinitionBuilder() .createNewInstance(PROCESS_CALL_ACTIVTY, "1.0"); processDefinitionBuidler.addActor("Employees", true) .addStartEvent("Start") .addCallActivity("Call Activity", expressionName, expressionVersion) .addEndEvent("Finish"); return processDefinitionBuidler; } // ////////////////////////////////////////////////////////////////////////////////// // / Factory accessors // ////////////////////////////////////////////////////////////////////////////////// public static TestProcess createRandomResolvedProcess(final TestUser actor) { return getRandomHumanTaskProcess().addActor(actor); } /** * Variables : * - variable1 : String * - variable2 : Long * - variable3 : Date * @param initiator */ public static TestHumanTask createActivityWithVariables(TestUser initiator) throws InvalidExpressionException { final String processName = "processName"; final ProcessDefinitionBuilder processDefinitionBuidler = new ProcessDefinitionBuilder().createNewInstance(processName+(String.valueOf(UUID.randomUUID().getLeastSignificantBits()).substring(0,5)), "1.0"); processDefinitionBuidler.addActor("Employees", true) .addDescription("This a default process") .addStartEvent("Start") .addUserTask("Activity 1", "Employees") .addData("variable1", String.class.getName(), new ExpressionBuilder().createConstantStringExpression("defaultValue")) .addData("variable2", Long.class.getName(), new ExpressionBuilder().createConstantLongExpression(1)) .addData("variable3", Date.class.getName(), new ExpressionBuilder().createConstantDateExpression("428558400000")) .addEndEvent("Finish"); final TestProcess testProcess = new TestProcess(processDefinitionBuidler); getInstance().getProcessList().put(processName, testProcess); return testProcess.addActor(initiator).setEnable(true).startCase().getNextHumanTask().assignTo(initiator); } /** * This process contains only a human task * * @return */ public static TestProcess getDefaultHumanTaskProcess() { return getHumanTaskProcess(DEFAULT_HUMAN_TASK_PROCESS_NAME); } public static TestProcess createProcessWithConnector(final TestProcessConnector testConnector) { final String aProcessWithConnector = "aProcessWithConnector"; final ProcessDefinitionBuilder processBuilder = getDefaultProcessDefinitionBuilder(aProcessWithConnector); processBuilder.addConnector(testConnector.getName(), testConnector.getId(), testConnector.getVersion(), testConnector.getConnectorEvent()); try { final InputStream stream = TestProcessFactory.class.getResourceAsStream(testConnector.getResourceFilePath()); final BarResource connectorResource = new BarResource(testConnector.getResourceFileName(), IOUtils.toByteArray(stream)); stream.close(); final BusinessArchiveBuilder barBuilder = new BusinessArchiveBuilder().createNewBusinessArchive().setProcessDefinition(processBuilder.done()); barBuilder.addConnectorImplementation(connectorResource); final TestProcess testProcess = new TestProcess(barBuilder); getInstance().getProcessList().put(aProcessWithConnector, testProcess); return testProcess; } catch (final Exception e) { throw new TestToolkitException("Unable to create a process with connector", e); } } public static List<TestProcess> getHumanTaskProcesses(final int count) { final List<TestProcess> results = new ArrayList<TestProcess>(count); for (int i = 0; i < count; i++) { results.add(getHumanTaskProcess(getRandomString())); } return results; } public static TestProcess getProcessWithDocumentAttached() { if (getInstance().getProcessList().get(PROCESS_WITH_DOCUMENT_ATTACHED) == null) { final TestProcess testProcess = new TestProcess(getBusinessArchiveWithDocumentBuilder(PROCESS_WITH_DOCUMENT_ATTACHED)); getInstance().getProcessList().put(PROCESS_WITH_DOCUMENT_ATTACHED, testProcess); } return getInstance().getProcessList().get(PROCESS_WITH_DOCUMENT_ATTACHED); } public static TestProcess createProcessWith3Actors() { final String processWith3Actors = "processWith3Actors"; final ProcessDefinitionBuilder builder = getDefaultProcessDefinitionBuilder(processWith3Actors); builder.addActor("actor2").addDescription("description actor2").addActor("actor3").addDescription("description actor3"); final TestProcess testProcess = new TestProcess(builder); getInstance().getProcessList().put(processWith3Actors, testProcess); return testProcess; } public static TestProcess createProcessWithVariables(final String processName, final ProcessVariable... variables) { final ProcessDefinitionBuilder builder = getDefaultProcessDefinitionBuilder(processName); for (final ProcessVariable variable : variables) { builder.addData(variable.getName(), variable.getClassName(), variable.getDefaultValue()); } final TestProcess testProcess = new TestProcess(builder); getInstance().getProcessList().put(processName, testProcess); return testProcess; } public static TestProcess getRandomHumanTaskProcess() { return getHumanTaskProcess(getRandomString()); } /** * This process contains only a human task * * @return */ public static TestProcess getHumanTaskProcess(final String processName, final String version) { if (getInstance().getProcessList().get(processName) == null) { final TestProcess testProcess = new TestProcess(getDefaultProcessDefinitionBuilder(processName, version)); getInstance().getProcessList().put(processName, testProcess); } return getInstance().getProcessList().get(processName); } /** * This process contains only a human task * * @return */ public static TestProcess getHumanTaskProcess(final String processName) { if (getInstance().getProcessList().get(processName) == null) { final TestProcess testProcess = new TestProcess(getDefaultProcessDefinitionBuilder(processName)); getInstance().getProcessList().put(processName, testProcess); } return getInstance().getProcessList().get(processName); } /** * This process contains only a human task * * @return */ public static TestProcess getMisconfiguredProcess() { if (getInstance().getProcessList().get(PROCESS_MISCONFIGURED) == null) { final TestProcess testProcess = new TestProcess(getMisconfiguredProcessDefinitionBuilder(PROCESS_MISCONFIGURED)); getInstance().getProcessList().put(PROCESS_MISCONFIGURED, testProcess); } return getInstance().getProcessList().get(PROCESS_MISCONFIGURED); } /** * This process contains a call activity * * @return */ public static TestProcess getCallActivityProcess(final ProcessDefinition processToStartViaCallActivity) { if (getInstance().getProcessList().get(PROCESS_CALL_ACTIVTY) == null) { final TestProcess testProcess = new TestProcess(getCallActivityProcessDefinitionBuilder(processToStartViaCallActivity)); getInstance().getProcessList().put(PROCESS_CALL_ACTIVTY, testProcess); } return getInstance().getProcessList().get(PROCESS_CALL_ACTIVTY); } public void check() { if (!getProcessList().isEmpty()) { throw new RuntimeException(this.getClass().getName() + " cannot be reset because the list is not empty: " + getProcessList()); } } private void clear(TestProcess testProcess) throws Exception { testProcess.deleteCases(); try { testProcess.disable(); } catch (TestToolkitException e) { if (!(e.getCause() instanceof ProcessActivationException)) { throw e; } //ignore as the process can be disabled } testProcess.delete(); } public void delete(TestProcess testProcess) throws Exception { clear(testProcess); getProcessList().remove(testProcess.getProcessDefinition().getName()); } public void remove(TestProcess testProcess) { getProcessList().remove(testProcess.getProcessDefinition().getName()); } public void add(TestProcess testProcess) { getProcessList().put(testProcess.getProcessDefinition().getName(), testProcess); } }