mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Created the new WorkflowFormProcessor which processes forms based on a workflow definition name.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21172 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -17,22 +17,23 @@
|
||||
<value>org.alfresco.repo.forms.FormService</value>
|
||||
</property>
|
||||
<property name="target">
|
||||
<ref bean="formService"/>
|
||||
<ref bean="formService" />
|
||||
</property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<idref local="FormService_transaction"/>
|
||||
<idref bean="AuditMethodInterceptor"/>
|
||||
<idref bean="exceptionTranslator"/>
|
||||
<idref local="FormService_security"/>
|
||||
<idref local="FormService_transaction" />
|
||||
<idref bean="AuditMethodInterceptor" />
|
||||
<idref bean="exceptionTranslator" />
|
||||
<idref local="FormService_security" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Form service transaction bean -->
|
||||
<bean id="FormService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||
<bean id="FormService_transaction"
|
||||
class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||
<property name="transactionManager">
|
||||
<ref bean="transactionManager"/>
|
||||
<ref bean="transactionManager" />
|
||||
</property>
|
||||
<property name="transactionAttributes">
|
||||
<props>
|
||||
@@ -42,7 +43,8 @@
|
||||
</bean>
|
||||
|
||||
<!-- Form service security bean -->
|
||||
<bean id="FormService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
|
||||
<bean id="FormService_security"
|
||||
class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
|
||||
|
||||
<bean id="formService" class="org.alfresco.repo.forms.FormServiceImpl">
|
||||
<property name="processorRegistry" ref="formProcessorRegistry" />
|
||||
@@ -52,37 +54,26 @@
|
||||
<bean id="formProcessorRegistry"
|
||||
class="org.alfresco.repo.forms.processor.FormProcessorRegistry" />
|
||||
|
||||
<bean id="nodeFilterRegistry"
|
||||
class="org.alfresco.repo.forms.processor.FilterRegistry" />
|
||||
<bean id="nodeFilterRegistry" class="org.alfresco.repo.forms.processor.FilterRegistry" />
|
||||
|
||||
<bean id="typeFilterRegistry"
|
||||
class="org.alfresco.repo.forms.processor.FilterRegistry" />
|
||||
|
||||
<bean id="workflowFilterRegistry"
|
||||
class="org.alfresco.repo.forms.processor.FilterRegistry" />
|
||||
<bean id="typeFilterRegistry" class="org.alfresco.repo.forms.processor.FilterRegistry" />
|
||||
|
||||
<!-- Form processors -->
|
||||
<bean id="baseFormProcessor" abstract="true" init-method="register"
|
||||
class="org.alfresco.repo.forms.processor.AbstractFormProcessor">
|
||||
class="org.alfresco.repo.forms.processor.node.ContentModelFormProcessor">
|
||||
<property name="processorRegistry" ref="formProcessorRegistry" />
|
||||
</bean>
|
||||
|
||||
<bean id="filteredFormProcessor" abstract="true"
|
||||
class="org.alfresco.repo.forms.processor.FilteredFormProcessor"
|
||||
parent="baseFormProcessor" >
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="contentService" ref="ContentService" />
|
||||
<property name="dictionaryService" ref="DictionaryService" />
|
||||
<property name="fileFolderService" ref="FileFolderService" />
|
||||
<property name="namespaceService" ref="NamespaceService" />
|
||||
<property name="fieldProcessorRegistry" ref="fieldProcessorRegistry" />
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="nodeFormProcessor"
|
||||
class="org.alfresco.repo.forms.processor.node.NodeFormProcessor"
|
||||
parent="filteredFormProcessor">
|
||||
parent="baseFormProcessor">
|
||||
<property name="filterRegistry" ref="nodeFilterRegistry" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="fileFolderService" ref="FileFolderService" />
|
||||
<property name="dictionaryService" ref="DictionaryService" />
|
||||
<property name="namespaceService" ref="NamespaceService" />
|
||||
<property name="contentService" ref="ContentService" />
|
||||
<property name="matchPattern">
|
||||
<value>node</value>
|
||||
</property>
|
||||
@@ -90,34 +81,13 @@
|
||||
|
||||
<bean id="typeFormProcessor"
|
||||
class="org.alfresco.repo.forms.processor.node.TypeFormProcessor"
|
||||
parent="filteredFormProcessor">
|
||||
parent="baseFormProcessor">
|
||||
<property name="filterRegistry" ref="typeFilterRegistry" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="fileFolderService" ref="FileFolderService" />
|
||||
<property name="dictionaryService" ref="DictionaryService" />
|
||||
<property name="namespaceService" ref="NamespaceService" />
|
||||
<property name="contentService" ref="ContentService" />
|
||||
<property name="matchPattern">
|
||||
<value>type</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="workflowFormProcessor"
|
||||
class="org.alfresco.repo.forms.processor.workflow.WorkflowFormProcessor"
|
||||
parent="filteredFormProcessor">
|
||||
<property name="filterRegistry" ref="workflowFilterRegistry" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="smallNodeService" ref="nodeService" />
|
||||
<property name="fileFolderService" ref="FileFolderService" />
|
||||
<property name="dictionaryService" ref="DictionaryService" />
|
||||
<property name="namespaceService" ref="NamespaceService" />
|
||||
<property name="contentService" ref="ContentService" />
|
||||
<property name="workflowService" ref="WorkflowService" />
|
||||
<property name="matchPattern">
|
||||
<value>workflow</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Filters -->
|
||||
<bean id="baseFormFilter" abstract="true" init-method="register"
|
||||
class="org.alfresco.repo.forms.processor.AbstractFilter" />
|
||||
@@ -125,16 +95,16 @@
|
||||
<!--
|
||||
<bean id="imageAspectFormFilter"
|
||||
class="org.alfresco.repo.forms.processor.node.ImageAspectFilter"
|
||||
parent="baseFormFilter">
|
||||
<property name="filterRegistry" ref="nodeFilterRegistry" />
|
||||
</bean>
|
||||
parent="baseFormFilter"> <property name="filterRegistry"
|
||||
ref="nodeFilterRegistry" /> </bean>
|
||||
-->
|
||||
|
||||
<bean id="formServiceScript" parent="baseJavaScriptExtension" class="org.alfresco.repo.forms.script.ScriptFormService">
|
||||
<bean id="formServiceScript" parent="baseJavaScriptExtension"
|
||||
class="org.alfresco.repo.forms.script.ScriptFormService">
|
||||
<property name="extensionName">
|
||||
<value>formService</value>
|
||||
</property>
|
||||
<property name="formService" ref="FormService"/>
|
||||
<property name="formService" ref="FormService" />
|
||||
</bean>
|
||||
|
||||
<!-- Field Processor Config -->
|
||||
@@ -182,4 +152,35 @@
|
||||
class="org.alfresco.repo.forms.processor.node.DefaultFieldProcessor"
|
||||
parent="qnameFieldProcessor" />
|
||||
|
||||
<!-- Workflow Form Processor Config -->
|
||||
|
||||
<bean id="workflowFormProcessor"
|
||||
class="org.alfresco.repo.forms.processor.workflow.WorkflowFormProcessor"
|
||||
parent="baseFormProcessor">
|
||||
<property name="filterRegistry" ref="workflowFilterRegistry" />
|
||||
<property name="smallNodeService" ref="nodeService" />
|
||||
<property name="workflowService" ref="WorkflowService" />
|
||||
<property name="matchPattern">
|
||||
<value>workflow</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="taskFormProcessor"
|
||||
class="org.alfresco.repo.forms.processor.workflow.TaskFormProcessor"
|
||||
parent="baseFormProcessor">
|
||||
<property name="filterRegistry" ref="taskFilterRegistry" />
|
||||
<property name="workflowService" ref="workflowServiceImpl" />
|
||||
<property name="matchPattern">
|
||||
<value>task</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="workflowFilterRegistry" class="org.alfresco.repo.forms.processor.FilterRegistry" />
|
||||
|
||||
<bean id="taskFilterRegistry" class="org.alfresco.repo.forms.processor.FilterRegistry" />
|
||||
|
||||
<bean id="packageItemsFieldProcessor"
|
||||
class="org.alfresco.repo.forms.processor.workflow.PackageItemsFieldProcessor"
|
||||
parent="baseFieldProcessor" />
|
||||
|
||||
</beans>
|
||||
|
@@ -6,3 +6,6 @@ form_service.encoding.label=Encoding
|
||||
form_service.encoding.description=Encoding of the content
|
||||
form_service.size.label=Size
|
||||
form_service.size.description=Size of the content in bytes
|
||||
|
||||
form_service.package.items.label=Items
|
||||
form_service.package.items.description=Items that are part of the workflow
|
@@ -35,13 +35,11 @@ public class ContentField implements Field
|
||||
{
|
||||
private final FieldDefinition fieldDefinition;
|
||||
private final ClassAttributeDefinition classDefinition;
|
||||
private final boolean isProperty;
|
||||
private final Object value;
|
||||
|
||||
public ContentField(PropertyDefinition propertyDefinition,
|
||||
PropertyFieldDefinition fieldDef, Object value)
|
||||
{
|
||||
this.isProperty = true;
|
||||
this.classDefinition = propertyDefinition;
|
||||
this.fieldDefinition = fieldDef;
|
||||
this.value = value;
|
||||
@@ -50,7 +48,6 @@ public class ContentField implements Field
|
||||
public ContentField(AssociationDefinition assocDefinition,
|
||||
AssociationFieldDefinition fieldDef, Object value)
|
||||
{
|
||||
this.isProperty = false;
|
||||
this.classDefinition = assocDefinition;
|
||||
this.fieldDefinition = fieldDef;
|
||||
this.value = value;
|
||||
@@ -60,10 +57,9 @@ public class ContentField implements Field
|
||||
* This constructor should only be used to create FieldInfo for transient properties such as encoding, mimetype or size.
|
||||
* @param fieldDef The PropertyFieldDefinition for the transient property.
|
||||
*/
|
||||
public ContentField(PropertyFieldDefinition fieldDef, Object value)
|
||||
public ContentField(FieldDefinition fieldDef, Object value)
|
||||
{
|
||||
this.classDefinition = null;
|
||||
this.isProperty = true;
|
||||
this.fieldDefinition = fieldDef;
|
||||
this.value = value;
|
||||
}
|
||||
@@ -76,6 +72,14 @@ public class ContentField implements Field
|
||||
return classDefinition == null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.task.Field#isTransient()
|
||||
*/
|
||||
public boolean isProperty()
|
||||
{
|
||||
return fieldDefinition instanceof PropertyFieldDefinition;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.task.Field#getFieldDefinition()
|
||||
*/
|
||||
@@ -112,7 +116,7 @@ public class ContentField implements Field
|
||||
public String toString()
|
||||
{
|
||||
String type = isTransient()?"Transient ":"";
|
||||
type += isProperty ? "Property" : "Association";
|
||||
type += isProperty() ? "Property" : "Association";
|
||||
return "Field: " + getFieldName() + " Type: " + type;
|
||||
}
|
||||
|
||||
|
@@ -244,108 +244,6 @@ public abstract class ContentModelFormProcessor<ItemType, PersistType> extends
|
||||
|
||||
protected abstract TypeDefinition getBaseType(ItemType item);
|
||||
|
||||
/**
|
||||
* Generates the field definition for the transient mimetype property
|
||||
*
|
||||
* @param content The ContentData object to generate the field from
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateMimetypePropertyField(ContentData content, Form form)
|
||||
{
|
||||
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_MIMETYPE;
|
||||
PropertyFieldDefinition mimetypeField = new PropertyFieldDefinition(TRANSIENT_MIMETYPE, DataTypeDefinition.TEXT
|
||||
.getLocalName());
|
||||
mimetypeField.setLabel(I18NUtil.getMessage(MSG_MIMETYPE_LABEL));
|
||||
mimetypeField.setDescription(I18NUtil.getMessage(MSG_MIMETYPE_DESC));
|
||||
mimetypeField.setDataKeyName(dataKeyName);
|
||||
form.addFieldDefinition(mimetypeField);
|
||||
|
||||
if (content != null)
|
||||
{
|
||||
form.addData(dataKeyName, content.getMimetype());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the field definition for the transient encoding property
|
||||
*
|
||||
* @param content The ContentData object to generate the field from
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateEncodingPropertyField(ContentData content, Form form)
|
||||
{
|
||||
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_ENCODING;
|
||||
PropertyFieldDefinition encodingField = new PropertyFieldDefinition(TRANSIENT_ENCODING, DataTypeDefinition.TEXT
|
||||
.getLocalName());
|
||||
encodingField.setLabel(I18NUtil.getMessage(MSG_ENCODING_LABEL));
|
||||
encodingField.setDescription(I18NUtil.getMessage(MSG_ENCODING_DESC));
|
||||
encodingField.setDataKeyName(dataKeyName);
|
||||
form.addFieldDefinition(encodingField);
|
||||
|
||||
if (content != null)
|
||||
{
|
||||
form.addData(dataKeyName, content.getEncoding());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the field definition for the transient size property
|
||||
*
|
||||
* @param content The ContentData object to generate the field from
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateSizePropertyField(ContentData content, Form form)
|
||||
{
|
||||
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_SIZE;
|
||||
PropertyFieldDefinition sizeField = new PropertyFieldDefinition(TRANSIENT_SIZE, DataTypeDefinition.LONG
|
||||
.getLocalName());
|
||||
sizeField.setLabel(I18NUtil.getMessage(MSG_SIZE_LABEL));
|
||||
sizeField.setDescription(I18NUtil.getMessage(MSG_SIZE_DESC));
|
||||
sizeField.setDataKeyName(dataKeyName);
|
||||
sizeField.setProtectedField(true);
|
||||
form.addFieldDefinition(sizeField);
|
||||
|
||||
if (content != null)
|
||||
{
|
||||
form.addData(dataKeyName, new Long(content.getSize()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given node represents a working copy, if it does
|
||||
* the name field is searched for and set to protected as the name field
|
||||
* should not be edited for a working copy.
|
||||
*
|
||||
* If the node is not a working copy this method has no effect.
|
||||
*
|
||||
* @param nodeRef NodeRef of node to check and potentially process
|
||||
* @param form The generated form
|
||||
*/
|
||||
protected void processWorkingCopy(NodeRef nodeRef, Form form)
|
||||
{
|
||||
// if the node is a working copy ensure that the name field (id present)
|
||||
// is set to be protected as it can not be edited
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
// go through fields looking for name field
|
||||
for (FieldDefinition fieldDef : form.getFieldDefinitions())
|
||||
{
|
||||
if (fieldDef.getName().equals(ContentModel.PROP_NAME.toPrefixString(this.namespaceService)))
|
||||
{
|
||||
fieldDef.setProtectedField(true);
|
||||
|
||||
if (getLogger().isDebugEnabled())
|
||||
{
|
||||
getLogger().debug("Set " + ContentModel.PROP_NAME.toPrefixString(this.namespaceService) +
|
||||
"field to protected as it is a working copy");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the values of the given association definition on the given
|
||||
* node.
|
||||
|
@@ -27,6 +27,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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;
|
||||
import org.alfresco.repo.forms.Item;
|
||||
@@ -223,6 +225,52 @@ public class NodeFormProcessor extends ContentModelFormProcessor<NodeRef, NodeRe
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given node represents a working copy, if it does
|
||||
* the name field is searched for and set to protected as the name field
|
||||
* should not be edited for a working copy.
|
||||
*
|
||||
* If the node is not a working copy this method has no effect.
|
||||
*
|
||||
* @param nodeRef NodeRef of node to check and potentially process
|
||||
* @param form The generated form
|
||||
*/
|
||||
protected void processWorkingCopy(NodeRef nodeRef, Form form)
|
||||
{
|
||||
// if the node is a working copy ensure that the name field (id present)
|
||||
// is set to be protected as it can not be edited
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
// go through fields looking for name field
|
||||
for (FieldDefinition fieldDef : form.getFieldDefinitions())
|
||||
{
|
||||
if (fieldDef.getName().equals(ContentModel.PROP_NAME.toPrefixString(this.namespaceService)))
|
||||
{
|
||||
fieldDef.setProtectedField(true);
|
||||
|
||||
if (getLogger().isDebugEnabled())
|
||||
{
|
||||
getLogger().debug("Set " + ContentModel.PROP_NAME.toPrefixString(this.namespaceService) +
|
||||
"field to protected as it is a working copy");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#internalGenerate(java.lang.Object, java.util.List, java.util.List, org.alfresco.repo.forms.Form, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected void internalGenerate(NodeRef item, List<String> fields, List<String> forcedFields, Form form,
|
||||
Map<String, Object> context)
|
||||
{
|
||||
super.internalGenerate(item, fields, forcedFields, form, context);
|
||||
processWorkingCopy(item, form);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.alfresco.repo.forms.processor.FilteredFormProcessor#internalPersist
|
||||
|
@@ -22,6 +22,7 @@ package org.alfresco.repo.forms.processor.node;
|
||||
import static org.alfresco.repo.forms.processor.node.FormFieldConstants.PROP_DATA_PREFIX;
|
||||
import static org.alfresco.repo.forms.processor.node.FormFieldConstants.TRANSIENT_ENCODING;
|
||||
|
||||
import org.alfresco.repo.forms.FieldDefinition;
|
||||
import org.alfresco.repo.forms.PropertyFieldDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -42,7 +43,7 @@ public class TransientEncodingFieldProcessor extends TransientFieldProcessor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyFieldDefinition makeTransientPropertyDefinition()
|
||||
protected FieldDefinition makeTransientPropertyDefinition()
|
||||
{
|
||||
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_ENCODING;
|
||||
PropertyFieldDefinition encodingField = new PropertyFieldDefinition(TRANSIENT_ENCODING,
|
||||
|
@@ -20,6 +20,7 @@
|
||||
package org.alfresco.repo.forms.processor.node;
|
||||
|
||||
import org.alfresco.repo.forms.Field;
|
||||
import org.alfresco.repo.forms.FieldDefinition;
|
||||
import org.alfresco.repo.forms.PropertyFieldDefinition;
|
||||
import org.alfresco.repo.forms.processor.AbstractFieldProcessor;
|
||||
import org.alfresco.repo.forms.processor.FormCreationData;
|
||||
@@ -32,7 +33,7 @@ public abstract class TransientFieldProcessor extends AbstractFieldProcessor<Tra
|
||||
@Override
|
||||
protected Field generateTypedField(String fieldName, FormCreationData formData, TransientValueGetter typedData)
|
||||
{
|
||||
PropertyFieldDefinition transientPropDef = makeTransientPropertyDefinition();
|
||||
FieldDefinition transientPropDef = makeTransientPropertyDefinition();
|
||||
Field fieldInfo = null;
|
||||
Object value = getValue(fieldName, typedData);
|
||||
if (transientPropDef != null)
|
||||
@@ -59,5 +60,5 @@ public abstract class TransientFieldProcessor extends AbstractFieldProcessor<Tra
|
||||
return TransientValueGetter.class;
|
||||
}
|
||||
|
||||
protected abstract PropertyFieldDefinition makeTransientPropertyDefinition();
|
||||
protected abstract FieldDefinition makeTransientPropertyDefinition();
|
||||
}
|
@@ -22,6 +22,7 @@ package org.alfresco.repo.forms.processor.node;
|
||||
import static org.alfresco.repo.forms.processor.node.FormFieldConstants.PROP_DATA_PREFIX;
|
||||
import static org.alfresco.repo.forms.processor.node.FormFieldConstants.TRANSIENT_MIMETYPE;
|
||||
|
||||
import org.alfresco.repo.forms.FieldDefinition;
|
||||
import org.alfresco.repo.forms.PropertyFieldDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -40,7 +41,7 @@ public class TransientMimetypeFieldProcessor extends TransientFieldProcessor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyFieldDefinition makeTransientPropertyDefinition() {
|
||||
protected FieldDefinition makeTransientPropertyDefinition() {
|
||||
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_MIMETYPE;
|
||||
PropertyFieldDefinition mimetypeField = new PropertyFieldDefinition(TRANSIENT_MIMETYPE, DataTypeDefinition.TEXT
|
||||
.getLocalName());
|
||||
|
@@ -22,6 +22,7 @@ package org.alfresco.repo.forms.processor.node;
|
||||
import static org.alfresco.repo.forms.processor.node.FormFieldConstants.PROP_DATA_PREFIX;
|
||||
import static org.alfresco.repo.forms.processor.node.FormFieldConstants.TRANSIENT_SIZE;
|
||||
|
||||
import org.alfresco.repo.forms.FieldDefinition;
|
||||
import org.alfresco.repo.forms.PropertyFieldDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -41,7 +42,7 @@ public class TransientSizeFieldProcessor extends TransientFieldProcessor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyFieldDefinition makeTransientPropertyDefinition()
|
||||
protected FieldDefinition makeTransientPropertyDefinition()
|
||||
{
|
||||
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_SIZE;
|
||||
PropertyFieldDefinition sizeField = new PropertyFieldDefinition(TRANSIENT_SIZE,
|
||||
|
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.alfresco.repo.forms.AssociationFieldDefinition;
|
||||
import org.alfresco.repo.forms.FieldDefinition;
|
||||
import org.alfresco.repo.forms.AssociationFieldDefinition.Direction;
|
||||
import org.alfresco.repo.forms.processor.FieldProcessor;
|
||||
import org.alfresco.repo.forms.processor.node.TransientFieldProcessor;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
import static org.alfresco.repo.forms.processor.node.FormFieldConstants.ASSOC_DATA_PREFIX;
|
||||
|
||||
/**
|
||||
* {@link FieldProcessor} for handling package contents when displaying Workflow and Task Forms.
|
||||
* @author Nick Smith
|
||||
*/
|
||||
public class PackageItemsFieldProcessor extends TransientFieldProcessor
|
||||
{
|
||||
/** Logger */
|
||||
private final static Log logger = LogFactory.getLog(PackageItemsFieldProcessor.class);
|
||||
|
||||
public static final String KEY = "packageItems";
|
||||
|
||||
private static final String MSG_LABEL = "form_service.package.items.label";
|
||||
private static final String MSG_DESCRIPTION = "form_service.package.items.description";
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.node.TransientFieldProcessor#makeTransientPropertyDefinition()
|
||||
*/
|
||||
@Override
|
||||
protected FieldDefinition makeTransientPropertyDefinition()
|
||||
{
|
||||
AssociationFieldDefinition fieldDef = new AssociationFieldDefinition(
|
||||
KEY, "cm:content", Direction.TARGET);
|
||||
fieldDef.setLabel(I18NUtil.getMessage(MSG_LABEL));
|
||||
fieldDef.setDescription(I18NUtil.getMessage(MSG_DESCRIPTION));
|
||||
fieldDef.setProtectedField(false);
|
||||
fieldDef.setEndpointMandatory(false);
|
||||
fieldDef.setEndpointMany(true);
|
||||
|
||||
// define the data key name and set
|
||||
String dataKey = ASSOC_DATA_PREFIX + KEY;
|
||||
fieldDef.setDataKeyName(dataKey);
|
||||
return fieldDef;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.AbstractFieldProcessor#getLogger()
|
||||
*/
|
||||
@Override
|
||||
protected Log getLogger()
|
||||
{
|
||||
return logger;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.AbstractFieldProcessor#getRegistryKey()
|
||||
*/
|
||||
@Override
|
||||
protected String getRegistryKey()
|
||||
{
|
||||
return KEY;
|
||||
}
|
||||
|
||||
}
|
@@ -24,40 +24,22 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.forms.AssociationFieldDefinition;
|
||||
import org.alfresco.repo.forms.FieldGroup;
|
||||
import org.alfresco.repo.forms.Form;
|
||||
import org.alfresco.repo.forms.FormData;
|
||||
import org.alfresco.repo.forms.FormNotFoundException;
|
||||
import org.alfresco.repo.forms.Item;
|
||||
import org.alfresco.repo.forms.PropertyFieldDefinition;
|
||||
import org.alfresco.repo.forms.AssociationFieldDefinition.Direction;
|
||||
import org.alfresco.repo.forms.PropertyFieldDefinition.FieldConstraint;
|
||||
import org.alfresco.repo.forms.processor.node.ContentModelFormProcessor;
|
||||
import org.alfresco.repo.forms.processor.node.PeriodDataTypeParameters;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.Period;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
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;
|
||||
@@ -69,39 +51,78 @@ import org.springframework.util.StringUtils;
|
||||
* Temporary FormProcessor implementation that can generate and persist
|
||||
* Form objects for workflow definitions.
|
||||
*
|
||||
* @author Gavin Cornwell
|
||||
* @author Nick Smith
|
||||
*/
|
||||
public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDefinition, WorkflowInstance>
|
||||
{
|
||||
/** Logger */
|
||||
private static Log logger = LogFactory.getLog(WorkflowFormProcessor.class);
|
||||
private final static Log logger = LogFactory.getLog(WorkflowFormProcessor.class);
|
||||
|
||||
public static final String TRANSIENT_PACKAGE_ITEMS = "packageItems";
|
||||
/** WorkflowService */
|
||||
private WorkflowService workflowService;
|
||||
|
||||
/** workflow service */
|
||||
protected WorkflowService workflowService;
|
||||
/** Unprotected Node Service */
|
||||
private NodeService unprotectedNodeService;
|
||||
|
||||
protected NodeService unprotectedNodeService;
|
||||
|
||||
/**
|
||||
* Sets the workflow service
|
||||
*
|
||||
* @param workflowService The WorkflowService instance
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.node.ContentModelFormProcessor#getAssociationValues(java.lang.Object)
|
||||
*/
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
@Override
|
||||
protected Map<QName, Serializable> getAssociationValues(WorkflowDefinition item)
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSmallNodeService(NodeService nodeService)
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.node.ContentModelFormProcessor#getBaseType(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected TypeDefinition getBaseType(WorkflowDefinition item)
|
||||
{
|
||||
this.unprotectedNodeService = nodeService;
|
||||
//TODO I'm not sure this is safe as getStartTaskDefinition() is 'optional'.
|
||||
WorkflowTaskDefinition startTask = item.getStartTaskDefinition();
|
||||
return startTask.getMetadata();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.alfresco.repo.forms.processor.node.ContentModelFormProcessor#getLogger
|
||||
* ()
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.node.ContentModelFormProcessor#getPropertyValues(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected Map<QName, Serializable> getPropertyValues(WorkflowDefinition item)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.node.ContentModelFormProcessor#getTransientValues(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected Map<String, Object> getTransientValues(WorkflowDefinition item)
|
||||
{
|
||||
return Collections.<String, Object>singletonMap(
|
||||
PackageItemsFieldProcessor.KEY, Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#getItemType(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected String getItemType(WorkflowDefinition item)
|
||||
{
|
||||
return item.name;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#getItemURI(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected String getItemURI(WorkflowDefinition item)
|
||||
{
|
||||
return "api/workflow-definitions/"+item.id;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#getLogger()
|
||||
*/
|
||||
@Override
|
||||
protected Log getLogger()
|
||||
@@ -109,6 +130,11 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
|
||||
return logger;
|
||||
}
|
||||
|
||||
public void setSmallNodeService(NodeService nodeService)
|
||||
{
|
||||
this.unprotectedNodeService = nodeService;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.alfresco.repo.forms.processor.node.NodeFormProcessor#getTypedItem
|
||||
@@ -117,151 +143,47 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
|
||||
@Override
|
||||
protected WorkflowDefinition getTypedItem(Item item)
|
||||
{
|
||||
WorkflowDefinition workflowDef = null;
|
||||
|
||||
try
|
||||
{
|
||||
// item id could be the raw workflow definition name or it could be
|
||||
// in a URL friendly format
|
||||
String workflowDefName = item.getId();
|
||||
if (workflowDefName.indexOf("$") == -1)
|
||||
String itemId = item.getId();
|
||||
return getWorkflowDefinitionForName(itemId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// decode the itemId
|
||||
workflowDefName = workflowDefName.replace("jbpm_", "jbpm$");
|
||||
workflowDefName = workflowDefName.replace('_', ':');
|
||||
throw new FormNotFoundException(item, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the workflow definition
|
||||
workflowDef = this.workflowService.getDefinitionByName(workflowDefName);
|
||||
|
||||
private WorkflowDefinition getWorkflowDefinitionForName(String itemId)
|
||||
{
|
||||
String workflowDefName = decodeWorkflowDefinitionName(itemId);
|
||||
WorkflowDefinition workflowDef = workflowService.getDefinitionByName(workflowDefName);
|
||||
if (workflowDef == null)
|
||||
{
|
||||
throw new FormNotFoundException(item,
|
||||
new IllegalArgumentException("Workflow definition does not exist: " + item.getId()));
|
||||
String msg = "Workflow definition does not exist: " + itemId;
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
}
|
||||
catch (WorkflowException we)
|
||||
{
|
||||
throw new FormNotFoundException(item, we);
|
||||
}
|
||||
|
||||
// return the type definition object for the requested type
|
||||
return workflowDef;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.alfresco.repo.forms.processor.FilteredFormProcessor#internalGenerate
|
||||
* (java.lang.Object, java.util.List, java.util.List,
|
||||
* org.alfresco.repo.forms.Form, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
protected void internalGenerate(WorkflowDefinition workflowDef, List<String> fields,
|
||||
List<String> forcedFields, Form form, Map<String, Object> context)
|
||||
{
|
||||
if (logger.isDebugEnabled()) logger.debug("Generating form for item: " + workflowDef);
|
||||
|
||||
// generate the form for the workflow definition
|
||||
form.getItem().setType(workflowDef.name);
|
||||
form.getItem().setUrl("/api/workflow-definition/" + workflowDef.id);
|
||||
|
||||
// get the type of the start task for the workflow definition
|
||||
TypeDefinition typeDef = workflowDef.getStartTaskDefinition().metadata;
|
||||
|
||||
if (fields != null && fields.size() > 0)
|
||||
{
|
||||
generateSelectedFields(null, typeDef, fields, forcedFields, form);
|
||||
}
|
||||
else
|
||||
{
|
||||
// setup field definitions and data
|
||||
generateAllPropertyFields(typeDef, form);
|
||||
generateAllAssociationFields(typeDef, form);
|
||||
}
|
||||
|
||||
// add the "packageItems" transient field
|
||||
generatePackageItemsTransientField(form);
|
||||
|
||||
if (logger.isDebugEnabled()) logger.debug("Generating form: " + form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the 'packageItems' field
|
||||
* The itemId may be in a URL/Webscript-friendly format. If so it must be converted
|
||||
* back to the proper workflow definition name.
|
||||
*
|
||||
* @param form The Form instance to populate
|
||||
* @param itemId
|
||||
*/
|
||||
protected void generatePackageItemsTransientField(Form form)
|
||||
private String decodeWorkflowDefinitionName(String itemId)
|
||||
{
|
||||
// setup basic field info
|
||||
AssociationFieldDefinition fieldDef = new AssociationFieldDefinition(TRANSIENT_PACKAGE_ITEMS,
|
||||
"cm:content", Direction.TARGET);
|
||||
fieldDef.setLabel("Items");
|
||||
fieldDef.setDescription("Items that are part of the workflow");
|
||||
fieldDef.setProtectedField(false);
|
||||
fieldDef.setEndpointMandatory(false);
|
||||
fieldDef.setEndpointMany(true);
|
||||
|
||||
// define the data key name and set
|
||||
fieldDef.setDataKeyName(ASSOC_DATA_PREFIX + TRANSIENT_PACKAGE_ITEMS);
|
||||
|
||||
// add definition to the form
|
||||
form.addFieldDefinition(fieldDef);
|
||||
String defName = itemId;
|
||||
if (itemId.contains("$")==false)
|
||||
{
|
||||
defName = itemId.replaceFirst("_", "$");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for all the type's properties.
|
||||
*
|
||||
* @param typeDef The type being setup
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateAllPropertyFields(TypeDefinition typeDef, Form form)
|
||||
if (itemId.contains(":")==false)
|
||||
{
|
||||
// iterate round the property defintions and setup field definition
|
||||
Map<QName, PropertyDefinition> propDefs = typeDef.getProperties();
|
||||
for (PropertyDefinition propDef : propDefs.values())
|
||||
{
|
||||
generatePropertyField(propDef, form, this.namespaceService);
|
||||
}
|
||||
|
||||
// get all default aspects for the type and iterate round their
|
||||
// property definitions too
|
||||
List<AspectDefinition> aspects = typeDef.getDefaultAspects(true);
|
||||
for (AspectDefinition aspect : aspects)
|
||||
{
|
||||
propDefs = aspect.getProperties();
|
||||
for (PropertyDefinition propDef : propDefs.values())
|
||||
{
|
||||
generatePropertyField(propDef, form, this.namespaceService);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for all the type's associations.
|
||||
*
|
||||
* @param typeDef The type being setup
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateAllAssociationFields(TypeDefinition typeDef, Form form)
|
||||
{
|
||||
// iterate round the association defintions and setup field definition
|
||||
Map<QName, AssociationDefinition> assocDefs = typeDef.getAssociations();
|
||||
for (AssociationDefinition assocDef : assocDefs.values())
|
||||
{
|
||||
generateAssociationField(assocDef, form, this.namespaceService);
|
||||
}
|
||||
|
||||
// get all default aspects for the type and iterate round their
|
||||
// association definitions too
|
||||
List<AspectDefinition> aspects = typeDef.getDefaultAspects(true);
|
||||
for (AspectDefinition aspect : aspects)
|
||||
{
|
||||
assocDefs = aspect.getAssociations();
|
||||
for (AssociationDefinition assocDef : assocDefs.values())
|
||||
{
|
||||
generateAssociationField(assocDef, form, this.namespaceService);
|
||||
}
|
||||
defName = defName.replaceFirst("_", ":");
|
||||
}
|
||||
return defName;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -341,595 +263,10 @@ public class WorkflowFormProcessor extends ContentModelFormProcessor<WorkflowDef
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a field definition for the given property.
|
||||
* <p>
|
||||
* NOTE: This method is static so that it can serve as a helper method for
|
||||
* FormFilter implementations as adding additional property fields is likely
|
||||
* to be a common extension.
|
||||
* </p>
|
||||
*
|
||||
* @param propDef The PropertyDefinition of the field to generate
|
||||
* @param form The Form instance to populate
|
||||
* @param namespaceService NamespaceService instance
|
||||
* @param workflowService the workflowService to set
|
||||
*/
|
||||
protected void generatePropertyField(PropertyDefinition propDef, Form form, NamespaceService namespaceService)
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
{
|
||||
generatePropertyField(propDef, form, null, null, namespaceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a field definition for the given property.
|
||||
* <p>
|
||||
* NOTE: This method is static so that it can serve as a helper method for
|
||||
* FormFilter implementations as adding additional property fields is likely
|
||||
* to be a common extension.
|
||||
* </p>
|
||||
*
|
||||
* @param propDef The PropertyDefinition of the field to generate
|
||||
* @param form The Form instance to populate
|
||||
* @param propValue The value of the property field
|
||||
* @param namespaceService NamespaceService instance
|
||||
*/
|
||||
protected void generatePropertyField(PropertyDefinition propDef, Form form, Serializable propValue,
|
||||
NamespaceService namespaceService)
|
||||
{
|
||||
generatePropertyField(propDef, form, propValue, null, namespaceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a field definition for the given property.
|
||||
* <p>
|
||||
* NOTE: This method is static so that it can serve as a helper method for
|
||||
* FormFilter implementations as adding additional property fields is likely
|
||||
* to be a common extension.
|
||||
* </p>
|
||||
*
|
||||
* @param propDef The PropertyDefinition of the field to generate
|
||||
* @param form The Form instance to populate
|
||||
* @param propValue The value of the property field
|
||||
* @param group The FieldGroup the property field belongs to, can be null
|
||||
* @param namespaceService NamespaceService instance
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generatePropertyField(PropertyDefinition propDef, Form form, Serializable propValue,
|
||||
FieldGroup group, NamespaceService namespaceService)
|
||||
{
|
||||
String propName = propDef.getName().toPrefixString(namespaceService);
|
||||
String[] nameParts = QName.splitPrefixedQName(propName);
|
||||
PropertyFieldDefinition fieldDef = new PropertyFieldDefinition(propName, propDef.getDataType().getName()
|
||||
.getLocalName());
|
||||
|
||||
String title = propDef.getTitle();
|
||||
if (title == null)
|
||||
{
|
||||
title = propName;
|
||||
}
|
||||
fieldDef.setLabel(title);
|
||||
fieldDef.setDefaultValue(propDef.getDefaultValue());
|
||||
fieldDef.setDescription(propDef.getDescription());
|
||||
fieldDef.setMandatory(propDef.isMandatory());
|
||||
fieldDef.setProtectedField(propDef.isProtected());
|
||||
fieldDef.setRepeating(propDef.isMultiValued());
|
||||
fieldDef.setGroup(group);
|
||||
|
||||
// any property from the system model (sys prefix) should be protected
|
||||
// the model doesn't currently enforce this so make sure they are not
|
||||
// editable
|
||||
if (NamespaceService.SYSTEM_MODEL_1_0_URI.equals(propDef.getName().getNamespaceURI()))
|
||||
{
|
||||
fieldDef.setProtectedField(true);
|
||||
}
|
||||
|
||||
// define the data key name and set
|
||||
String dataKeyName = PROP_DATA_PREFIX + nameParts[0] + DATA_KEY_SEPARATOR + nameParts[1];
|
||||
fieldDef.setDataKeyName(dataKeyName);
|
||||
|
||||
// setup any parameters requried for the data type
|
||||
if (propDef.getDataType().getName().equals(DataTypeDefinition.PERIOD))
|
||||
{
|
||||
// if the property data type is d:period we need to setup a data
|
||||
// type parameters object to represent the options and rules
|
||||
PeriodDataTypeParameters periodOptions = new PeriodDataTypeParameters();
|
||||
Set<String> providers = Period.getProviderNames();
|
||||
for (String provider : providers)
|
||||
{
|
||||
periodOptions.addPeriodProvider(Period.getProvider(provider));
|
||||
}
|
||||
|
||||
fieldDef.setDataTypeParameters(periodOptions);
|
||||
}
|
||||
|
||||
// setup constraints for the property
|
||||
List<ConstraintDefinition> constraints = propDef.getConstraints();
|
||||
if (constraints != null && constraints.size() > 0)
|
||||
{
|
||||
List<FieldConstraint> fieldConstraints = new ArrayList<FieldConstraint>(constraints.size());
|
||||
|
||||
for (ConstraintDefinition constraintDef : constraints)
|
||||
{
|
||||
Constraint constraint = constraintDef.getConstraint();
|
||||
FieldConstraint fieldConstraint = new FieldConstraint(constraint.getType(), constraint.getParameters());
|
||||
fieldConstraints.add(fieldConstraint);
|
||||
}
|
||||
|
||||
fieldDef.setConstraints(fieldConstraints);
|
||||
}
|
||||
|
||||
form.addFieldDefinition(fieldDef);
|
||||
|
||||
// add the property value to the form
|
||||
if (propValue != null)
|
||||
{
|
||||
if (propValue instanceof List)
|
||||
{
|
||||
// temporarily add repeating field data as a comma
|
||||
// separated list, this will be changed to using
|
||||
// a separate field for each value once we have full
|
||||
// UI support in place.
|
||||
propValue = StringUtils.collectionToCommaDelimitedString((List) propValue);
|
||||
}
|
||||
else if (propValue instanceof ContentData)
|
||||
{
|
||||
// for content properties retrieve the info URL rather than the
|
||||
// the object value itself
|
||||
propValue = ((ContentData)propValue).getInfoUrl();
|
||||
}
|
||||
|
||||
form.addData(dataKeyName, propValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a field definition for the given association.
|
||||
* <p>
|
||||
* NOTE: This method is static so that it can serve as a helper method for
|
||||
* FormFilter implementations as adding additional association fields is
|
||||
* likely to be a common extension.
|
||||
* </p>
|
||||
*
|
||||
* @param assocDef The AssociationDefinition of the field to generate
|
||||
* @param form The Form instance to populate
|
||||
* @param namespaceService NamespaceService instance
|
||||
*/
|
||||
protected void generateAssociationField(AssociationDefinition assocDef, Form form,
|
||||
NamespaceService namespaceService)
|
||||
{
|
||||
generateAssociationField(assocDef, form, null, null, namespaceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a field definition for the given association.
|
||||
* <p>
|
||||
* NOTE: This method is static so that it can serve as a helper method for
|
||||
* FormFilter implementations as adding additional association fields is
|
||||
* likely to be a common extension.
|
||||
* </p>
|
||||
*
|
||||
* @param assocDef The AssociationDefinition of the field to generate
|
||||
* @param form The Form instance to populate
|
||||
* @param assocValues The values of the association field, can be null
|
||||
* @param namespaceService NamespaceService instance
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generateAssociationField(AssociationDefinition assocDef, Form form, List assocValues,
|
||||
NamespaceService namespaceService)
|
||||
{
|
||||
generateAssociationField(assocDef, form, assocValues, null, namespaceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a field definition for the given association.
|
||||
* <p>
|
||||
* NOTE: This method is static so that it can serve as a helper method for
|
||||
* FormFilter implementations as adding additional association fields is
|
||||
* likely to be a common extension.
|
||||
* </p>
|
||||
*
|
||||
* @param assocDef The AssociationDefinition of the field to generate
|
||||
* @param form The Form instance to populate
|
||||
* @param assocValues The values of the association field, can be null
|
||||
* @param group The FieldGroup the association field belongs to, can be null
|
||||
* @param namespaceService NamespaceService instance
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static void generateAssociationField(AssociationDefinition assocDef, Form form, List assocValues,
|
||||
FieldGroup group, NamespaceService namespaceService)
|
||||
{
|
||||
String assocName = assocDef.getName().toPrefixString(namespaceService);
|
||||
String[] nameParts = QName.splitPrefixedQName(assocName);
|
||||
AssociationFieldDefinition fieldDef = new AssociationFieldDefinition(assocName, assocDef.getTargetClass()
|
||||
.getName().toPrefixString(namespaceService), Direction.TARGET);
|
||||
String title = assocDef.getTitle();
|
||||
if (title == null)
|
||||
{
|
||||
title = assocName;
|
||||
}
|
||||
fieldDef.setLabel(title);
|
||||
fieldDef.setDescription(assocDef.getDescription());
|
||||
fieldDef.setProtectedField(assocDef.isProtected());
|
||||
fieldDef.setEndpointMandatory(assocDef.isTargetMandatory());
|
||||
fieldDef.setEndpointMany(assocDef.isTargetMany());
|
||||
fieldDef.setGroup(group);
|
||||
|
||||
// define the data key name and set
|
||||
String dataKeyName = ASSOC_DATA_PREFIX + nameParts[0] + DATA_KEY_SEPARATOR + nameParts[1];
|
||||
fieldDef.setDataKeyName(dataKeyName);
|
||||
|
||||
// add definition to the form
|
||||
form.addFieldDefinition(fieldDef);
|
||||
|
||||
if (assocValues != null)
|
||||
{
|
||||
// add the association value to the form
|
||||
// determine the type of association values data and extract
|
||||
// accordingly
|
||||
List<String> values = new ArrayList<String>(4);
|
||||
for (Object value : assocValues)
|
||||
{
|
||||
if (value instanceof ChildAssociationRef)
|
||||
{
|
||||
values.add(((ChildAssociationRef) value).getChildRef().toString());
|
||||
}
|
||||
else if (value instanceof AssociationRef)
|
||||
{
|
||||
values.add(((AssociationRef) value).getTargetRef().toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
values.add(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the list as the value for the association.
|
||||
form.addData(dataKeyName, values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for all the requested fields.
|
||||
* <p>
|
||||
* A NodeRef or TypeDefinition can be provided, however, if a NodeRef is
|
||||
* provided all type information will be derived from the NodeRef and the
|
||||
* TypeDefinition will be ignored.
|
||||
* </p>
|
||||
* <p>
|
||||
* If any of the requested fields are not present on the type and they
|
||||
* appear in the forcedFields list an attempt to find a model definition for
|
||||
* those fields is made so they can be included.
|
||||
* </p>
|
||||
*
|
||||
* @param nodeRef The NodeRef of the item being generated
|
||||
* @param typeDef The TypeDefiniton of the item being generated
|
||||
* @param fields Restricted list of fields to include
|
||||
* @param forcedFields List of field names that should be included even if
|
||||
* the field is not currently present
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateSelectedFields(NodeRef nodeRef, TypeDefinition typeDef, List<String> fields,
|
||||
List<String> forcedFields, Form form)
|
||||
{
|
||||
// ensure a NodeRef or TypeDefinition is provided
|
||||
if (nodeRef == null && typeDef == null) { throw new IllegalArgumentException(
|
||||
"A NodeRef or TypeDefinition must be provided"); }
|
||||
|
||||
if (getLogger().isDebugEnabled())
|
||||
getLogger().debug("Generating selected fields: " + fields + " and forcing: " + forcedFields);
|
||||
|
||||
// get data dictionary definition for node if it is provided
|
||||
QName type = null;
|
||||
Map<QName, Serializable> propValues = Collections.emptyMap();
|
||||
Map<QName, PropertyDefinition> propDefs = null;
|
||||
Map<QName, AssociationDefinition> assocDefs = null;
|
||||
|
||||
if (nodeRef != null)
|
||||
{
|
||||
type = this.nodeService.getType(nodeRef);
|
||||
typeDef = this.dictionaryService.getAnonymousType(type, this.nodeService.getAspects(nodeRef));
|
||||
|
||||
// NOTE: the anonymous type returns all property and association
|
||||
// defs
|
||||
// for all aspects applied as well as the type
|
||||
propDefs = typeDef.getProperties();
|
||||
assocDefs = typeDef.getAssociations();
|
||||
propValues = this.nodeService.getProperties(nodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = typeDef.getName();
|
||||
|
||||
// we only get the properties and associations of the actual type so
|
||||
// we also need to manually get properties and associations from any
|
||||
// mandatory aspects
|
||||
propDefs = new HashMap<QName, PropertyDefinition>(16);
|
||||
assocDefs = new HashMap<QName, AssociationDefinition>(16);
|
||||
propDefs.putAll(typeDef.getProperties());
|
||||
assocDefs.putAll(typeDef.getAssociations());
|
||||
|
||||
List<AspectDefinition> aspects = typeDef.getDefaultAspects(true);
|
||||
for (AspectDefinition aspect : aspects)
|
||||
{
|
||||
propDefs.putAll(aspect.getProperties());
|
||||
assocDefs.putAll(aspect.getAssociations());
|
||||
}
|
||||
}
|
||||
|
||||
for (String fieldName : fields)
|
||||
{
|
||||
// try and split the field name
|
||||
String[] parts = fieldName.split(":");
|
||||
if (parts.length == 2 || parts.length == 3)
|
||||
{
|
||||
boolean foundField = false;
|
||||
boolean tryProperty = true;
|
||||
boolean tryAssociation = true;
|
||||
String qNamePrefix = null;
|
||||
String localName = null;
|
||||
|
||||
if (parts.length == 2)
|
||||
{
|
||||
qNamePrefix = parts[0];
|
||||
localName = parts[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there are 3 parts to the field name the first one
|
||||
// represents
|
||||
// whether the field is a property or association i.e.
|
||||
// prop:prefix:local
|
||||
// or assoc:prefix:local, determine the prefix and ensure
|
||||
// it's valid
|
||||
if (PROP.equals(parts[0]))
|
||||
{
|
||||
tryAssociation = false;
|
||||
}
|
||||
else if (ASSOC.equals(parts[0]))
|
||||
{
|
||||
tryProperty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getLogger().isWarnEnabled())
|
||||
getLogger()
|
||||
.warn(
|
||||
"\""
|
||||
+ parts[0]
|
||||
+ "\" is an invalid prefix for requesting a property or association");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
qNamePrefix = parts[1];
|
||||
localName = parts[2];
|
||||
}
|
||||
|
||||
// create qname of field name
|
||||
QName fullQName = QName.createQName(qNamePrefix, localName, namespaceService);
|
||||
|
||||
// try the field as a property
|
||||
if (tryProperty)
|
||||
{
|
||||
// lookup property def on node
|
||||
PropertyDefinition propDef = propDefs.get(fullQName);
|
||||
if (propDef != null)
|
||||
{
|
||||
// generate the property field
|
||||
generatePropertyField(propDef, form, propValues.get(fullQName), this.namespaceService);
|
||||
|
||||
// no need to try and find an association
|
||||
tryAssociation = false;
|
||||
foundField = true;
|
||||
}
|
||||
}
|
||||
|
||||
// try the field as an association
|
||||
if (tryAssociation)
|
||||
{
|
||||
AssociationDefinition assocDef = assocDefs.get(fullQName);
|
||||
if (assocDef != null)
|
||||
{
|
||||
// generate the association field
|
||||
generateAssociationField(assocDef, form, (nodeRef != null) ? retrieveAssociationValues(nodeRef,
|
||||
assocDef) : null, this.namespaceService);
|
||||
|
||||
foundField = true;
|
||||
}
|
||||
}
|
||||
|
||||
// still not found the field, is it a force'd field?
|
||||
if (!foundField)
|
||||
{
|
||||
if (forcedFields != null && forcedFields.size() > 0 && forcedFields.contains(fieldName))
|
||||
{
|
||||
generateForcedField(fieldName, form);
|
||||
}
|
||||
else if (getLogger().isDebugEnabled())
|
||||
{
|
||||
getLogger().debug(
|
||||
"Ignoring field \"" + fieldName + "\" as it is not defined for the current "
|
||||
+ ((nodeRef != null) ? "node" : "type")
|
||||
+ " and it does not appear in the 'force' list");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// see if the fieldName is a well known transient property
|
||||
if (TRANSIENT_MIMETYPE.equals(fieldName) || TRANSIENT_ENCODING.equals(fieldName)
|
||||
|| TRANSIENT_SIZE.equals(fieldName))
|
||||
{
|
||||
// if the node type is content or sublcass thereof generate appropriate field
|
||||
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
ContentData content = null;
|
||||
|
||||
if (nodeRef != null)
|
||||
{
|
||||
content = (ContentData) this.nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
||||
}
|
||||
|
||||
if (TRANSIENT_MIMETYPE.equals(fieldName))
|
||||
{
|
||||
generateMimetypePropertyField(content, form);
|
||||
}
|
||||
else if (TRANSIENT_ENCODING.equals(fieldName))
|
||||
{
|
||||
generateEncodingPropertyField(content, form);
|
||||
}
|
||||
else if (TRANSIENT_SIZE.equals(fieldName))
|
||||
{
|
||||
generateSizePropertyField(content, form);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (getLogger().isWarnEnabled())
|
||||
{
|
||||
getLogger().warn("Ignoring unrecognised field \"" + fieldName + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a field definition for the given field that is being forced to
|
||||
* show.
|
||||
*
|
||||
* @param fieldName Name of the field to force
|
||||
* @param form The Form instance to populated
|
||||
*/
|
||||
protected void generateForcedField(String fieldName, Form form)
|
||||
{
|
||||
if (getLogger().isDebugEnabled())
|
||||
getLogger().debug("Attempting to force the inclusion of field \"" + fieldName + "\"");
|
||||
|
||||
String[] parts = fieldName.split(":");
|
||||
if (parts.length == 2 || parts.length == 3)
|
||||
{
|
||||
boolean foundField = false;
|
||||
boolean tryProperty = true;
|
||||
boolean tryAssociation = true;
|
||||
String qNamePrefix = null;
|
||||
String localName = null;
|
||||
|
||||
if (parts.length == 2)
|
||||
{
|
||||
qNamePrefix = parts[0];
|
||||
localName = parts[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there are 3 parts to the field name the first one
|
||||
// represents
|
||||
// whether the field is a property or association i.e.
|
||||
// prop:prefix:local
|
||||
// or assoc:prefix:local, determine the prefix and ensure it's
|
||||
// valid
|
||||
if (PROP.equals(parts[0]))
|
||||
{
|
||||
tryAssociation = false;
|
||||
}
|
||||
else if (ASSOC.equals(parts[0]))
|
||||
{
|
||||
tryProperty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getLogger().isWarnEnabled())
|
||||
getLogger().warn(
|
||||
"\"" + parts[0]
|
||||
+ "\" is an invalid prefix for requesting a property or association");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
qNamePrefix = parts[1];
|
||||
localName = parts[2];
|
||||
}
|
||||
|
||||
// create qname of field name
|
||||
QName fullQName = QName.createQName(qNamePrefix, localName, namespaceService);
|
||||
|
||||
if (tryProperty)
|
||||
{
|
||||
// lookup the field as a property in the whole model
|
||||
PropertyDefinition propDef = this.dictionaryService.getProperty(fullQName);
|
||||
if (propDef != null)
|
||||
{
|
||||
// generate the property field
|
||||
generatePropertyField(propDef, form, this.namespaceService);
|
||||
|
||||
// no need to try and find an association
|
||||
tryAssociation = false;
|
||||
foundField = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (tryAssociation)
|
||||
{
|
||||
// lookup the field as an association in the whole model
|
||||
AssociationDefinition assocDef = this.dictionaryService.getAssociation(fullQName);
|
||||
if (assocDef != null)
|
||||
{
|
||||
// generate the association field
|
||||
generateAssociationField(assocDef, form, this.namespaceService);
|
||||
|
||||
foundField = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundField && getLogger().isDebugEnabled())
|
||||
{
|
||||
getLogger()
|
||||
.debug(
|
||||
"Ignoring field \""
|
||||
+ fieldName
|
||||
+ "\" as it is not defined for the current node and can not be found in any model");
|
||||
}
|
||||
}
|
||||
else if (getLogger().isWarnEnabled())
|
||||
{
|
||||
getLogger().warn("Ignoring unrecognised field \"" + fieldName + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#getItemType(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected String getItemType(WorkflowDefinition item)
|
||||
{
|
||||
return item.name;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#getItemURI(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected String getItemURI(WorkflowDefinition item)
|
||||
{
|
||||
return "/api/workflow-definitions/" + item.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<QName, Serializable> getAssociationValues(WorkflowDefinition item)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<QName, Serializable> getPropertyValues(WorkflowDefinition item)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> getTransientValues(WorkflowDefinition item)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeDefinition getBaseType(WorkflowDefinition item)
|
||||
{
|
||||
return item.getStartTaskDefinition().metadata;
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
}
|
||||
|
@@ -40,10 +40,34 @@ public class WorkflowTaskDefinition
|
||||
/** Task Metadata */
|
||||
public TypeDefinition metadata;
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the metadata
|
||||
*/
|
||||
public TypeDefinition getMetadata()
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the node
|
||||
*/
|
||||
public WorkflowNode getNode()
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "WorkflowTaskDefinition[id=" + id + ",metadata=" + metadata + "]";
|
||||
|
Reference in New Issue
Block a user