diff --git a/config/alfresco/form-services-context.xml b/config/alfresco/form-services-context.xml
index f477d3c37e..9e5ba3340f 100644
--- a/config/alfresco/form-services-context.xml
+++ b/config/alfresco/form-services-context.xml
@@ -109,6 +109,22 @@
ref="nodeFilterRegistry" />
-->
+
+
+
+ ${system.workflow.jbpm.comment.property.max.length}
+
+
+
+
+
+
+ ${system.workflow.jbpm.comment.property.max.length}
+
+
+
diff --git a/config/alfresco/model/bpmModel.xml b/config/alfresco/model/bpmModel.xml
index 4eaa018e66..d8fec9e32b 100644
--- a/config/alfresco/model/bpmModel.xml
+++ b/config/alfresco/model/bpmModel.xml
@@ -64,6 +64,15 @@
+
+
+ 0
+
+
+ 4000
+
+
+
@@ -169,6 +178,9 @@
d:text
+
+
+
diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index b1cbf7a3e3..f671759f27 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -70,6 +70,8 @@ system.workflow.jbpm.config.location=classpath:org/alfresco/repo/workflow/jbpm/j
# any in-flight JBPM workflows to be completed.
system.workflow.engine.jbpm.definitions.visible=false
+system.workflow.jbpm.comment.property.max.length=4000
+
#Determines if Activiti definitions are visible
system.workflow.engine.activiti.definitions.visible=true
diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/WorkflowFormFilter.java b/source/java/org/alfresco/repo/forms/processor/workflow/WorkflowFormFilter.java
new file mode 100644
index 0000000000..b48fe57e8e
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/workflow/WorkflowFormFilter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2005-2014 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.repo.forms.processor.workflow;
+
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.repo.forms.Form;
+import org.alfresco.repo.forms.FormData;
+import org.alfresco.repo.forms.FormData.FieldData;
+import org.alfresco.repo.forms.processor.AbstractFilter;
+import org.alfresco.repo.workflow.PropertyValueSizeIsMoreMaxLengthException;
+
+public class WorkflowFormFilter extends AbstractFilter
+{
+
+ private static final String PROP_BPM_COMMENT = "prop_bpm_comment";
+
+ private int maxLengthBpmCommentProperty = 4000;
+
+ public void setMaxLengthBpmCommentProperty(int maxLengthBpmCommentProperty)
+ {
+ this.maxLengthBpmCommentProperty = maxLengthBpmCommentProperty;
+ }
+
+ @Override
+ public void beforeGenerate(ItemType item, List fields, List forcedFields, Form form, Map context)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void afterGenerate(ItemType item, List fields, List forcedFields, Form form, Map context)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void beforePersist(ItemType item, FormData data)
+ {
+ FieldData bpmComment = data.getFieldData(PROP_BPM_COMMENT);
+ if (bpmComment != null)
+ {
+ int value = ((String) bpmComment.getValue()).getBytes().length;
+
+ if (maxLengthBpmCommentProperty < value)
+ {
+ throw new PropertyValueSizeIsMoreMaxLengthException(PROP_BPM_COMMENT);
+ }
+ }
+
+ }
+
+ @Override
+ public void afterPersist(ItemType item, FormData data, PersistType persistedObject)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/workflow/PropertyValueSizeIsMoreMaxLengthException.java b/source/java/org/alfresco/repo/workflow/PropertyValueSizeIsMoreMaxLengthException.java
new file mode 100644
index 0000000000..34f6a0852f
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/PropertyValueSizeIsMoreMaxLengthException.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005-2014 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.workflow;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.service.namespace.QName;
+
+public class PropertyValueSizeIsMoreMaxLengthException extends AlfrescoRuntimeException
+{
+ private static final long serialVersionUID = 5722742734237891185L;
+
+ public PropertyValueSizeIsMoreMaxLengthException(QName name)
+ {
+ super("Property '" + name.getLocalName() + "' has size more than max value.");
+ }
+
+ public PropertyValueSizeIsMoreMaxLengthException(String name)
+ {
+ super("Property '" + name + "' has size more than max value.");
+ }
+}
\ No newline at end of file
diff --git a/source/test-java/org/alfresco/repo/forms/processor/workflow/FormProcessorTest.java b/source/test-java/org/alfresco/repo/forms/processor/workflow/FormProcessorTest.java
new file mode 100644
index 0000000000..62ce10899d
--- /dev/null
+++ b/source/test-java/org/alfresco/repo/forms/processor/workflow/FormProcessorTest.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2005-2014 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.repo.forms.processor.workflow;
+
+import static org.alfresco.repo.forms.processor.node.FormFieldConstants.*;
+import static org.alfresco.repo.workflow.WorkflowModel.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.alfresco.repo.forms.FieldDefinition;
+import org.alfresco.repo.forms.Form;
+import org.alfresco.repo.forms.FormData;
+import org.alfresco.repo.forms.FormData.FieldData;
+import org.alfresco.repo.forms.Item;
+import org.alfresco.repo.forms.processor.FilterRegistry;
+import org.alfresco.repo.forms.processor.node.DefaultFieldProcessor;
+import org.alfresco.repo.forms.processor.node.MockClassAttributeDefinition;
+import org.alfresco.repo.forms.processor.node.MockFieldProcessorRegistry;
+import org.alfresco.repo.policy.BehaviourFilter;
+import org.alfresco.service.cmr.dictionary.AssociationDefinition;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.QNamePattern;
+
+import junit.framework.TestCase;
+
+public class FormProcessorTest extends TestCase
+{
+ protected static final String TASK_DEF_NAME = "TaskDef";
+ protected static final QName DESC_NAME = PROP_DESCRIPTION;
+ protected static final QName STATUS_NAME = PROP_STATUS;
+ protected static final QName PROP_WITH_ = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "some_prop");
+ protected static final QName ACTORS_NAME = ASSOC_POOLED_ACTORS;
+ protected static final QName ASSIGNEE_NAME = ASSOC_ASSIGNEE;
+ protected static final QName ASSOC_WITH_ = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "some_assoc");
+ protected static final NodeRef FAKE_NODE = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode");
+ protected static final NodeRef FAKE_NODE2 = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode2");
+ protected static final NodeRef FAKE_NODE3 = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode3");
+ protected static final NodeRef PCKG_NODE = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakePackage");
+
+ protected WorkflowService workflowService;
+ protected NodeService nodeService;
+ protected NamespaceService namespaceService;
+ protected AbstractWorkflowFormProcessor processor;
+ protected Item item;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ protected DefaultFieldProcessor makeDefaultFieldProcessor(DictionaryService dictionaryService) throws Exception
+ {
+ DefaultFieldProcessor defaultProcessor = new DefaultFieldProcessor();
+ defaultProcessor.setDictionaryService(dictionaryService);
+ defaultProcessor.setNamespaceService(namespaceService);
+ defaultProcessor.afterPropertiesSet();
+ return defaultProcessor;
+ }
+
+ public void testPersistPropertyComment(String taskId) throws Exception
+ {
+ // MNT-11809 Activiti losses data with large Aspect or Type property values
+ // wiki Hamlet text
+ StringBuilder wikiHamlet = new StringBuilder();
+ wikiHamlet.append("Hamlet is the son of the King of Denmark. When Hamlet`s father dies, his uncle Claudius becomes king and marries Hamlet`s mother (Gertrude).");
+ wikiHamlet.append("Hamlet`s father appears as a ghost and tells Hamlet that he was murdered by Claudius. Hamlet is not sure that the ghost is really his father.");
+ wikiHamlet.append("He gets some travelling actors to perform a play which shows the murder of a king in the same way Hamlet`s father said he was killed.");
+ wikiHamlet.append("When Claudius reacts badly to seeing this, Hamlet believes he is guilty.");
+ wikiHamlet.append("Hamlet tells his mother that he knows about the murder. While there he kills Polonius, who is the king`s advisor, because he thinks he is Claudius.");
+ wikiHamlet.append("Rosencrantz and Guildenstern were Hamlet`s childhood friends.");
+ wikiHamlet
+ .append("Claudius sends Rosencrantz and Guildenstern with Hamlet to England to have Hamlet killed, but their ship is attacked by pirates who take Hamlet prisoner but then return him to Denmark.");
+ wikiHamlet
+ .append("Rosencrantz and Guildenstern are taken to England where they die. Ophelia is Polonius` daughter . After her father, Polonius, is killed by Hamlet she goes mad.");
+ wikiHamlet.append("Then she falls into a river and drowns. Hamlet returns just as her funeral is happening. Laertes, her brother, decides to kill Hamlet in revenge.");
+ wikiHamlet
+ .append("He challenges Hamlet to a sword fight, and puts poison on his own sword. Claudius makes some poisoned wine for Hamlet to drink in case that does not work.");
+ wikiHamlet.append("At first Hamlet wins the sword fight, and in the meantime his mother drinks the poisoned wine without knowing, and dies.");
+ wikiHamlet
+ .append("On the other hand Laertes falsely pierces Hamlet with a poisoned blade, but then Hamlet stabs Laertes with the same sword. Laertes tells Hamlet about the plot and then dies.");
+ wikiHamlet.append("Hamlet kills Claudius with the poisoned sword. Horatio, Hamlet`s friend, tells everyone about the murder of the old king.");
+ wikiHamlet.append("Hamlet tells everyone that the Norwegian prince, Fortinbras, should be king, and then dies from the poison.");
+ wikiHamlet.append("When Fortinbras arrives, Horatio recounts the tale and Fortinbras orders Hamlet`s body borne off in honour.");
+ wikiHamlet.append("Hamlet is one of the hardest parts for an actor to perform. It is one of the largest roles written by Shakespeare.");
+ wikiHamlet.append("Many people disagree about what Hamlet is really thinking. For many actors, playing Hamlet is one of the most important parts of their career.");
+
+ // Get max length of jbpm_comment property from repository.properties
+ String maxLength = "4000";
+
+ String dir = System.getProperty("user.dir");
+ File propFile = new File(dir + File.separator + "config" + File.separator + "alfresco" + File.separator + "repository.properties");
+
+ if (propFile.exists())
+ {
+ InputStream propStream = null;
+ try
+ {
+ propStream = new FileInputStream(propFile);
+ Properties properties = new Properties();
+ properties.load(propStream);
+
+ maxLength = properties.getProperty("system.workflow.jbpm.comment.property.max.length");
+ }
+ finally
+ {
+ if (propStream != null)
+ {
+ propStream.close();
+ }
+ }
+ }
+
+ // Convert value of property to int
+ int maxLengthPropery;
+ try
+ {
+ maxLengthPropery = Integer.valueOf(maxLength);
+ }
+ catch (NumberFormatException e)
+ {
+ maxLengthPropery = 4000;
+ }
+
+ FormData data = new FormData();
+ boolean repeatTest = true;
+ String test = wikiHamlet.toString();
+ Item item = new Item("task", taskId);
+
+ while (repeatTest)
+ {
+ data.addFieldData("prop_bpm_comment", test);
+
+ int value = test.getBytes().length;
+
+ try
+ {
+ processor.persist(item, data);
+
+ assertTrue("Value is " + value, value < maxLengthPropery);
+ }
+ catch (Exception e)
+ {
+ assertTrue("Caught Exception, value is " + value, value > maxLengthPropery);
+ }
+
+ if (value < maxLengthPropery)
+ {
+ test += wikiHamlet.toString();
+ }
+ else
+ {
+ repeatTest = false;
+ }
+ }
+ }
+
+ protected AbstractWorkflowFormProcessor makeTaskFormProcessor(AbstractWorkflowFormProcessor processor1, DictionaryService dictionaryService,
+ MockFieldProcessorRegistry fieldProcessorRegistry, DefaultFieldProcessor defaultProcessor)
+ {
+ processor1.setWorkflowService(workflowService);
+ processor1.setNodeService(nodeService);
+ processor1.setNamespaceService(namespaceService);
+ processor1.setDictionaryService(dictionaryService);
+ processor1.setFieldProcessorRegistry(fieldProcessorRegistry);
+ processor1.setBehaviourFilter(mock(BehaviourFilter.class));
+ // MNT-11809 Activiti losses data with large Aspect or Type property values
+ FilterRegistry filterRegistry = new FilterRegistry();
+ filterRegistry.addFilter(new WorkflowFormFilter());
+ processor1.setFilterRegistry(filterRegistry);
+ return processor1;
+ }
+
+ protected void mockPackageItems(NodeRef... children)
+ {
+ ArrayList results = new ArrayList(children.length);
+ for (NodeRef nodeRef : children)
+ {
+ ChildAssociationRef child = new ChildAssociationRef(ASSOC_PACKAGE_CONTAINS, PCKG_NODE, null, nodeRef);
+ results.add(child);
+ }
+ when(nodeService.getChildAssocs(eq(PCKG_NODE), (QNamePattern) any(), (QNamePattern) any())).thenReturn(results);
+
+ }
+
+ protected void checkRemovedPackageItem(NodeRef child, boolean wasCalled)
+ {
+ int times = wasCalled ? 1 : 0;
+ verify(nodeService, times(times)).removeChild(PCKG_NODE, child);
+ }
+
+ protected void checkAddPackageItem(NodeRef child, boolean wasCalled)
+ {
+ int times = wasCalled ? 1 : 0;
+ verify(nodeService, times(times)).addChild(eq(PCKG_NODE), eq(child), eq(ASSOC_PACKAGE_CONTAINS), (QName) any());
+ }
+
+ protected void checkSingleProperty(Form form, String fieldName, Serializable fieldData)
+ {
+ String expDataKey = makeDataKeyName(fieldName);
+ checkSingleField(form, fieldName, fieldData, expDataKey);
+ }
+
+ protected void checkSingleAssociation(Form form, String fieldName, Serializable fieldData)
+ {
+ String expDataKey = makeAssociationDataKey(fieldName);
+ checkSingleField(form, fieldName, fieldData, expDataKey);
+ }
+
+ protected void checkSingleField(Form form, String fieldName, Serializable fieldData, String expDataKey)
+ {
+ List fieldDefs = form.getFieldDefinitions();
+ assertEquals(1, fieldDefs.size());
+ FieldDefinition fieldDef = fieldDefs.get(0);
+ assertEquals(fieldName, fieldDef.getName());
+ String dataKey = fieldDef.getDataKeyName();
+ assertEquals(expDataKey, dataKey);
+ FieldData data = form.getFormData().getFieldData(dataKey);
+ if (fieldData != null && data != null)
+ {
+ assertEquals(fieldData, data.getValue());
+ }
+ else
+ {
+ assertNull(data);
+ }
+ }
+
+ protected String makeDataKeyName(String fieldName)
+ {
+ return PROP_DATA_PREFIX + fieldName.replace(":", "_");
+ }
+
+ protected String makeDataKeyName(String fieldName, boolean added)
+ {
+ String assocDataKey = makeAssociationDataKey(fieldName);
+ String suffix = added ? ASSOC_DATA_ADDED_SUFFIX : ASSOC_DATA_REMOVED_SUFFIX;
+ return assocDataKey + suffix;
+ }
+
+ protected String makeAssociationDataKey(String fieldName)
+ {
+ return ASSOC_DATA_PREFIX + fieldName.replace(":", "_");
+ }
+
+ protected Map makeTaskAssociationDefs()
+ {
+ Map associations = new HashMap();
+ QName actorName = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "Actor");
+
+ // Add Assigneee association
+ MockClassAttributeDefinition assigneeDef = MockClassAttributeDefinition.mockAssociationDefinition(ASSIGNEE_NAME, actorName);
+ associations.put(ASSIGNEE_NAME, assigneeDef);
+
+ // Add Assigneee association
+ MockClassAttributeDefinition actorsDef = MockClassAttributeDefinition.mockAssociationDefinition(ACTORS_NAME, actorName);
+ associations.put(ACTORS_NAME, actorsDef);
+
+ // Add association with _
+ MockClassAttributeDefinition with_ = MockClassAttributeDefinition.mockAssociationDefinition(ASSOC_WITH_, actorName);
+ associations.put(ASSOC_WITH_, with_);
+
+ return associations;
+ }
+
+}
diff --git a/source/test-java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java b/source/test-java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java
index d1a1c8b3b6..bff72d5726 100644
--- a/source/test-java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java
+++ b/source/test-java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2010 Alfresco Software Limited.
+ * Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -19,13 +19,11 @@
package org.alfresco.repo.forms.processor.workflow;
-import static org.alfresco.repo.forms.processor.node.FormFieldConstants.*;
import static org.alfresco.repo.workflow.WorkflowModel.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -33,10 +31,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
-
import org.alfresco.model.ContentModel;
-import org.alfresco.repo.forms.FieldDefinition;
import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData;
import org.alfresco.repo.forms.FormNotFoundException;
@@ -45,13 +40,11 @@ import org.alfresco.repo.forms.FormData.FieldData;
import org.alfresco.repo.forms.processor.node.DefaultFieldProcessor;
import org.alfresco.repo.forms.processor.node.MockClassAttributeDefinition;
import org.alfresco.repo.forms.processor.node.MockFieldProcessorRegistry;
-import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
-import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
@@ -68,7 +61,6 @@ import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.NamespaceServiceMemoryImpl;
import org.alfresco.service.namespace.QName;
-import org.alfresco.service.namespace.QNamePattern;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -78,28 +70,13 @@ import org.mockito.stubbing.Answer;
* @author Nick Smith
*
*/
-public class TaskFormProcessorTest extends TestCase
+public class TaskFormProcessorTest extends FormProcessorTest
{
- private static final String TASK_DEF_NAME = "TaskDef";
private static final String TASK_ID = "foo$Real Id";
- private static final QName DESC_NAME = PROP_DESCRIPTION;
- private static final QName STATUS_NAME = PROP_STATUS;
- private static final QName PROP_WITH_ = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "some_prop");
- private static final QName ACTORS_NAME = ASSOC_POOLED_ACTORS;
- private static final QName ASSIGNEE_NAME = ASSOC_ASSIGNEE;
- private static final QName ASSOC_WITH_ = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "some_assoc");
- private static final NodeRef FAKE_NODE = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode");
- private static final NodeRef FAKE_NODE2 = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode2");
- private static final NodeRef FAKE_NODE3 = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode3");
- private static final NodeRef PCKG_NODE = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakePackage");
private static final NodeRef USER_NODE = new NodeRef(NamespaceService.CONTENT_MODEL_1_0_URI + "/admin");
private static final String NO_MESSAGE = "(No Message)";
- private WorkflowService workflowService;
- private NodeService nodeService;
- private TaskFormProcessor processor;
private WorkflowTask task;
- private NamespaceService namespaceService;
private AuthenticationService authenticationService;
private PersonService personService;
private WorkflowTask newTask;
@@ -129,22 +106,19 @@ public class TaskFormProcessorTest extends TestCase
// Do nothing!
}
- Item item = new Item("task", TASK_ID);
- WorkflowTask result = processor.getTypedItem(item);
+ WorkflowTask result = ((TaskFormProcessor) processor).getTypedItem(item);
assertNotNull(result);
assertEquals(TASK_ID, result.getId());
// Check URI-encoded id.
- item = new Item("task", TASK_ID);
- result = processor.getTypedItem(item);
+ result = ((TaskFormProcessor) processor).getTypedItem(item);
assertNotNull(result);
assertEquals(TASK_ID, result.getId());
}
public void testGenerateSetsItemAndUrl() throws Exception
{
- Item item = new Item("task", TASK_ID);
- Form form = processor.generate(item, null, null, null);
+ Form form = ((TaskFormProcessor) processor).generate(item, null, null, null);
Item formItem = form.getItem();
assertEquals(item.getId(), formItem.getId());
assertEquals(item.getKind(), formItem.getKind());
@@ -412,7 +386,6 @@ public class TaskFormProcessorTest extends TestCase
data.addFieldData("prop_bpm_foo", "bar");
String dataKey = makeDataKeyName(TransitionFieldProcessor.KEY);
data.addFieldData(dataKey, "foo");
- Item item = new Item("task", TASK_ID);
WorkflowTask persistedItem = (WorkflowTask) processor.persist(item, data);
// make sure task is correct and update and endTask were called
@@ -421,6 +394,11 @@ public class TaskFormProcessorTest extends TestCase
verify(workflowService, times(1)).endTask(TASK_ID, "foo");
}
+ public void testPersistPropertyComment() throws Exception
+ {
+ super.testPersistPropertyComment(TASK_ID);
+ }
+
public void testPersistPackageItemsAdded() throws Exception
{
mockPackageItems(FAKE_NODE3);
@@ -476,41 +454,10 @@ public class TaskFormProcessorTest extends TestCase
}
}
- private void mockPackageItems(NodeRef... children)
- {
- ArrayList results = new ArrayList(children.length);
- for (NodeRef nodeRef : children)
- {
- ChildAssociationRef child = new ChildAssociationRef(ASSOC_PACKAGE_CONTAINS, PCKG_NODE, null, nodeRef);
- results.add(child);
- }
- when(nodeService.getChildAssocs(eq(PCKG_NODE), (QNamePattern)any(), (QNamePattern)any()))
- .thenReturn(results);
-
- }
-
- private void checkRemovedPackageItem(NodeRef child, boolean wasCalled)
- {
- int times = wasCalled ? 1 : 0;
- verify(nodeService, times(times))
- .removeChild(PCKG_NODE, child);
- }
-
- private void checkAddPackageItem(NodeRef child, boolean wasCalled)
- {
- int times = wasCalled ? 1 : 0;
- verify(nodeService, times(times))
- .addChild(eq(PCKG_NODE),
- eq(child),
- eq(ASSOC_PACKAGE_CONTAINS),
- (QName)any());
- }
-
private void processPersist(String dataKey, String value)
{
FormData data = new FormData();
data.addFieldData(dataKey, value);
- Item item = new Item("task", TASK_ID);
WorkflowTask persistedItem = (WorkflowTask) processor.persist(item, data);
assertEquals(newTask, persistedItem);
}
@@ -522,8 +469,7 @@ public class TaskFormProcessorTest extends TestCase
private Form processForm(List fields)
{
- Item item = new Item("task", TASK_ID);
- Form form = processor.generate(item, fields, null, null);
+ Form form = ((TaskFormProcessor) processor).generate(item, fields, null, null);
return form;
}
@@ -537,54 +483,6 @@ public class TaskFormProcessorTest extends TestCase
assertEquals("read_package_item_actions", pckgItemActionData.getValue());
}
- private void checkSingleProperty(Form form, String fieldName, Serializable fieldData)
- {
- String expDataKey = makeDataKeyName(fieldName);
- checkSingleField(form, fieldName, fieldData, expDataKey);
- }
-
- private void checkSingleAssociation(Form form, String fieldName, Serializable fieldData)
- {
- String expDataKey = makeAssociationDataKey(fieldName);
- checkSingleField(form, fieldName, fieldData, expDataKey);
- }
-
- private void checkSingleField(Form form, String fieldName, Serializable fieldData, String expDataKey)
- {
- List fieldDefs = form.getFieldDefinitions();
- assertEquals(1, fieldDefs.size());
- FieldDefinition fieldDef = fieldDefs.get(0);
- assertEquals(fieldName, fieldDef.getName());
- String dataKey = fieldDef.getDataKeyName();
- assertEquals(expDataKey, dataKey);
- FieldData data = form.getFormData().getFieldData(dataKey);
- if (fieldData != null && data != null)
- {
- assertEquals(fieldData, data.getValue());
- }
- else
- {
- assertNull(data);
- }
- }
-
- private String makeDataKeyName(String fieldName)
- {
- return PROP_DATA_PREFIX + fieldName.replace(":", "_");
- }
-
- private String makeDataKeyName(String fieldName, boolean added)
- {
- String assocDataKey = makeAssociationDataKey(fieldName);
- String suffix = added ? ASSOC_DATA_ADDED_SUFFIX : ASSOC_DATA_REMOVED_SUFFIX;
- return assocDataKey + suffix;
- }
-
- private String makeAssociationDataKey(String fieldName)
- {
- return ASSOC_DATA_PREFIX + fieldName.replace(":", "_");
- }
-
/*
* @see junit.framework.TestCase#setUp()
*/
@@ -592,43 +490,33 @@ public class TaskFormProcessorTest extends TestCase
protected void setUp() throws Exception
{
super.setUp();
+ super.item = new Item("task", TASK_ID);
task = makeTask();
- workflowService = makeWorkflowService();
- nodeService = makeNodeService();
+ super.workflowService = makeWorkflowService();
+ super.nodeService = makeNodeService();
DictionaryService dictionaryService = makeDictionaryService();
- namespaceService = makeNamespaceService();
+ super.namespaceService = makeNamespaceService();
authenticationService = makeAuthenticationService();
personService = makePersonService();
MockFieldProcessorRegistry fieldProcessorRegistry = new MockFieldProcessorRegistry(namespaceService,
dictionaryService);
- DefaultFieldProcessor defaultProcessor = makeDefaultFieldProcessor(dictionaryService);
- processor = makeTaskFormProcessor(dictionaryService, fieldProcessorRegistry, defaultProcessor);
+ DefaultFieldProcessor defaultProcessor = super.makeDefaultFieldProcessor(dictionaryService);
+ super.processor = makeTaskFormProcessor(dictionaryService, fieldProcessorRegistry, defaultProcessor);
}
private TaskFormProcessor makeTaskFormProcessor(DictionaryService dictionaryService,
MockFieldProcessorRegistry fieldProcessorRegistry, DefaultFieldProcessor defaultProcessor)
{
TaskFormProcessor processor1 = new TaskFormProcessor();
- processor1.setWorkflowService(workflowService);
- processor1.setNodeService(nodeService);
- processor1.setNamespaceService(namespaceService);
- processor1.setDictionaryService(dictionaryService);
+ processor1 =(TaskFormProcessor) super.makeTaskFormProcessor(processor1, dictionaryService,
+ fieldProcessorRegistry, defaultProcessor);
+
processor1.setAuthenticationService(authenticationService);
processor1.setPersonService(personService);
- processor1.setFieldProcessorRegistry(fieldProcessorRegistry);
- processor1.setBehaviourFilter(mock(BehaviourFilter.class));
+
return processor1;
}
- private DefaultFieldProcessor makeDefaultFieldProcessor(DictionaryService dictionaryService) throws Exception
- {
- DefaultFieldProcessor defaultProcessor = new DefaultFieldProcessor();
- defaultProcessor.setDictionaryService(dictionaryService);
- defaultProcessor.setNamespaceService(namespaceService);
- defaultProcessor.afterPropertiesSet();
- return defaultProcessor;
- }
-
private WorkflowTask makeTask(WorkflowTransition... transitions)
{
String id = TASK_ID;
@@ -721,29 +609,6 @@ public class TaskFormProcessorTest extends TestCase
return properties;
}
- private Map makeTaskAssociationDefs()
- {
- Map associations = new HashMap();
- QName actorName = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "Actor");
-
- // Add Assigneee association
- MockClassAttributeDefinition assigneeDef = MockClassAttributeDefinition.mockAssociationDefinition(
- ASSIGNEE_NAME, actorName);
- associations.put(ASSIGNEE_NAME, assigneeDef);
-
- // Add Assigneee association
- MockClassAttributeDefinition actorsDef = MockClassAttributeDefinition.mockAssociationDefinition(ACTORS_NAME,
- actorName);
- associations.put(ACTORS_NAME, actorsDef);
-
- // Add association with _
- MockClassAttributeDefinition with_ = MockClassAttributeDefinition.mockAssociationDefinition(ASSOC_WITH_,
- actorName);
- associations.put(ASSOC_WITH_, with_);
-
- return associations;
- }
-
private NamespaceService makeNamespaceService()
{
NamespaceServiceMemoryImpl nsService = new NamespaceServiceMemoryImpl();
diff --git a/source/test-java/org/alfresco/repo/forms/processor/workflow/WorkflowFormProcessorTest.java b/source/test-java/org/alfresco/repo/forms/processor/workflow/WorkflowFormProcessorTest.java
index 0b590a28d9..0005fd1c62 100644
--- a/source/test-java/org/alfresco/repo/forms/processor/workflow/WorkflowFormProcessorTest.java
+++ b/source/test-java/org/alfresco/repo/forms/processor/workflow/WorkflowFormProcessorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2010 Alfresco Software Limited.
+ * Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -19,30 +19,18 @@
package org.alfresco.repo.forms.processor.workflow;
-import static org.alfresco.repo.forms.processor.node.FormFieldConstants.ASSOC_DATA_ADDED_SUFFIX;
-import static org.alfresco.repo.forms.processor.node.FormFieldConstants.ASSOC_DATA_PREFIX;
-import static org.alfresco.repo.forms.processor.node.FormFieldConstants.ASSOC_DATA_REMOVED_SUFFIX;
-import static org.alfresco.repo.forms.processor.node.FormFieldConstants.PROP_DATA_PREFIX;
import static org.alfresco.repo.workflow.WorkflowModel.ASPECT_WORKFLOW_PACKAGE;
-import static org.alfresco.repo.workflow.WorkflowModel.ASSOC_ASSIGNEE;
import static org.alfresco.repo.workflow.WorkflowModel.ASSOC_PACKAGE;
-import static org.alfresco.repo.workflow.WorkflowModel.ASSOC_PACKAGE_CONTAINS;
-import static org.alfresco.repo.workflow.WorkflowModel.ASSOC_POOLED_ACTORS;
-import static org.alfresco.repo.workflow.WorkflowModel.PROP_DESCRIPTION;
import static org.alfresco.repo.workflow.WorkflowModel.PROP_PACKAGE_ACTION_GROUP;
import static org.alfresco.repo.workflow.WorkflowModel.PROP_PACKAGE_ITEM_ACTION_GROUP;
import static org.alfresco.repo.workflow.WorkflowModel.PROP_WORKFLOW_PRIORITY;
-import static org.alfresco.repo.workflow.WorkflowModel.PROP_STATUS;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMap;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -50,9 +38,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
-
-import org.alfresco.repo.forms.FieldDefinition;
import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData;
import org.alfresco.repo.forms.FormNotFoundException;
@@ -61,15 +46,12 @@ import org.alfresco.repo.forms.FormData.FieldData;
import org.alfresco.repo.forms.processor.node.DefaultFieldProcessor;
import org.alfresco.repo.forms.processor.node.MockClassAttributeDefinition;
import org.alfresco.repo.forms.processor.node.MockFieldProcessorRegistry;
-import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
-import org.alfresco.service.cmr.repository.ChildAssociationRef;
-import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowInstance;
@@ -81,7 +63,6 @@ import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.NamespaceServiceMemoryImpl;
import org.alfresco.service.namespace.QName;
-import org.alfresco.service.namespace.QNamePattern;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -91,27 +72,11 @@ import org.mockito.stubbing.Answer;
* @author Nick Smith
*
*/
-public class WorkflowFormProcessorTest extends TestCase
+public class WorkflowFormProcessorTest extends FormProcessorTest
{
- private static final String TASK_DEF_NAME = "TaskDef";
private static final String WF_DEF_NAME = "foo$wf:bar";
private static final QName PRIORITY_NAME = PROP_WORKFLOW_PRIORITY;
- private static final QName DESC_NAME = PROP_DESCRIPTION;
- private static final QName STATUS_NAME = PROP_STATUS;
- private static final QName PROP_WITH_ = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "some_prop");
- private static final QName ACTORS_NAME = ASSOC_POOLED_ACTORS;
- private static final QName ASSIGNEE_NAME = ASSOC_ASSIGNEE;
- private static final QName ASSOC_WITH_ = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "some_assoc");
- private static final NodeRef FAKE_NODE = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode");
- private static final NodeRef FAKE_NODE2 = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode2");
- private static final NodeRef FAKE_NODE3 = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakeNode3");
- private static final NodeRef PCKG_NODE = new NodeRef(NamespaceService.BPM_MODEL_1_0_URI + "/FakePackage");
- private static final Item item = new Item("workflow", WF_DEF_NAME);
- private NamespaceService namespaceService;
- private NodeService nodeService;
- private WorkflowService workflowService;
- private WorkflowFormProcessor processor;
private WorkflowInstance newInstance;
private WorkflowDefinition definition;
private Map actualProperties = null;
@@ -138,14 +103,19 @@ public class WorkflowFormProcessorTest extends TestCase
// Do nothing!
}
- WorkflowDefinition result = processor.getTypedItem(item);
+ WorkflowDefinition result = ((WorkflowFormProcessor) processor).getTypedItem(item);
assertNotNull(result);
assertEquals(WF_DEF_NAME, result.getName());
}
+ public void testPersistPropertyComment() throws Exception
+ {
+ super.testPersistPropertyComment(item.getId());
+ }
+
public void testGenerateSetsItemAndUrl() throws Exception
{
- Form form = processor.generate(item, null, null, null);
+ Form form = ((WorkflowFormProcessor) processor).generate(item, null, null, null);
Item formItem = form.getItem();
assertEquals(item.getId(), formItem.getId());
assertEquals(item.getKind(), formItem.getKind());
@@ -324,36 +294,6 @@ public class WorkflowFormProcessorTest extends TestCase
checkRemovedPackageItem(FAKE_NODE3, false);
}
- private void mockPackageItems(NodeRef... children)
- {
- ArrayList results = new ArrayList(children.length);
- for (NodeRef nodeRef : children)
- {
- ChildAssociationRef child = new ChildAssociationRef(ASSOC_PACKAGE_CONTAINS, PCKG_NODE, null, nodeRef);
- results.add(child);
- }
- when(nodeService.getChildAssocs(eq(PCKG_NODE), (QNamePattern)any(), (QNamePattern)any()))
- .thenReturn(results);
-
- }
-
- private void checkRemovedPackageItem(NodeRef child, boolean wasCalled)
- {
- int times = wasCalled ? 1 : 0;
- verify(nodeService, times(times))
- .removeChild(PCKG_NODE, child);
- }
-
- private void checkAddPackageItem(NodeRef child, boolean wasCalled)
- {
- int times = wasCalled ? 1 : 0;
- verify(nodeService, times(times))
- .addChild(eq(PCKG_NODE),
- eq(child),
- eq(ASSOC_PACKAGE_CONTAINS),
- (QName)any());
- }
-
private void processPersist(String dataKey, String value)
{
FormData data = new FormData();
@@ -369,7 +309,7 @@ public class WorkflowFormProcessorTest extends TestCase
private Form processForm(List fields)
{
- return processor.generate(item, fields, null, null);
+ return ((WorkflowFormProcessor) processor).generate(item, fields, null, null);
}
private void checkPackageActionGroups(FormData formData)
@@ -381,50 +321,7 @@ public class WorkflowFormProcessorTest extends TestCase
assertNotNull(pckgItemActionData);
assertEquals("start_package_item_actions", pckgItemActionData.getValue());
}
-
- private void checkSingleProperty(Form form, String fieldName, Serializable fieldData)
- {
- String expDataKey = makeDataKeyName(fieldName);
- checkSingleField(form, fieldName, fieldData, expDataKey);
-
- }
-
- private void checkSingleAssociation(Form form, String fieldName, Serializable fieldData)
- {
- String expDataKey = makeAssociationDataKey(fieldName);
- checkSingleField(form, fieldName, fieldData, expDataKey);
- }
-
- private void checkSingleField(Form form, String fieldName, Serializable fieldData, String expDataKey)
- {
- List fieldDefs = form.getFieldDefinitions();
- assertEquals(1, fieldDefs.size());
- FieldDefinition fieldDef = fieldDefs.get(0);
- assertEquals(fieldName, fieldDef.getName());
- String dataKey = fieldDef.getDataKeyName();
- assertEquals(expDataKey, dataKey);
- FieldData data = form.getFormData().getFieldData(dataKey);
- assertEquals(fieldData, data.getValue());
- }
-
-
- private String makeDataKeyName(String fieldName)
- {
- return PROP_DATA_PREFIX + fieldName.replace(":", "_");
- }
-
- private String makeDataKeyName(String fieldName, boolean added)
- {
- String assocDataKey = makeAssociationDataKey(fieldName);
- String suffix = added ? ASSOC_DATA_ADDED_SUFFIX : ASSOC_DATA_REMOVED_SUFFIX;
- return assocDataKey + suffix;
- }
-
- private String makeAssociationDataKey(String fieldName)
- {
- return ASSOC_DATA_PREFIX + fieldName.replace(":", "_");
- }
-
+
/*
* @see junit.framework.TestCase#setUp()
*/
@@ -432,39 +329,27 @@ public class WorkflowFormProcessorTest extends TestCase
protected void setUp() throws Exception
{
super.setUp();
+ super.item = new Item("workflow", WF_DEF_NAME);
definition = makeWorkflowDefinition();
- workflowService = makeWorkflowService();
- nodeService = makeNodeService();
+ super.workflowService = makeWorkflowService();
+ super.nodeService = makeNodeService();
DictionaryService dictionaryService = makeDictionaryService();
- namespaceService = makeNamespaceService();
+ super.namespaceService = makeNamespaceService();
MockFieldProcessorRegistry fieldProcessorRegistry = new MockFieldProcessorRegistry(namespaceService,
dictionaryService);
- DefaultFieldProcessor defaultProcessor = makeDefaultFieldProcessor(dictionaryService);
- processor = makeWorkflowFormProcessor(dictionaryService, fieldProcessorRegistry, defaultProcessor);
+ DefaultFieldProcessor defaultProcessor = super.makeDefaultFieldProcessor(dictionaryService);
+ super.processor = makeWorkflowFormProcessor(dictionaryService, fieldProcessorRegistry, defaultProcessor);
}
private WorkflowFormProcessor makeWorkflowFormProcessor(DictionaryService dictionaryService,
MockFieldProcessorRegistry fieldProcessorRegistry, DefaultFieldProcessor defaultProcessor)
{
WorkflowFormProcessor processor1 = new WorkflowFormProcessor();
- processor1.setWorkflowService(workflowService);
- processor1.setNodeService(nodeService);
- processor1.setNamespaceService(namespaceService);
- processor1.setDictionaryService(dictionaryService);
- processor1.setFieldProcessorRegistry(fieldProcessorRegistry);
- processor1.setBehaviourFilter(mock(BehaviourFilter.class));
+ processor1 =(WorkflowFormProcessor) super.makeTaskFormProcessor(processor1, dictionaryService,
+ fieldProcessorRegistry, defaultProcessor);
return processor1;
}
- private DefaultFieldProcessor makeDefaultFieldProcessor(DictionaryService dictionaryService) throws Exception
- {
- DefaultFieldProcessor defaultProcessor = new DefaultFieldProcessor();
- defaultProcessor.setDictionaryService(dictionaryService);
- defaultProcessor.setNamespaceService(namespaceService);
- defaultProcessor.afterPropertiesSet();
- return defaultProcessor;
- }
-
private WorkflowDefinition makeWorkflowDefinition()
{
String id = "foo$workflowDefId";
@@ -537,29 +422,6 @@ public class WorkflowFormProcessorTest extends TestCase
return properties;
}
- private Map makeTaskAssociationDefs()
- {
- Map associations = new HashMap();
- QName actorName = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "Actor");
-
- // Add Assigneee association
- MockClassAttributeDefinition assigneeDef = MockClassAttributeDefinition.mockAssociationDefinition(
- ASSIGNEE_NAME, actorName);
- associations.put(ASSIGNEE_NAME, assigneeDef);
-
- // Add Assigneee association
- MockClassAttributeDefinition actorsDef = MockClassAttributeDefinition.mockAssociationDefinition(ACTORS_NAME,
- actorName);
- associations.put(ACTORS_NAME, actorsDef);
-
- // Add association with _
- MockClassAttributeDefinition with_ = MockClassAttributeDefinition.mockAssociationDefinition(ASSOC_WITH_,
- actorName);
- associations.put(ASSOC_WITH_, with_);
-
- return associations;
- }
-
private NamespaceService makeNamespaceService()
{
NamespaceServiceMemoryImpl nsService = new NamespaceServiceMemoryImpl();