Added Package/PackageItem Action Group data to Workflow and Task FormProcessors.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21307 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
N Smith
2010-07-20 14:34:23 +00:00
parent 44f1aa459b
commit 5d2143cfe5
10 changed files with 155 additions and 109 deletions

View File

@@ -158,7 +158,6 @@
class="org.alfresco.repo.forms.processor.workflow.WorkflowFormProcessor" class="org.alfresco.repo.forms.processor.workflow.WorkflowFormProcessor"
parent="baseFormProcessor"> parent="baseFormProcessor">
<property name="filterRegistry" ref="workflowFilterRegistry" /> <property name="filterRegistry" ref="workflowFilterRegistry" />
<property name="smallNodeService" ref="nodeService" />
<property name="workflowService" ref="WorkflowService" /> <property name="workflowService" ref="WorkflowService" />
<property name="matchPattern"> <property name="matchPattern">
<value>workflow</value> <value>workflow</value>

View File

@@ -22,6 +22,8 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import org.alfresco.repo.forms.FormData.FieldData;
/** /**
* Data representation of a form to be displayed in the UI. * Data representation of a form to be displayed in the UI.
* *
@@ -169,6 +171,18 @@ public class Form
this.data = data; this.data = data;
} }
/**
* Returns <code>true</code> if the Form contains {@link FieldData} for the
* specified <code>dataKey</code>.
*
* @param dataKey The dataKey for the field.
* @return
*/
public boolean dataExists(String dataKey)
{
return data.getFieldNames().contains(dataKey);
}
/** /**
* Adds some data to be displayed by the form * Adds some data to be displayed by the form
* *

View File

@@ -156,6 +156,13 @@ public abstract class FilteredFormProcessor<ItemType, PersistType> extends Abstr
Object itemData = makeItemData(item); Object itemData = makeItemData(item);
FormCreationData data = new FormCreationData(itemData, forcedFields, context); FormCreationData data = new FormCreationData(itemData, forcedFields, context);
populateForm(form, fields, data);
if (log.isDebugEnabled()) //
log.debug("Generated form: " + form);
}
protected void populateForm(Form form, List<String> fields, FormCreationData data)
{
List<Field> fieldsToAdd; List<Field> fieldsToAdd;
if (fields != null && fields.size() > 0) if (fields != null && fields.size() > 0)
{ {
@@ -166,8 +173,6 @@ public abstract class FilteredFormProcessor<ItemType, PersistType> extends Abstr
fieldsToAdd = generateDefaultFields(data); fieldsToAdd = generateDefaultFields(data);
} }
form.addFields(fieldsToAdd); form.addFields(fieldsToAdd);
if (log.isDebugEnabled()) //
log.debug("Generated form: " + form);
} }
/** /**

View File

@@ -31,6 +31,7 @@ import java.util.regex.Pattern;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.forms.Field; import org.alfresco.repo.forms.Field;
import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData; import org.alfresco.repo.forms.FormData;
import org.alfresco.repo.forms.FormException; import org.alfresco.repo.forms.FormException;
import org.alfresco.repo.forms.FormData.FieldData; import org.alfresco.repo.forms.FormData.FieldData;
@@ -197,6 +198,24 @@ public abstract class ContentModelFormProcessor<ItemType, PersistType> extends
this.contentService = contentService; this.contentService = contentService;
} }
protected void addPropertyDataIfRequired(QName propName, Form form, ItemData<?> itemData)
{
String dataKey = makePropDataKey(propName);
if(form.dataExists(dataKey)== false)
{
PropertyFieldProcessor processor = new PropertyFieldProcessor(namespaceService, dictionaryService);
Object value = processor.getValue(propName, itemData);
form.addData(dataKey, value);
}
}
private String makePropDataKey(QName propName)
{
String propPrefixName = propName.toPrefixString(namespaceService);
String dataKey = FormFieldConstants.PROP_DATA_PREFIX + propPrefixName.replace(':', '_');
return dataKey;
}
@Override @Override
protected List<Field> generateDefaultFields(FormCreationData data) protected List<Field> generateDefaultFields(FormCreationData data)
{ {

View File

@@ -25,7 +25,8 @@
package org.alfresco.repo.forms.processor.node; package org.alfresco.repo.forms.processor.node;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.List; import java.util.List;
@@ -77,6 +78,14 @@ public class MockClassAttributeDefinition implements PropertyDefinition, Associa
return mock; return mock;
} }
public static MockClassAttributeDefinition mockPropertyDefinition(QName name, QName dataTypeName, String defaultValue)
{
MockClassAttributeDefinition mock = new MockClassAttributeDefinition(name);
mockDataTypeName(dataTypeName, mock);
mock.defaultValue = defaultValue;
return mock;
}
public static MockClassAttributeDefinition mockPropertyDefinition(QName name,// public static MockClassAttributeDefinition mockPropertyDefinition(QName name,//
QName dataTypeName,// QName dataTypeName,//
String title,// String title,//

View File

@@ -94,12 +94,12 @@ public class PropertyFieldProcessor extends QNameFieldProcessor<PropertyDefiniti
} }
@Override @Override
protected Object getValue(QName name, ItemData<?> data) public Object getValue(QName name, ItemData<?> data)
{ {
Serializable value = data.getPropertyValue(name); Serializable value = data.getPropertyValue(name);
if (value == null) if (value == null)
{ {
return null; return getDefaultValue(name, data);
} }
if (value instanceof Collection<?>) if (value instanceof Collection<?>)
@@ -121,6 +121,16 @@ public class PropertyFieldProcessor extends QNameFieldProcessor<PropertyDefiniti
return value; return value;
} }
private Object getDefaultValue(QName name, ItemData<?> data)
{
PropertyDefinition propDef = data.getPropertyDefinition(name);
if(propDef !=null)
{
return propDef.getDefaultValue();
}
return null;
}
private PropertyFieldDefinition makePropertyFieldDefinition(final PropertyDefinition propDef, FieldGroup group) private PropertyFieldDefinition makePropertyFieldDefinition(final PropertyDefinition propDef, FieldGroup group)
{ {
String name = getPrefixedName(propDef); String name = getPrefixedName(propDef);

View File

@@ -26,14 +26,18 @@
package org.alfresco.repo.forms.processor.workflow; package org.alfresco.repo.forms.processor.workflow;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData; import org.alfresco.repo.forms.FormData;
import org.alfresco.repo.forms.Item; import org.alfresco.repo.forms.Item;
import org.alfresco.repo.forms.FormData.FieldData; import org.alfresco.repo.forms.FormData.FieldData;
import org.alfresco.repo.forms.processor.FieldProcessorRegistry; import org.alfresco.repo.forms.processor.FieldProcessorRegistry;
import org.alfresco.repo.forms.processor.FormCreationData;
import org.alfresco.repo.forms.processor.node.ContentModelFormProcessor; import org.alfresco.repo.forms.processor.node.ContentModelFormProcessor;
import org.alfresco.repo.forms.processor.node.ItemData; import org.alfresco.repo.forms.processor.node.ItemData;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition;
@@ -84,6 +88,17 @@ public class TaskFormProcessor extends ContentModelFormProcessor<WorkflowTask, W
return task; return task;
} }
@Override
protected void populateForm(Form form, List<String> fields, FormCreationData data)
{
super.populateForm(form, fields, data);
// Add package actions to FormData.
ItemData<?> itemData = (ItemData<?>) data.getItemData();
addPropertyDataIfRequired(WorkflowModel.PROP_PACKAGE_ACTION_GROUP, form, itemData);
addPropertyDataIfRequired(WorkflowModel.PROP_PACKAGE_ITEM_ACTION_GROUP, form, itemData);
}
@Override @Override
protected WorkflowTask internalPersist(WorkflowTask task, FormData data) protected WorkflowTask internalPersist(WorkflowTask task, FormData data)
{ {

View File

@@ -146,6 +146,7 @@ public class TaskFormProcessorTest extends TestCase
fields = Arrays.asList(fullPropertyName); fields = Arrays.asList(fullPropertyName);
form = processForm(fields); form = processForm(fields);
checkSingleProperty(form, fieldName, WorkflowTaskState.IN_PROGRESS); checkSingleProperty(form, fieldName, WorkflowTaskState.IN_PROGRESS);
checkPackageActionGroups(form.getFormData());
} }
public void testGenerateSingleAssociation() public void testGenerateSingleAssociation()
@@ -163,6 +164,7 @@ public class TaskFormProcessorTest extends TestCase
fields = Arrays.asList(fullAssociationName); fields = Arrays.asList(fullAssociationName);
form = processForm(fields); form = processForm(fields);
checkSingleAssociation(form, fieldName, fieldData); checkSingleAssociation(form, fieldName, fieldData);
checkPackageActionGroups(form.getFormData());
} }
public void testIgnoresUnknownFields() throws Exception public void testIgnoresUnknownFields() throws Exception
@@ -172,22 +174,25 @@ public class TaskFormProcessorTest extends TestCase
List<String> fields = Arrays.asList(fakeFieldName, statusFieldName); List<String> fields = Arrays.asList(fakeFieldName, statusFieldName);
Form form = processForm(fields); Form form = processForm(fields);
checkSingleProperty(form, statusFieldName, WorkflowTaskState.IN_PROGRESS); checkSingleProperty(form, statusFieldName, WorkflowTaskState.IN_PROGRESS);
checkPackageActionGroups(form.getFormData());
} }
public void testGenerateDefaultForm() throws Exception public void testGenerateDefaultForm() throws Exception
{ {
Form form = processForm(null); Form form = processForm(null);
List<String> fieldDefs = form.getFieldDefinitionNames(); List<String> fieldDefs = form.getFieldDefinitionNames();
assertEquals(6, fieldDefs.size()); assertEquals(8, fieldDefs.size());
assertTrue(fieldDefs.contains(ASSIGNEE_NAME.toPrefixString(namespaceService))); assertTrue(fieldDefs.contains(ASSIGNEE_NAME.toPrefixString(namespaceService)));
assertTrue(fieldDefs.contains(ACTORS_NAME.toPrefixString(namespaceService))); assertTrue(fieldDefs.contains(ACTORS_NAME.toPrefixString(namespaceService)));
assertTrue(fieldDefs.contains(DESC_NAME.toPrefixString(namespaceService))); assertTrue(fieldDefs.contains(DESC_NAME.toPrefixString(namespaceService)));
assertTrue(fieldDefs.contains(STATUS_NAME.toPrefixString(namespaceService))); assertTrue(fieldDefs.contains(STATUS_NAME.toPrefixString(namespaceService)));
Serializable fieldData = (Serializable) Arrays.asList(FAKE_NODE.toString()); Serializable fieldData = (Serializable) Arrays.asList(FAKE_NODE.toString());
FormData formData = form.getFormData(); FormData formData = form.getFormData();
assertEquals(4, formData.getNumberOfFields()); assertEquals(6, formData.getNumberOfFields());
assertEquals(fieldData, formData.getFieldData("assoc_bpm_assignee").getValue()); assertEquals(fieldData, formData.getFieldData("assoc_bpm_assignee").getValue());
checkPackageActionGroups(formData);
assertEquals(WorkflowTaskState.IN_PROGRESS, formData.getFieldData("prop_bpm_status").getValue()); assertEquals(WorkflowTaskState.IN_PROGRESS, formData.getFieldData("prop_bpm_status").getValue());
} }
@@ -310,6 +315,16 @@ public class TaskFormProcessorTest extends TestCase
return form; return form;
} }
private void checkPackageActionGroups(FormData formData)
{
FieldData pckgActionData = formData.getFieldData("prop_bpm_packageActionGroup");
assertNotNull(pckgActionData);
assertEquals("", pckgActionData.getValue());
FieldData pckgItemActionData = formData.getFieldData("prop_bpm_packageItemActionGroup");
assertNotNull(pckgItemActionData);
assertEquals("read_package_item_actions", pckgItemActionData.getValue());
}
private void checkSingleProperty(Form form, String fieldName, Serializable fieldData) private void checkSingleProperty(Form form, String fieldName, Serializable fieldData)
{ {
checkSingleField(form, fieldName, fieldData, "prop_"); checkSingleField(form, fieldName, fieldData, "prop_");
@@ -442,6 +457,18 @@ public class TaskFormProcessorTest extends TestCase
PropertyDefinition with_ = MockClassAttributeDefinition.mockPropertyDefinition(PROP_WITH_, textType); PropertyDefinition with_ = MockClassAttributeDefinition.mockPropertyDefinition(PROP_WITH_, textType);
properties.put(PROP_WITH_, with_); properties.put(PROP_WITH_, with_);
// Add a Package Action property
QName pckgActionGroup = WorkflowModel.PROP_PACKAGE_ACTION_GROUP;
PropertyDefinition pckgAction =
MockClassAttributeDefinition.mockPropertyDefinition(pckgActionGroup, textType, "");
properties.put(pckgActionGroup, pckgAction);
// Add a Package Action property
QName pckgItemActionGroup = WorkflowModel.PROP_PACKAGE_ITEM_ACTION_GROUP;
PropertyDefinition pckgItemAction =
MockClassAttributeDefinition.mockPropertyDefinition(pckgItemActionGroup, textType, "read_package_item_actions");
properties.put(pckgItemActionGroup, pckgItemAction);
return properties; return properties;
} }
@@ -504,4 +531,6 @@ public class TaskFormProcessorTest extends TestCase
when(service.updateTask(anyString(), anyMap(), anyMap(), anyMap())).thenReturn(newTask); when(service.updateTask(anyString(), anyMap(), anyMap(), anyMap())).thenReturn(newTask);
return service; return service;
} }
} }

View File

@@ -19,38 +19,32 @@
package org.alfresco.repo.forms.processor.workflow; package org.alfresco.repo.forms.processor.workflow;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import org.alfresco.model.ContentModel; import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData; import org.alfresco.repo.forms.FormData;
import org.alfresco.repo.forms.FormException; import org.alfresco.repo.forms.FormException;
import org.alfresco.repo.forms.FormNotFoundException; import org.alfresco.repo.forms.FormNotFoundException;
import org.alfresco.repo.forms.Item; import org.alfresco.repo.forms.Item;
import org.alfresco.repo.forms.FormData.FieldData; import org.alfresco.repo.forms.FormData.FieldData;
import org.alfresco.repo.forms.processor.FormCreationData;
import org.alfresco.repo.forms.processor.node.ContentModelFormProcessor; import org.alfresco.repo.forms.processor.node.ContentModelFormProcessor;
import org.alfresco.repo.forms.processor.node.ItemData; import org.alfresco.repo.forms.processor.node.ItemData;
import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef; 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.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowInstance; import org.alfresco.service.cmr.workflow.WorkflowInstance;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService; 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.WorkflowTaskDefinition;
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
/** /**
* Temporary FormProcessor implementation that can generate and persist * Temporary FormProcessor implementation that can generate and persist
@@ -66,13 +60,26 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
/** WorkflowService */ /** WorkflowService */
private WorkflowService workflowService; private WorkflowService workflowService;
/** Unprotected Node Service */
private NodeService unprotectedNodeService;
/** TyepdPropertyValueGetter */ /** TyepdPropertyValueGetter */
private TypedPropertyValueGetter valueGetter; private TypedPropertyValueGetter valueGetter;
private DataKeyMatcher keyMatcher; private DataKeyMatcher keyMatcher;
/* (non-Javadoc)
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#generateFields(org.alfresco.repo.forms.Form, java.util.List, org.alfresco.repo.forms.processor.FormCreationData)
*/
@Override
protected void populateForm(Form form, List<String> fields, FormCreationData data)
{
super.populateForm(form, fields, data);
// Add package actions to FormData.
ItemData<?> itemData = (ItemData<?>) data.getItemData();
addPropertyDataIfRequired(WorkflowModel.PROP_PACKAGE_ACTION_GROUP, form, itemData);
addPropertyDataIfRequired(WorkflowModel.PROP_PACKAGE_ITEM_ACTION_GROUP, form, itemData);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.repo.forms.processor.node.ContentModelFormProcessor#getAssociationValues(java.lang.Object) * @see org.alfresco.repo.forms.processor.node.ContentModelFormProcessor#getAssociationValues(java.lang.Object)
*/ */
@@ -139,11 +146,6 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
return logger; return logger;
} }
public void setSmallNodeService(NodeService nodeService)
{
this.unprotectedNodeService = nodeService;
}
/* /*
* @see * @see
* org.alfresco.repo.forms.processor.node.NodeFormProcessor#getTypedItem * org.alfresco.repo.forms.processor.node.NodeFormProcessor#getTypedItem
@@ -226,91 +228,6 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
keyInfo.visit(visitor); keyInfo.visit(visitor);
} }
protected WorkflowInstance oldInternalPersist(WorkflowDefinition workflowDef, final FormData data)
{
if (logger.isDebugEnabled()) logger.debug("Persisting form for: " + workflowDef);
WorkflowInstance workflow = null;
Map<QName, Serializable> params = new HashMap<QName, Serializable>(8);
// create a package for the workflow
NodeRef workflowPackage = this.workflowService.createPackage(null);
params.put(WorkflowModel.ASSOC_PACKAGE, workflowPackage);
// TODO: iterate through form data to collect properties, for now
// just hardcode the ones we know
params.put(WorkflowModel.PROP_DESCRIPTION,
(Serializable)data.getFieldData("prop_bpm_workflowDescription").getValue());
// look for assignee and group assignee
FieldData assigneeField = data.getFieldData("assoc_bpm_assignee_added");
if (assigneeField != null)
{
NodeRef assignee = new NodeRef(assigneeField.getValue().toString());
ArrayList<NodeRef> assigneeList = new ArrayList<NodeRef>(1);
assigneeList.add(assignee);
params.put(WorkflowModel.ASSOC_ASSIGNEE, assigneeList);
}
else
{
Object groupValue = data.getFieldData("assoc_bpm_groupAssignee_added").getValue();
NodeRef group = new NodeRef(groupValue.toString());
ArrayList<NodeRef> groupList = new ArrayList<NodeRef>(1);
groupList.add(group);
params.put(QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "groupAssignee"),
groupList);
}
// add any package items
Object items = data.getFieldData("assoc_packageItems_added").getValue();
if (items != null)
{
String[] nodeRefs = StringUtils.tokenizeToStringArray(items.toString(), ",");
for (int x = 0; x < nodeRefs.length; x++)
{
NodeRef item = new NodeRef(nodeRefs[x]);
this.unprotectedNodeService.addChild(workflowPackage, item,
WorkflowModel.ASSOC_PACKAGE_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
QName.createValidLocalName((String)this.nodeService.getProperty(
item, ContentModel.PROP_NAME))));
}
}
// TODO: add any context (this could re-use alf_destination)
// start the workflow to get access to the start task
WorkflowPath path = this.workflowService.startWorkflow(workflowDef.getId(), params);
if (path != null)
{
// get hold of the workflow instance for returning
workflow = path.instance;
// extract the start task
List<WorkflowTask> tasks = this.workflowService.getTasksForWorkflowPath(path.id);
if (tasks.size() == 1)
{
WorkflowTask startTask = tasks.get(0);
if (logger.isDebugEnabled())
logger.debug("Found start task:" + startTask);
if (startTask.state == WorkflowTaskState.IN_PROGRESS)
{
// end the start task to trigger the first 'proper'
// task in the workflow
this.workflowService.endTask(startTask.id, null);
}
}
if (logger.isDebugEnabled())
logger.debug("Started workflow: " + workflowDef.getId());
}
// return the workflow just started
return workflow;
}
/** /**
* @param workflowService the workflowService to set * @param workflowService the workflowService to set
*/ */

View File

@@ -0,0 +1,29 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.forms.processor.workflow;
/**
* @author Nick Smith
*
*/
public class WorkflowFormProcessorTest
{
}