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

@@ -22,6 +22,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.alfresco.repo.forms.FormData.FieldData;
/**
* Data representation of a form to be displayed in the UI.
*
@@ -168,6 +170,18 @@ public class Form
{
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

View File

@@ -156,6 +156,13 @@ public abstract class FilteredFormProcessor<ItemType, PersistType> extends Abstr
Object itemData = makeItemData(item);
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;
if (fields != null && fields.size() > 0)
{
@@ -166,8 +173,6 @@ public abstract class FilteredFormProcessor<ItemType, PersistType> extends Abstr
fieldsToAdd = generateDefaultFields(data);
}
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.repo.forms.Field;
import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData;
import org.alfresco.repo.forms.FormException;
import org.alfresco.repo.forms.FormData.FieldData;
@@ -197,6 +198,24 @@ public abstract class ContentModelFormProcessor<ItemType, PersistType> extends
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
protected List<Field> generateDefaultFields(FormCreationData data)
{

View File

@@ -25,7 +25,8 @@
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;
@@ -76,6 +77,14 @@ public class MockClassAttributeDefinition implements PropertyDefinition, Associa
mockDataTypeName(dataTypeName, 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,//
QName dataTypeName,//

View File

@@ -94,12 +94,12 @@ public class PropertyFieldProcessor extends QNameFieldProcessor<PropertyDefiniti
}
@Override
protected Object getValue(QName name, ItemData<?> data)
public Object getValue(QName name, ItemData<?> data)
{
Serializable value = data.getPropertyValue(name);
if (value == null)
{
return null;
return getDefaultValue(name, data);
}
if (value instanceof Collection<?>)
@@ -121,6 +121,16 @@ public class PropertyFieldProcessor extends QNameFieldProcessor<PropertyDefiniti
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)
{
String name = getPrefixedName(propDef);

View File

@@ -26,14 +26,18 @@
package org.alfresco.repo.forms.processor.workflow;
import java.io.Serializable;
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.Item;
import org.alfresco.repo.forms.FormData.FieldData;
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.ItemData;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
@@ -84,6 +88,17 @@ public class TaskFormProcessor extends ContentModelFormProcessor<WorkflowTask, W
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
protected WorkflowTask internalPersist(WorkflowTask task, FormData data)
{

View File

@@ -146,6 +146,7 @@ public class TaskFormProcessorTest extends TestCase
fields = Arrays.asList(fullPropertyName);
form = processForm(fields);
checkSingleProperty(form, fieldName, WorkflowTaskState.IN_PROGRESS);
checkPackageActionGroups(form.getFormData());
}
public void testGenerateSingleAssociation()
@@ -163,6 +164,7 @@ public class TaskFormProcessorTest extends TestCase
fields = Arrays.asList(fullAssociationName);
form = processForm(fields);
checkSingleAssociation(form, fieldName, fieldData);
checkPackageActionGroups(form.getFormData());
}
public void testIgnoresUnknownFields() throws Exception
@@ -172,22 +174,25 @@ public class TaskFormProcessorTest extends TestCase
List<String> fields = Arrays.asList(fakeFieldName, statusFieldName);
Form form = processForm(fields);
checkSingleProperty(form, statusFieldName, WorkflowTaskState.IN_PROGRESS);
checkPackageActionGroups(form.getFormData());
}
public void testGenerateDefaultForm() throws Exception
{
Form form = processForm(null);
List<String> fieldDefs = form.getFieldDefinitionNames();
assertEquals(6, fieldDefs.size());
assertEquals(8, 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(6, formData.getNumberOfFields());
assertEquals(fieldData, formData.getFieldData("assoc_bpm_assignee").getValue());
checkPackageActionGroups(formData);
assertEquals(WorkflowTaskState.IN_PROGRESS, formData.getFieldData("prop_bpm_status").getValue());
}
@@ -310,6 +315,16 @@ public class TaskFormProcessorTest extends TestCase
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)
{
checkSingleField(form, fieldName, fieldData, "prop_");
@@ -441,6 +456,18 @@ public class TaskFormProcessorTest extends TestCase
// Add a Status property
PropertyDefinition with_ = MockClassAttributeDefinition.mockPropertyDefinition(PROP_WITH_, textType);
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;
}
@@ -504,4 +531,6 @@ public class TaskFormProcessorTest extends TestCase
when(service.updateTask(anyString(), anyMap(), anyMap(), anyMap())).thenReturn(newTask);
return service;
}
}

View File

@@ -19,38 +19,32 @@
package org.alfresco.repo.forms.processor.workflow;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.FormException;
import org.alfresco.repo.forms.FormNotFoundException;
import org.alfresco.repo.forms.Item;
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.ItemData;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
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;
import org.alfresco.service.cmr.workflow.WorkflowPath;
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.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
/**
* Temporary FormProcessor implementation that can generate and persist
@@ -65,14 +59,27 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
/** WorkflowService */
private WorkflowService workflowService;
/** Unprotected Node Service */
private NodeService unprotectedNodeService;
/** TyepdPropertyValueGetter */
private TypedPropertyValueGetter valueGetter;
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)
* @see org.alfresco.repo.forms.processor.node.ContentModelFormProcessor#getAssociationValues(java.lang.Object)
*/
@@ -138,11 +145,6 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
{
return logger;
}
public void setSmallNodeService(NodeService nodeService)
{
this.unprotectedNodeService = nodeService;
}
/*
* @see
@@ -226,91 +228,6 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
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
*/

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
{
}