diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/DataKeyInfo.java b/source/java/org/alfresco/repo/forms/processor/workflow/DataKeyInfo.java
new file mode 100644
index 0000000000..81a907aee1
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/workflow/DataKeyInfo.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2005-2010 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 org.alfresco.service.namespace.QName;
+
+/**
+ * @author Nick Smith
+ *
+ */
+public class DataKeyInfo
+{
+ private final String dataKey;
+ private final QName qName;
+ private final FieldType fieldType;
+ private final boolean isAdd;
+
+ private DataKeyInfo(String dataKey, QName qName, FieldType fieldType, boolean isAdd)
+ {
+ this.dataKey = dataKey;
+ this.qName = qName;
+ this.fieldType = fieldType;
+ this.isAdd = isAdd;
+ }
+
+ public static DataKeyInfo makeAssociationDataKeyInfo(String dataKey, QName qName, boolean isAdd)
+ {
+ return new DataKeyInfo(dataKey, qName, FieldType.ASSOCIATION, isAdd);
+ }
+
+ public static DataKeyInfo makePropertyDataKeyInfo(String dataKey, QName qName)
+ {
+ return new DataKeyInfo(dataKey, qName, FieldType.PROPERTY, true);
+ }
+
+ public static DataKeyInfo makeTransientDataKeyInfo(String dataKey)
+ {
+ return new DataKeyInfo(dataKey, null, FieldType.TRANSIENT, true);
+ }
+
+ /**
+ * @return the dataKey
+ */
+ public String getDataKey()
+ {
+ return dataKey;
+ }
+
+ /**
+ * @return the qName
+ */
+ public QName getqName()
+ {
+ return qName;
+ }
+
+
+ /**
+ * @return the fieldType
+ */
+ public FieldType getFieldType()
+ {
+ return fieldType;
+ }
+
+ /**
+ * @return the isAdd
+ */
+ public boolean isAdd()
+ {
+ return isAdd;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/DataKeyMatcher.java b/source/java/org/alfresco/repo/forms/processor/workflow/DataKeyMatcher.java
new file mode 100644
index 0000000000..4c2fdbbee8
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/workflow/DataKeyMatcher.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2005-2010 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.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+
+import static org.alfresco.repo.forms.processor.node.FormFieldConstants.*;
+
+/**
+ * @author Nick Smith
+ *
+ */
+public class DataKeyMatcher
+{
+ /**
+ * A regular expression which can be used to match property names. These
+ * names will look like "prop_cm_name". The pattern can also be
+ * used to extract the "cm" and the "name" parts.
+ */
+ private final static Pattern propertyNamePattern = Pattern.compile("(^[a-zA-Z0-9]+)_([a-zA-Z0-9_]+$)");
+
+ public DataKeyMatcher(NamespaceService namespaceService)
+ {
+ this.namespaceService = namespaceService;
+ }
+
+ /**
+ * A regular expression which can be used to match association names. These
+ * names will look like "assoc_cm_references_added". The
+ * pattern can also be used to extract the "cm", the "name" and the suffix
+ * parts.
+ */
+ private final static Pattern associationNamePattern = Pattern.compile("(^[a-zA-Z0-9]+)_([a-zA-Z0-9_]+)(_[a-zA-Z]+$)");
+
+ private final NamespaceService namespaceService;
+
+ /**
+ *
+ * @param dataKey
+ * @return
+ */
+ public DataKeyInfo match(String dataKey)
+ {
+ if (dataKey.startsWith(PROP_DATA_PREFIX))
+ {
+ return matchProperty(dataKey);
+ }
+ else if(dataKey.startsWith(ASSOC_DATA_PREFIX))
+ {
+ return matchAssociation(dataKey);
+ }
+
+ // No match found.
+ return null;
+ }
+
+ private DataKeyInfo matchAssociation(String dataKey)
+ {
+ String keyName = dataKey.substring(ASSOC_DATA_PREFIX.length());
+ Matcher matcher = associationNamePattern.matcher(keyName);
+ if (!matcher.matches())
+ {
+ return null;
+ }
+ QName qName = getQName(matcher);
+ String suffix = matcher.group(3);
+ boolean isAdd = !(ASSOC_DATA_REMOVED_SUFFIX.equals(suffix));
+ return DataKeyInfo.makeAssociationDataKeyInfo(keyName, qName, isAdd);
+ }
+
+ private DataKeyInfo matchProperty(String dataKey)
+ {
+ String keyName = dataKey.substring(PROP_DATA_PREFIX.length());
+ Matcher matcher = propertyNamePattern.matcher(keyName);
+ if (matcher.matches())
+ {
+ QName qName = getQName(matcher);
+ return DataKeyInfo.makePropertyDataKeyInfo(keyName, qName);
+ }
+ return DataKeyInfo.makeTransientDataKeyInfo(keyName);
+ }
+
+ private QName getQName(Matcher matcher)
+ {
+ String prefix = matcher.group(1);
+ String localName = matcher.group(2);
+ QName qName = QName.createQName(prefix, localName, namespaceService);
+ return qName;
+ }
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/FieldType.java b/source/java/org/alfresco/repo/forms/processor/workflow/FieldType.java
new file mode 100644
index 0000000000..486fc558a1
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/workflow/FieldType.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2005-2010 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;
+
+/**
+ * @author Nick Smith
+ *
+ */
+public enum FieldType
+{
+ ASSOCIATION,
+ PROPERTY,
+ TRANSIENT;
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessor.java b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessor.java
new file mode 100644
index 0000000000..b6b7f6e4c5
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessor.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * 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
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.repo.forms.processor.workflow;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.alfresco.repo.forms.FormData;
+import org.alfresco.repo.forms.Item;
+import org.alfresco.repo.forms.FormData.FieldData;
+import org.alfresco.repo.forms.processor.FieldProcessorRegistry;
+import org.alfresco.repo.forms.processor.node.ContentModelFormProcessor;
+import org.alfresco.repo.forms.processor.node.ItemData;
+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.workflow.WorkflowService;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.ParameterCheck;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @author Nick Smith
+ */
+public class TaskFormProcessor extends ContentModelFormProcessor
+{
+ /** Logger */
+ private static final Log LOGGER = LogFactory.getLog(TaskFormProcessor.class);
+ private static final TypedPropertyValueGetter valueGetter = new TypedPropertyValueGetter();
+
+ private DataKeyMatcher keyMatcher;
+ private WorkflowService workflowService;
+
+ // Constructor for Spring
+ public TaskFormProcessor()
+ {
+ super();
+ }
+
+ // Constructor for tests.
+ public TaskFormProcessor(WorkflowService workflowService, NamespaceService namespaceService,
+ DictionaryService dictionaryService, FieldProcessorRegistry fieldProcessorRegistry)
+ {
+ this.workflowService = workflowService;
+ this.namespaceService = namespaceService;
+ this.dictionaryService = dictionaryService;
+ this.fieldProcessorRegistry = fieldProcessorRegistry;
+ this.keyMatcher = new DataKeyMatcher(namespaceService);
+ }
+
+ @Override
+ protected WorkflowTask getTypedItem(Item item)
+ {
+ ParameterCheck.mandatory("item", item);
+ String id = item.getId();
+ WorkflowTask task = workflowService.getTaskById(id);
+ return task;
+ }
+
+ @Override
+ protected WorkflowTask internalPersist(WorkflowTask task, FormData data)
+ {
+ TaskUpdater updater = new TaskUpdater(task.id, workflowService);
+ ItemData itemData = makeItemData(task);
+ for (FieldData fieldData : data)
+ {
+ addFieldToSerialize(updater, itemData, fieldData);
+ }
+ return updater.update();
+ }
+
+ private void addFieldToSerialize(TaskUpdater updater,
+ ItemData> itemData,
+ FieldData fieldData)
+ {
+ String name = fieldData.getName();
+ DataKeyInfo keyInfo = keyMatcher.match(name);
+ if ((keyInfo == null || FieldType.TRANSIENT == keyInfo.getFieldType()) &&
+ LOGGER.isWarnEnabled())
+ {
+ LOGGER.warn("Ignoring unrecognized field: " + name);
+ }
+
+ if (keyInfo != null)
+ {
+ QName fullName = keyInfo.getqName();
+ Object rawValue = fieldData.getValue();
+ if (FieldType.PROPERTY == keyInfo.getFieldType())
+ {
+ Serializable propValue = getPropertyValueToPersist(fullName, rawValue, itemData);
+ // TODO What if the user wants to set prop to null?
+ if (propValue != null)
+ {
+ updater.addProperty(fullName, propValue);
+ }
+ }
+ else if (FieldType.ASSOCIATION == keyInfo.getFieldType())
+ {
+ if (rawValue instanceof String)
+ {
+ updater.changeAssociation(fullName, (String) rawValue, keyInfo.isAdd());
+ }
+ }
+ }
+ }
+
+ private Serializable getPropertyValueToPersist(QName fullName,
+ Object value,
+ ItemData> itemData)
+ {
+ PropertyDefinition propDef = itemData.getPropertyDefinition(fullName);
+ if (propDef == null)
+ {
+ propDef = dictionaryService.getProperty(fullName);
+ }
+ if (propDef != null)
+ {
+ return valueGetter.getValue(value, propDef);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.alfresco.repo.forms.processor.FilteredFormProcessor#getItemType(java
+ * .lang.Object)
+ */
+ @Override
+ protected String getItemType(WorkflowTask item)
+ {
+ TypeDefinition typeDef = item.definition.metadata;
+ return typeDef.getName().toPrefixString(namespaceService);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.alfresco.repo.forms.processor.FilteredFormProcessor#getItemURI(java
+ * .lang.Object)
+ */
+ @Override
+ protected String getItemURI(WorkflowTask item)
+ {
+ // TODO Check this URL is OK.
+ return "/api/task-instances/" + item.id;
+ }
+
+ /*
+ * @see
+ * org.alfresco.repo.forms.processor.task.ContentModelFormProcessor#getLogger
+ * ()
+ */
+ @Override
+ protected Log getLogger()
+ {
+ return LOGGER;
+ }
+
+ @Override
+ protected TypeDefinition getBaseType(WorkflowTask task)
+ {
+ return task.definition.metadata;
+ }
+
+ @Override
+ protected Map getPropertyValues(WorkflowTask task)
+ {
+ return task.properties;
+ }
+
+ @Override
+ protected Map getAssociationValues(WorkflowTask item)
+ {
+ return item.properties;
+ }
+
+ @Override
+ protected Map getTransientValues(WorkflowTask item)
+ {
+ return null;
+ }
+
+ /**
+ * Sets the Workflow Service.
+ *
+ * @param workflowService
+ */
+ public void setWorkflowService(WorkflowService workflowService)
+ {
+ this.workflowService = workflowService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.alfresco.repo.forms.processor.task.ContentModelFormProcessor#
+ * setNamespaceService(org.alfresco.service.namespace.NamespaceService)
+ */
+ @Override
+ public void setNamespaceService(NamespaceService namespaceService)
+ {
+ super.setNamespaceService(namespaceService);
+ this.keyMatcher = new DataKeyMatcher(namespaceService);
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java
new file mode 100644
index 0000000000..23f51eac10
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/workflow/TaskFormProcessorTest.java
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * 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
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.repo.forms.processor.workflow;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+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.Item;
+import org.alfresco.repo.forms.FormData.FieldData;
+import org.alfresco.repo.forms.processor.node.DefaultFieldProcessor;
+import org.alfresco.repo.forms.processor.node.FormFieldConstants;
+import org.alfresco.repo.forms.processor.node.MockClassAttributeDefinition;
+import org.alfresco.repo.forms.processor.node.MockFieldProcessorRegistry;
+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.NodeRef;
+import org.alfresco.service.cmr.workflow.WorkflowException;
+import org.alfresco.service.cmr.workflow.WorkflowNode;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowTaskState;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.NamespaceServiceMemoryImpl;
+import org.alfresco.service.namespace.QName;
+import org.mockito.ArgumentCaptor;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+/**
+ * @author Nick Smith
+ */
+public class TaskFormProcessorTest extends TestCase
+{
+ private static final String TASK_DEF_NAME = "TaskDef";
+ private static final String TASK_ID = "Real Id";
+ private static final QName DESC_NAME = WorkflowModel.PROP_DESCRIPTION;
+ private static final QName STATUS_NAME = WorkflowModel.PROP_STATUS;
+ private static final QName PROP_WITH_ = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "some_prop");
+ private static final QName ACTORS_NAME = WorkflowModel.ASSOC_POOLED_ACTORS;
+ private static final QName ASSIGNEE_NAME = WorkflowModel.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 WorkflowService workflowService;
+ private TaskFormProcessor processor;
+ private WorkflowTask task;
+ private NamespaceService namespaceService;
+ private WorkflowTask newTask;
+
+ public void testGetTypedItem() throws Exception
+ {
+ try
+ {
+ processor.getTypedItem(null);
+ fail("Should have thrown an Exception here!");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // Do nothing!
+ }
+
+ try
+ {
+ processor.getTypedItem(new Item("task", "bad id"));
+ fail("Should have thrown an Exception here!");
+ }
+ catch (WorkflowException e)
+ {
+ // Do nothing!
+ }
+
+ Item item = new Item("task", TASK_ID);
+ WorkflowTask result = processor.getTypedItem(item);
+ assertNotNull(result);
+ assertEquals(TASK_ID, result.id);
+ }
+
+ public void testGenerateSetsItemAndUrl() throws Exception
+ {
+ Item item = new Item("task", TASK_ID);
+ Form form = processor.generate(item, null, null, null);
+ Item formItem = form.getItem();
+ assertEquals(item.getId(), formItem.getId());
+ assertEquals(item.getKind(), formItem.getKind());
+ String expType = NamespaceService.BPM_MODEL_PREFIX + ":" + TASK_DEF_NAME;
+ assertEquals(expType, formItem.getType());
+ assertEquals("/api/task-instances/" + TASK_ID, formItem.getUrl());
+ }
+
+ public void testGenerateSingleProperty()
+ {
+ // Check Status field is added to Form.
+ String fieldName = STATUS_NAME.toPrefixString(namespaceService);
+ List fields = Arrays.asList(fieldName);
+ Form form = processForm(fields);
+ checkSingleProperty(form, fieldName, WorkflowTaskState.IN_PROGRESS);
+
+ // Check Status field is added to Form, when explicitly typed as a
+ // property.
+ String fullPropertyName = "prop:" + fieldName;
+ fields = Arrays.asList(fullPropertyName);
+ form = processForm(fields);
+ checkSingleProperty(form, fieldName, WorkflowTaskState.IN_PROGRESS);
+ }
+
+ public void testGenerateSingleAssociation()
+ {
+ // Check Assignee field is added to Form.
+ String fieldName = ASSIGNEE_NAME.toPrefixString(namespaceService);
+ List fields = Arrays.asList(fieldName);
+ Form form = processForm(fields);
+ Serializable fieldData = (Serializable) Arrays.asList(FAKE_NODE.toString());
+// checkSingleAssociation(form, fieldName, fieldData);
+
+ // Check Assignee field is added to Form, when explicitly typed as an
+ // association.
+ String fullAssociationName = "assoc:" + fieldName;
+ fields = Arrays.asList(fullAssociationName);
+ form = processForm(fields);
+// checkSingleAssociation(form, fieldName, fieldData);
+ }
+
+ public void testIgnoresUnknownFields() throws Exception
+ {
+ String fakeFieldName = NamespaceService.BPM_MODEL_PREFIX + ":" + "Fake Field";
+ String statusFieldName = STATUS_NAME.toPrefixString(namespaceService);
+ List fields = Arrays.asList(fakeFieldName, statusFieldName);
+ Form form = processForm(fields);
+ checkSingleProperty(form, statusFieldName, WorkflowTaskState.IN_PROGRESS);
+ }
+
+ public void testGenerateDefaultForm() throws Exception
+ {
+ Form form = processForm(null);
+ List fieldDefs = form.getFieldDefinitionNames();
+ assertEquals(6, fieldDefs.size());
+ assertTrue(fieldDefs.contains(ASSIGNEE_NAME.toPrefixString(namespaceService)));
+ assertTrue(fieldDefs.contains(ACTORS_NAME.toPrefixString(namespaceService)));
+ assertTrue(fieldDefs.contains(DESC_NAME.toPrefixString(namespaceService)));
+ assertTrue(fieldDefs.contains(STATUS_NAME.toPrefixString(namespaceService)));
+
+ Serializable fieldData = (Serializable) Arrays.asList(FAKE_NODE.toString());
+ FormData formData = form.getFormData();
+ assertEquals(4, formData.getNumberOfFields());
+// assertEquals(fieldData, formData.getFieldData("assoc_bpm_assignee").getValue());
+ assertEquals(WorkflowTaskState.IN_PROGRESS, formData.getFieldData("prop_bpm_status").getValue());
+ }
+
+ public void testPersistPropertyChanged() throws Exception
+ {
+ String fieldName = DESC_NAME.toPrefixString(namespaceService);
+ String dataKey = makeDataKeyName(fieldName, FormFieldConstants.PROP_DATA_PREFIX);
+ String value = "New Description";
+
+ processPersist(dataKey, value);
+
+ Map actualProperties = retrievePropertyies();
+ assertEquals(1, actualProperties.size());
+ assertEquals(value, actualProperties.get(DESC_NAME));
+ }
+
+ public void testPersistPropertyWith_() throws Exception
+ {
+ String fieldName = PROP_WITH_.toPrefixString(namespaceService);
+ String dataKey = makeDataKeyName(fieldName, FormFieldConstants.PROP_DATA_PREFIX);
+ String value = "New _ Value";
+
+ processPersist(dataKey, value);
+
+ Map actualProperties = retrievePropertyies();
+ assertEquals(1, actualProperties.size());
+ assertEquals(value, actualProperties.get(PROP_WITH_));
+ }
+
+ @SuppressWarnings("unchecked")
+ private Map retrievePropertyies()
+ {
+ ArgumentCaptor