extends Abstr
return persistedObject;
}
- protected void setItemType(Form form, String type)
- {
- form.getItem().setType(type);
- }
-
- protected void setItemUrl(Form form, String url)
- {
- form.getItem().setUrl(url);
- }
-
/**
* Returns a typed Object representing the given item.
*
diff --git a/source/java/org/alfresco/repo/forms/processor/node/ContentModelFormProcessor.java b/source/java/org/alfresco/repo/forms/processor/node/ContentModelFormProcessor.java
index e099fbce29..66da5f8f3f 100644
--- a/source/java/org/alfresco/repo/forms/processor/node/ContentModelFormProcessor.java
+++ b/source/java/org/alfresco/repo/forms/processor/node/ContentModelFormProcessor.java
@@ -125,8 +125,7 @@ public abstract class ContentModelFormProcessor extends
* pattern can also be used to extract the "cm", the "name" and the suffix
* parts.
*/
- protected Pattern associationNamePattern = Pattern.compile(ASSOC_DATA_PREFIX
- + "(.*){1}?_(.*){1}?(_[a-zA-Z]+)");
+ protected Pattern associationNamePattern = Pattern.compile(ASSOC_DATA_PREFIX + "(.*){1}?_(.*){1}?(_[a-zA-Z]+)");
/**
* Sets the node service
@@ -180,8 +179,7 @@ public abstract class ContentModelFormProcessor extends
* @param form The Form instance to populate
* @param namespaceService NamespaceService instance
*/
- public static void generatePropertyField(PropertyDefinition propDef, Form form,
- NamespaceService namespaceService)
+ public static void generatePropertyField(PropertyDefinition propDef, Form form, NamespaceService namespaceService)
{
generatePropertyField(propDef, form, null, null, namespaceService);
}
@@ -199,8 +197,8 @@ public abstract class ContentModelFormProcessor extends
* @param propValue The value of the property field
* @param namespaceService NamespaceService instance
*/
- public static void generatePropertyField(PropertyDefinition propDef, Form form,
- Serializable propValue, NamespaceService namespaceService)
+ public static void generatePropertyField(PropertyDefinition propDef, Form form, Serializable propValue,
+ NamespaceService namespaceService)
{
generatePropertyField(propDef, form, propValue, null, namespaceService);
}
@@ -220,13 +218,13 @@ public abstract class ContentModelFormProcessor extends
* @param namespaceService NamespaceService instance
*/
@SuppressWarnings("unchecked")
- public static void generatePropertyField(PropertyDefinition propDef, Form form,
- Serializable propValue, FieldGroup group, NamespaceService namespaceService)
+ public static 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());
+ PropertyFieldDefinition fieldDef = new PropertyFieldDefinition(propName, propDef.getDataType().getName()
+ .getLocalName());
String title = propDef.getTitle();
if (title == null)
@@ -272,14 +270,12 @@ public abstract class ContentModelFormProcessor extends
List constraints = propDef.getConstraints();
if (constraints != null && constraints.size() > 0)
{
- List fieldConstraints = new ArrayList(constraints
- .size());
+ List fieldConstraints = new ArrayList(constraints.size());
for (ConstraintDefinition constraintDef : constraints)
{
Constraint constraint = constraintDef.getConstraint();
- FieldConstraint fieldConstraint = new FieldConstraint(constraint.getType(),
- constraint.getParameters());
+ FieldConstraint fieldConstraint = new FieldConstraint(constraint.getType(), constraint.getParameters());
fieldConstraints.add(fieldConstraint);
}
@@ -336,8 +332,8 @@ public abstract class ContentModelFormProcessor extends
* @param namespaceService NamespaceService instance
*/
@SuppressWarnings("unchecked")
- public static void generateAssociationField(AssociationDefinition assocDef, Form form,
- List assocValues, NamespaceService namespaceService)
+ public static void generateAssociationField(AssociationDefinition assocDef, Form form, List assocValues,
+ NamespaceService namespaceService)
{
generateAssociationField(assocDef, form, assocValues, null, namespaceService);
}
@@ -357,13 +353,13 @@ public abstract class ContentModelFormProcessor extends
* @param namespaceService NamespaceService instance
*/
@SuppressWarnings("unchecked")
- public static void generateAssociationField(AssociationDefinition assocDef, Form form,
- List assocValues, FieldGroup group, NamespaceService namespaceService)
+ public 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);
+ AssociationFieldDefinition fieldDef = new AssociationFieldDefinition(assocName, assocDef.getTargetClass()
+ .getName().toPrefixString(namespaceService), Direction.TARGET);
String title = assocDef.getTitle();
if (title == null)
{
@@ -437,16 +433,15 @@ public abstract class ContentModelFormProcessor extends
* the field is not currently present
* @param form The Form instance to populate
*/
- protected void generateSelectedFields(NodeRef nodeRef, TypeDefinition typeDef,
- List fields, List forcedFields, Form form)
+ protected void generateSelectedFields(NodeRef nodeRef, TypeDefinition typeDef, List fields,
+ List 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);
+ getLogger().debug("Generating selected fields: " + fields + " and forcing: " + forcedFields);
// get data dictionary definition for node if it is provided
QName type = null;
@@ -457,8 +452,7 @@ public abstract class ContentModelFormProcessor extends
if (nodeRef != null)
{
type = this.nodeService.getType(nodeRef);
- typeDef = this.dictionaryService.getAnonymousType(type, this.nodeService
- .getAspects(nodeRef));
+ typeDef = this.dictionaryService.getAnonymousType(type, this.nodeService.getAspects(nodeRef));
// NOTE: the anonymous type returns all property and association
// defs
@@ -547,8 +541,7 @@ public abstract class ContentModelFormProcessor extends
if (propDef != null)
{
// generate the property field
- generatePropertyField(propDef, form, propValues.get(fullQName),
- this.namespaceService);
+ generatePropertyField(propDef, form, propValues.get(fullQName), this.namespaceService);
// no need to try and find an association
tryAssociation = false;
@@ -563,11 +556,8 @@ public abstract class ContentModelFormProcessor extends
if (assocDef != null)
{
// generate the association field
- generateAssociationField(
- assocDef,
- form,
- (nodeRef != null) ? retrieveAssociationValues(nodeRef, assocDef)
- : null, this.namespaceService);
+ generateAssociationField(assocDef, form, (nodeRef != null) ? retrieveAssociationValues(nodeRef,
+ assocDef) : null, this.namespaceService);
foundField = true;
}
@@ -576,16 +566,14 @@ public abstract class ContentModelFormProcessor extends
// still not found the field, is it a force'd field?
if (!foundField)
{
- if (forcedFields != null && forcedFields.size() > 0
- && forcedFields.contains(fieldName))
+ 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 "
+ "Ignoring field \"" + fieldName + "\" as it is not defined for the current "
+ ((nodeRef != null) ? "node" : "type")
+ " and it does not appear in the 'force' list");
}
@@ -599,9 +587,7 @@ public abstract class ContentModelFormProcessor extends
{
// if the node type is content or sublcass thereof generate
// appropriate field
- if (nodeRef != null
- && this.dictionaryService.isSubClass(type,
- ContentModel.TYPE_CONTENT))
+ if (nodeRef != null && this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT))
{
ContentData content = (ContentData) this.nodeService.getProperty(nodeRef,
ContentModel.PROP_CONTENT);
@@ -675,11 +661,9 @@ public abstract class ContentModelFormProcessor extends
else
{
if (getLogger().isWarnEnabled())
- getLogger()
- .warn(
- "\""
- + parts[0]
- + "\" is an invalid prefix for requesting a property or association");
+ getLogger().warn(
+ "\"" + parts[0]
+ + "\" is an invalid prefix for requesting a property or association");
return;
}
@@ -743,8 +727,8 @@ public abstract class ContentModelFormProcessor extends
protected void generateMimetypePropertyField(ContentData content, Form form)
{
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_MIMETYPE;
- PropertyFieldDefinition mimetypeField = new PropertyFieldDefinition(TRANSIENT_MIMETYPE,
- DataTypeDefinition.TEXT.getLocalName());
+ 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);
@@ -765,8 +749,8 @@ public abstract class ContentModelFormProcessor extends
protected void generateEncodingPropertyField(ContentData content, Form form)
{
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_ENCODING;
- PropertyFieldDefinition encodingField = new PropertyFieldDefinition(TRANSIENT_ENCODING,
- DataTypeDefinition.TEXT.getLocalName());
+ 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);
@@ -787,8 +771,8 @@ public abstract class ContentModelFormProcessor extends
protected void generateSizePropertyField(ContentData content, Form form)
{
String dataKeyName = PROP_DATA_PREFIX + TRANSIENT_SIZE;
- PropertyFieldDefinition sizeField = new PropertyFieldDefinition(TRANSIENT_SIZE,
- DataTypeDefinition.LONG.getLocalName());
+ 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);
@@ -818,8 +802,7 @@ public abstract class ContentModelFormProcessor extends
// get the list of values (if any) for the association
if (assocDef instanceof ChildAssociationDefinition)
{
- assocValues = this.nodeService.getChildAssocs(nodeRef, assocDef.getName(),
- RegexQNamePattern.MATCH_ALL);
+ assocValues = this.nodeService.getChildAssocs(nodeRef, assocDef.getName(), RegexQNamePattern.MATCH_ALL);
}
else
{
@@ -839,14 +822,12 @@ public abstract class ContentModelFormProcessor extends
{
// get the property definitions for the type of node being persisted
QName type = this.nodeService.getType(nodeRef);
- TypeDefinition typeDef = this.dictionaryService.getAnonymousType(type, this.nodeService
- .getAspects(nodeRef));
+ TypeDefinition typeDef = this.dictionaryService.getAnonymousType(type, this.nodeService.getAspects(nodeRef));
Map assocDefs = typeDef.getAssociations();
Map childAssocDefs = typeDef.getChildAssociations();
Map propDefs = typeDef.getProperties();
- Map propsToPersist = new HashMap(data
- .getNumberOfFields());
+ Map propsToPersist = new HashMap(data.getNumberOfFields());
List assocsToPersist = new ArrayList();
for (FieldData fieldData : data)
@@ -862,8 +843,7 @@ public abstract class ContentModelFormProcessor extends
}
else if (fieldName.startsWith(ASSOC_DATA_PREFIX))
{
- processAssociationPersist(nodeRef, assocDefs, childAssocDefs, fieldData,
- assocsToPersist);
+ processAssociationPersist(nodeRef, assocDefs, childAssocDefs, fieldData, assocsToPersist);
}
else if (getLogger().isWarnEnabled())
{
@@ -1004,8 +984,7 @@ public abstract class ContentModelFormProcessor extends
// everything else
// should be represented as null
if (!propDef.getDataType().getName().equals(DataTypeDefinition.TEXT)
- && !propDef.getDataType().getName().equals(
- DataTypeDefinition.MLTEXT))
+ && !propDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT))
{
value = null;
}
@@ -1018,8 +997,7 @@ public abstract class ContentModelFormProcessor extends
else if (getLogger().isWarnEnabled())
{
getLogger().warn(
- "Ignoring field '" + fieldData.getName()
- + "' as a property definition can not be found");
+ "Ignoring field '" + fieldData.getName() + "' as a property definition can not be found");
}
}
else
@@ -1064,8 +1042,7 @@ public abstract class ContentModelFormProcessor extends
* @param fieldData Data to persist for the associations
* @param assocCommands List of associations to be persisted
*/
- protected void processAssociationPersist(NodeRef nodeRef,
- Map assocDefs,
+ protected void processAssociationPersist(NodeRef nodeRef, Map assocDefs,
Map childAssocDefs, FieldData fieldData,
List assocCommands)
{
@@ -1102,9 +1079,7 @@ public abstract class ContentModelFormProcessor extends
{
if (getLogger().isWarnEnabled())
{
- getLogger().warn(
- "Definition for association " + fullQName
- + " not recognised and not persisted.");
+ getLogger().warn("Definition for association " + fullQName + " not recognised and not persisted.");
}
return;
}
@@ -1125,26 +1100,25 @@ public abstract class ContentModelFormProcessor extends
{
if (assocDef.isChild())
{
- assocCommands.add(new AddChildAssocCommand(nodeRef, new NodeRef(
- nextTargetNode), fullQName));
+ assocCommands.add(new AddChildAssocCommand(nodeRef, new NodeRef(nextTargetNode),
+ fullQName));
}
else
{
- assocCommands.add(new AddAssocCommand(nodeRef, new NodeRef(
- nextTargetNode), fullQName));
+ assocCommands.add(new AddAssocCommand(nodeRef, new NodeRef(nextTargetNode), fullQName));
}
}
else if (assocSuffix.equals(ASSOC_DATA_REMOVED_SUFFIX))
{
if (assocDef.isChild())
{
- assocCommands.add(new RemoveChildAssocCommand(nodeRef, new NodeRef(
- nextTargetNode), fullQName));
+ assocCommands.add(new RemoveChildAssocCommand(nodeRef, new NodeRef(nextTargetNode),
+ fullQName));
}
else
{
- assocCommands.add(new RemoveAssocCommand(nodeRef, new NodeRef(
- nextTargetNode), fullQName));
+ assocCommands.add(new RemoveAssocCommand(nodeRef, new NodeRef(nextTargetNode),
+ fullQName));
}
}
else
@@ -1153,10 +1127,9 @@ public abstract class ContentModelFormProcessor extends
{
StringBuilder msg = new StringBuilder();
msg.append("fieldName ").append(fieldName).append(
- " does not have one of the expected suffixes [")
- .append(ASSOC_DATA_ADDED_SUFFIX).append(", ").append(
- ASSOC_DATA_REMOVED_SUFFIX).append(
- "] and has been ignored.");
+ " does not have one of the expected suffixes [").append(
+ ASSOC_DATA_ADDED_SUFFIX).append(", ").append(ASSOC_DATA_REMOVED_SUFFIX)
+ .append("] and has been ignored.");
getLogger().warn(msg.toString());
}
}
@@ -1215,8 +1188,7 @@ public abstract class ContentModelFormProcessor extends
if (contentData == null)
{
// content data has not been persisted yet so get it from the node
- contentData = (ContentData) this.nodeService.getProperty(nodeRef,
- ContentModel.PROP_CONTENT);
+ contentData = (ContentData) this.nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
}
if (contentData != null)
@@ -1241,8 +1213,7 @@ public abstract class ContentModelFormProcessor extends
if (contentData == null)
{
// content data has not been persisted yet so get it from the node
- contentData = (ContentData) this.nodeService.getProperty(nodeRef,
- ContentModel.PROP_CONTENT);
+ contentData = (ContentData) this.nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
}
if (contentData != null)
@@ -1300,8 +1271,7 @@ class AddAssocCommand extends AbstractAssocCommand
@Override
protected void updateAssociations(NodeService nodeService)
{
- List existingAssocs = nodeService
- .getTargetAssocs(sourceNodeRef, assocQName);
+ List existingAssocs = nodeService.getTargetAssocs(sourceNodeRef, assocQName);
for (AssociationRef assoc : existingAssocs)
{
if (assoc.getTargetRef().equals(targetNodeRef))
@@ -1334,8 +1304,7 @@ class RemoveAssocCommand extends AbstractAssocCommand
@Override
protected void updateAssociations(NodeService nodeService)
{
- List existingAssocs = nodeService
- .getTargetAssocs(sourceNodeRef, assocQName);
+ List existingAssocs = nodeService.getTargetAssocs(sourceNodeRef, assocQName);
boolean assocDoesNotExist = true;
for (AssociationRef assoc : existingAssocs)
{
@@ -1350,8 +1319,8 @@ class RemoveAssocCommand extends AbstractAssocCommand
if (logger.isWarnEnabled())
{
StringBuilder msg = new StringBuilder();
- msg.append("Attempt to remove non-existent association prevented. ").append(
- sourceNodeRef).append("|").append(targetNodeRef).append(assocQName);
+ msg.append("Attempt to remove non-existent association prevented. ").append(sourceNodeRef).append("|")
+ .append(targetNodeRef).append(assocQName);
logger.warn(msg.toString());
}
return;
@@ -1432,8 +1401,8 @@ class RemoveChildAssocCommand extends AbstractAssocCommand
if (logger.isWarnEnabled())
{
StringBuilder msg = new StringBuilder();
- msg.append("Attempt to remove non-existent child association prevented. ").append(
- sourceNodeRef).append("|").append(targetNodeRef).append(assocQName);
+ msg.append("Attempt to remove non-existent child association prevented. ").append(sourceNodeRef)
+ .append("|").append(targetNodeRef).append(assocQName);
logger.warn(msg.toString());
}
return;
diff --git a/source/java/org/alfresco/repo/forms/processor/node/NodeFormProcessor.java b/source/java/org/alfresco/repo/forms/processor/node/NodeFormProcessor.java
index d4fa251702..81c750e02a 100644
--- a/source/java/org/alfresco/repo/forms/processor/node/NodeFormProcessor.java
+++ b/source/java/org/alfresco/repo/forms/processor/node/NodeFormProcessor.java
@@ -95,21 +95,19 @@ public class NodeFormProcessor extends ContentModelFormProcessor fields, List forcedFields,
- Form form, Map context)
+ protected void internalGenerate(NodeRef item, List fields, List forcedFields, Form form,
+ Map context)
{
if (logger.isDebugEnabled()) logger.debug("Generating form for: " + item);
@@ -144,17 +142,17 @@ public class NodeFormProcessor extends ContentModelFormProcessor fields, List forcedFields,
- Form form)
+ protected void generateNode(NodeRef nodeRef, List fields, List forcedFields, Form form)
{
// set the type and URL of the item
QName type = this.nodeService.getType(nodeRef);
- form.getItem().setType(type.toPrefixString(this.namespaceService));
+ setFormItemType(form, type.toPrefixString(this.namespaceService));
+
StringBuilder builder = new StringBuilder("/api/node/");
builder.append(nodeRef.getStoreRef().getProtocol()).append("/");
builder.append(nodeRef.getStoreRef().getIdentifier()).append("/");
builder.append(nodeRef.getId());
- form.getItem().setUrl(builder.toString());
+ setFormItemUrl(form, builder.toString());
if (fields != null && fields.size() > 0)
{
@@ -179,8 +177,7 @@ public class NodeFormProcessor extends ContentModelFormProcessor propValues = this.nodeService.getProperties(nodeRef);
for (PropertyDefinition propDef : propDefs.values())
{
- generatePropertyField(propDef, form, propValues.get(propDef.getName()),
- this.namespaceService);
+ generatePropertyField(propDef, form, propValues.get(propDef.getName()), this.namespaceService);
}
}
@@ -203,8 +199,7 @@ public class NodeFormProcessor extends ContentModelFormProcessor assocDefs = typeDef.getAssociations();
@@ -229,8 +224,7 @@ public class NodeFormProcessor extends ContentModelFormProcessor"prop_cm_name". The pattern can also
+ // be
+ // * used to extract the "cm" and the "name" parts.
+ // */
+ // protected Pattern propertyNamePattern = Pattern.compile(PROP_DATA_PREFIX
+ // + "(.*){1}?_(.*){1}?");
+ //
+ // /**
+ // * A regular expression which can be used to match tranisent property
+ // names.
+ // * These names will look like "prop_name"
. The pattern can
+ // also
+ // * be used to extract the "name" part.
+ // */
+ // protected Pattern transientPropertyPattern =
+ // Pattern.compile(PROP_DATA_PREFIX + "(.*){1}?");
+ //
+ // /**
+ // * A regular expression which can be used to match association names.
+ // These
+ // * names will look like "assoc_cm_references_added"
. The
+ // * pattern can also be used to extract the "cm", the "name" and the suffix
+ // * parts.
+ // */
+ // protected Pattern associationNamePattern =
+ // Pattern.compile(ASSOC_DATA_PREFIX + "(.*){1}?_(.*){1}?(_[a-zA-Z]+)");
+ //
+ // private NamespaceService namespaceService;
+ //
+ // private FieldDefinitionFactory factory;
+ //
+ // /**
+ // * Sets up the field definitions for all the requested fields.
+ // *
+ // * 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.
+ // *
+ // *
+ // * 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.
+ // *
+ // *
+ // * @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
+ // */
+ // public void generateSelectedField(String fieldName, FieldCreationData
+ // data)
+ // {
+ // FieldInfo fieldInfo = new FieldInfo(fieldName, data);
+ // if (fieldInfo.isValid()) fieldInfo.addToForm(form);
+ //
+ // // try the field as a property
+ // if (fieldInfo.tryProperty)
+ // {
+ // // lookup property def on node
+ // PropertyDefinition propDef = propDefs.get(fullQName);
+ // if (propDef != null)
+ // {
+ // // generate the property field
+ // generatePropertyField(propDef, propValues.get(fullQName), null);
+ //
+ // // no need to try and find an association
+ // tryAssociation = false;
+ // foundField = true;
+ // }
+ // }
+ //
+ // // try the field as an association
+ // if (fieldInfo.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 forced 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");
+ // }
+ // }
+ // }
+ //
+ // /**
+ // * Sets up a field definition for the given association.
+ // *
+ // * 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.
+ // *
+ // *
+ // * @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
+ // */
+ // public void generateAssociationField(AssociationDefinition assocDef,
+ // List> assocValues, FieldGroup group)
+ // {
+ // AssociationFieldDefinition fieldDef =
+ // makeAssociationFieldDefinition(assocDef, group);
+ //
+ // // 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 values = new ArrayList(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(fieldDef.getDataKeyName(), values);
+ // }
+ // }
+ //
+ // /**
+ // * Sets up a field definition for the given property.
+ // *
+ // * 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.
+ // *
+ // *
+ // * @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")
+ // public void generatePropertyField(PropertyDefinition propDef,
+ // Serializable propValue, FieldGroup group)
+ // {
+ // PropertyFieldDefinition fieldDef =
+ // factory.makePropertyFieldDefinition(propDef, group);
+ // form.addFieldDefinition(fieldDef);
+ //
+ // // add the property value to the form
+ // if (propValue != null)
+ // {
+ // if (propValue instanceof List)
+ // {
+ // // TODO Currently this adds repeating field data as a comma
+ // // separated list, this needs to be replaced with a separate
+ // // field for each value once we have full UI support in place.
+ // propValue = StringUtils.collectionToCommaDelimitedString((List)
+ // propValue);
+ // }
+ // form.addData(fieldDef.getDataKeyName(), propValue);
+ // }
+ // }
+ //
+ // private class FieldInfo
+ // {
+ // private final QName name;
+ //
+ // private final FieldDefinition fieldDefinition;
+ //
+ // private FieldType fieldType;
+ //
+ // private FieldInfo(String fieldName, FieldCreationData data)
+ // {
+ // this.name = makeNameAndFieldType(fieldName);
+ // this.fieldDefinition = createDefinition(data);
+ // }
+ //
+ // /**
+ // * @return
+ // */
+ // public boolean isValid()
+ // {
+ // return fieldDefinition != null;
+ // }
+ //
+ // private QName makeNameAndFieldType(String fieldName)
+ // {
+ // String[] parts = fieldName.split(":");
+ // if (parts.length < 2 || parts.length > 3)
+ // {
+ // this.fieldType = FieldType.INVALID;
+ // return QName.createQName(null, fieldName);
+ // }
+ // int indexer = 0;
+ // if (parts.length == 3)
+ // {
+ // indexer = 1;
+ // this.fieldType = FieldType.getType(parts[0]);
+ // }
+ // else
+ // this.fieldType = FieldType.UNKNOWN;
+ // String prefix = parts[0 + indexer];
+ // String localName = parts[1 + indexer];
+ // return QName.createQName(prefix, localName, namespaceService);
+ // }
+ //
+ // /**
+ // * @param data
+ // */
+ // private FieldDefinition createDefinition(FieldCreationData data)
+ // {
+ // FieldDefinition fieldDef = null;
+ // switch (fieldType)
+ // {
+ // case INVALID:// So fieldDef will stay null.
+ // break;
+ // case PROPERTY:
+ // fieldDef = generatePropertyDefinition(data);
+ // break;
+ // case ASSOCIATION:
+ // fieldDef = generateAssociationDefinition(data);
+ // break;
+ // case UNKNOWN:
+ // fieldDef = generatePropertyDefinition(data);
+ // if (fieldDef != null)
+ // fieldType = FieldType.PROPERTY;
+ // else
+ // {
+ // fieldDef = generateAssociationDefinition(data);
+ // if (fieldDef != null) fieldType = FieldType.ASSOCIATION;
+ // }
+ // }
+ // if (fieldDef == null)
+ // {
+ // this.fieldType = FieldType.INVALID;
+ // }
+ // return fieldDef;
+ // }
+ //
+ // /**
+ // * @param data
+ // * @return
+ // */
+ // private AssociationFieldDefinition
+ // generateAssociationDefinition(FieldCreationData data)
+ // {
+ // AssociationDefinition assocDef = data.getAssocDefs().get(name);
+ // if (assocDef != null)
+ // return factory.makeAssociationFieldDefinition(assocDef, data.getGroup());
+ // else
+ // return null;
+ // }
+ //
+ // /**
+ // * @param data
+ // */
+ // private PropertyFieldDefinition
+ // generatePropertyDefinition(FieldCreationData data)
+ // {
+ // PropertyDefinition propDef = data.getPropDefs().get(name);
+ // if (propDef != null) //
+ // return factory.makePropertyFieldDefinition(propDef, data.getGroup());
+ // else
+ // return null;
+ // }
+ //
+ // public void addToForm(Form form, FieldCreationData data)
+ // {
+ // if (isValid())
+ // {
+ // form.addFieldDefinition(fieldDefinition);
+ // Object value = null;
+ // if (fieldType == FieldType.PROPERTY)
+ // {
+ // value = buildPropertyData(data, (PropertyFieldDefinition)
+ // fieldDefinition);
+ // }
+ // else if (fieldType == FieldType.ASSOCIATION)
+ // {
+ // value = buildAssociationData(data, (AssociationFieldDefinition)
+ // fieldDefinition);
+ // }
+ // if (value != null)
+ // {
+ // form.addData(fieldDefinition.getDataKeyName(), value);
+ // }
+ // }
+ // else
+ // {
+ // throw new IllegalStateException("Cannot add invalid field:" +
+ // name.getLocalName() + " to a form!");
+ // }
+ // }
+ // }
+ //
+ // private enum FieldType
+ // {
+ // ASSOCIATION, INVALID, PROPERTY, UNKNOWN;
+ //
+ // public static FieldType getType(String type)
+ // {
+ // if (PROP.equals(type))
+ // {
+ // return PROPERTY;
+ // }
+ // else if (ASSOC.equals(type)) return ASSOCIATION;
+ // return UNKNOWN;
+ // }
+ // }
+ //
+ // protected abstract Object buildPropertyData(FieldCreationData data,
+ // PropertyFieldDefinition fieldDef);
+ //
+ // protected abstract Object buildAssociationData(FieldCreationData data,
+ // AssociationFieldDefinition fieldDef);
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/task/FieldCreationData.java b/source/java/org/alfresco/repo/forms/processor/task/FieldCreationData.java
new file mode 100644
index 0000000000..ad3faaa937
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/task/FieldCreationData.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.repo.forms.processor.task;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.alfresco.repo.forms.FieldGroup;
+import org.alfresco.service.cmr.dictionary.AspectDefinition;
+import org.alfresco.service.cmr.dictionary.AssociationDefinition;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.dictionary.PropertyDefinition;
+import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.namespace.QName;
+
+/**
+ * @author Nick Smith
+ */
+public class FieldCreationData
+{
+ private final QName type;
+
+ private final TypeDefinition typeDef;
+
+ private final Map propValues;
+
+ private final Map propDefs;
+
+ private final Map assocDefs;
+
+ private final FieldGroup group;
+
+ private final List forcedFields;
+
+ public FieldCreationData(NodeRef nodeRef, List forcedFields, FieldGroup group, NodeService nodeService,
+ DictionaryService dictionaryService)
+ {
+ this.forcedFields = forcedFields;
+ this.group = group;
+ this.type = nodeService.getType(nodeRef);
+ Set aspects = nodeService.getAspects(nodeRef);
+ this.typeDef = dictionaryService.getAnonymousType(type, aspects);
+
+ // NOTE: the anonymous type returns all property and association
+ // defs for all aspects applied as well as the type
+ this.propDefs = typeDef.getProperties();
+ this.assocDefs = typeDef.getAssociations();
+ this.propValues = nodeService.getProperties(nodeRef);
+ }
+
+ public FieldCreationData(TypeDefinition typeDef, List forcedFields, FieldGroup group)
+ {
+ this.propValues = null;
+
+ this.forcedFields = forcedFields;
+ this.group = group;
+ this.typeDef = typeDef;
+ this.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
+ this.propDefs = new HashMap(16);
+ this.assocDefs = new HashMap(16);
+ propDefs.putAll(typeDef.getProperties());
+ assocDefs.putAll(typeDef.getAssociations());
+
+ List aspects = typeDef.getDefaultAspects(true);
+ for (AspectDefinition aspect : aspects)
+ {
+ propDefs.putAll(aspect.getProperties());
+ assocDefs.putAll(aspect.getAssociations());
+ }
+ }
+
+ public FieldCreationData(WorkflowTask task, List forcedFields, FieldGroup group)
+ {
+ this.forcedFields = forcedFields;
+ this.group = group;
+ this.typeDef = task.definition.metadata;
+ this.type = typeDef.getName();
+
+ this.propDefs = populateProperties(typeDef);
+ this.assocDefs = populateAssociations(typeDef);
+ this.propValues = task.properties;
+ }
+
+ private Map populateAssociations(TypeDefinition typeDef2)
+ {
+ HashMap allProps = new HashMap();
+ allProps.putAll(typeDef.getAssociations());
+ List aspects = typeDef.getDefaultAspects(true);
+ for (AspectDefinition aspect : aspects)
+ {
+ allProps.putAll(aspect.getAssociations());
+ }
+ return Collections.unmodifiableMap(allProps);
+ }
+
+ private Map populateProperties(TypeDefinition typeDef)
+ {
+ HashMap allProps = new HashMap();
+ allProps.putAll(typeDef.getProperties());
+ List aspects = typeDef.getDefaultAspects(true);
+ for (AspectDefinition aspect : aspects)
+ {
+ allProps.putAll(aspect.getProperties());
+ }
+ return Collections.unmodifiableMap(allProps);
+ }
+
+ /**
+ * @return the propValues
+ */
+ public Map getPropValues()
+ {
+ return this.propValues;
+ }
+
+ /**
+ * @return the propDefs
+ */
+ public Map getPropDefs()
+ {
+ return this.propDefs;
+ }
+
+ /**
+ * @return the assocDefs
+ */
+ public Map getAssocDefs()
+ {
+ return this.assocDefs;
+ }
+
+ /**
+ * @return the group
+ */
+ public FieldGroup getGroup()
+ {
+ return this.group;
+ }
+
+ /**
+ * @return the forcedFields
+ */
+ public List getForcedFields()
+ {
+ return this.forcedFields;
+ }
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/task/FieldDefinitionFactory.java b/source/java/org/alfresco/repo/forms/processor/task/FieldDefinitionFactory.java
new file mode 100644
index 0000000000..4aee8e24eb
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/task/FieldDefinitionFactory.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.repo.forms.processor.task;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.alfresco.repo.forms.processor.node.FormFieldConstants.*;
+import org.alfresco.repo.forms.AssociationFieldDefinition;
+import org.alfresco.repo.forms.FieldDefinition;
+import org.alfresco.repo.forms.FieldGroup;
+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.PeriodDataTypeParameters;
+import org.alfresco.service.cmr.dictionary.AssociationDefinition;
+import org.alfresco.service.cmr.dictionary.ClassAttributeDefinition;
+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.repository.Period;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+
+/**
+ * @author Nick Smith
+ */
+public class FieldDefinitionFactory
+{
+ private final NamespaceService namespaceService;
+
+ public FieldDefinitionFactory(NamespaceService namespaceService)
+ {
+ this.namespaceService = namespaceService;
+ }
+
+ public AssociationFieldDefinition makeAssociationFieldDefinition(
+ final AssociationDefinition assocDef, FieldGroup group)
+ {
+ // Callback used to construct the AssociationFieldDefinition.
+ FieldDefinitionCreator factory = new FieldDefinitionCreator()
+ {
+ public AssociationFieldDefinition create(String name)
+ {
+ String endpointType = assocDef.getTargetClass().getName().toPrefixString(
+ namespaceService);
+ return new AssociationFieldDefinition(name, endpointType, Direction.TARGET);
+ }
+ };
+ AssociationFieldDefinition fieldDef = makeFieldDefinition(assocDef, group,
+ ASSOC_DATA_PREFIX, factory);
+
+ fieldDef.setEndpointMandatory(assocDef.isTargetMandatory());
+ fieldDef.setEndpointMany(assocDef.isTargetMany());
+ return fieldDef;
+ }
+
+ public PropertyFieldDefinition makePropertyFieldDefinition(final PropertyDefinition propDef,
+ FieldGroup group)
+ {
+ // Callback used to construct the PropertyFieldDefinition.
+ FieldDefinitionCreator factory = new FieldDefinitionCreator()
+ {
+ public PropertyFieldDefinition create(String name)
+ {
+ QName dataType = propDef.getDataType().getName();
+ return new PropertyFieldDefinition(name, dataType.getLocalName());
+ }
+ };
+ PropertyFieldDefinition fieldDef = makeFieldDefinition(propDef, group, PROP_DATA_PREFIX,
+ factory);
+
+ fieldDef.setDefaultValue(propDef.getDefaultValue());
+ fieldDef.setMandatory(propDef.isMandatory());
+ fieldDef.setRepeating(propDef.isMultiValued());
+
+ // any property from the system model (sys prefix) should be protected
+ // the model doesn't
+ // cu rrently enforce this so make sure they are not editable
+ if (NamespaceService.SYSTEM_MODEL_1_0_URI.equals(propDef.getName().getNamespaceURI()))
+ {
+ fieldDef.setProtectedField(true);
+ }
+
+ // If the property data type is d:period we need to setup a data
+ // type parameters object to represent the options and rules
+ if (fieldDef.getDataType().equals(DataTypeDefinition.PERIOD))
+ {
+ PeriodDataTypeParameters periodOptions = getPeriodOptions();
+ fieldDef.setDataTypeParameters(periodOptions);
+ }
+
+ // setup constraints for the property
+ List fieldConstraints = makeFieldConstraints(propDef);
+ fieldDef.setConstraints(fieldConstraints);
+ return fieldDef;
+ }
+
+ /**
+ * Creates either a PropertyFieldDefinition or an
+ * AssociationFieldDefinition, as defined by the factory class being passed
+ * in. Sets several properties on this FieldDefinition, including name,
+ * label, description, dataKeyName and whether the field is protected. These
+ * values are derived from the attribDef
parameter.
+ *
+ * @param attribDef Used to set the values of name, description, label,
+ * dataKeyName and isProtected properties on the returned object.
+ * @param group Used to set the group on the returned FieldDefinition.
+ * @param factory A factory object used to create the FieldDefinition to be
+ * returned.
+ * @return An object of type T
which extends
+ * FieldDefinition
.
+ */
+ private T makeFieldDefinition(ClassAttributeDefinition attribDef,
+ FieldGroup group, String dataKeyPrefix, FieldDefinitionCreator factory)
+ {
+ String attribName = attribDef.getName().toPrefixString(namespaceService);
+ T fieldDef = factory.create(attribName);
+ fieldDef.setGroup(group);
+ String title = attribDef.getTitle();
+ title = title == null ? attribName : title;
+ fieldDef.setLabel(title);
+ fieldDef.setDescription(attribDef.getDescription());
+ fieldDef.setProtectedField(attribDef.isProtected());
+
+ // define the data key name and set
+ String dataKeyName = makeDataKeyForName(attribName, dataKeyPrefix);
+ fieldDef.setDataKeyName(dataKeyName);
+ return fieldDef;
+ }
+
+ private static List makeFieldConstraints(PropertyDefinition propDef)
+ {
+ List fieldConstraints = null;
+ List constraints = propDef.getConstraints();
+ if (constraints != null && constraints.size() > 0)
+ {
+ fieldConstraints = new ArrayList(constraints.size());
+ for (ConstraintDefinition constraintDef : constraints)
+ {
+ Constraint constraint = constraintDef.getConstraint();
+ String type = constraint.getType();
+ Map params = constraint.getParameters();
+ FieldConstraint fieldConstraint = new FieldConstraint(type, params);
+ fieldConstraints.add(fieldConstraint);
+ }
+ }
+ return fieldConstraints;
+ }
+
+ private PeriodDataTypeParameters getPeriodOptions()
+ {
+ PeriodDataTypeParameters periodOptions = new PeriodDataTypeParameters();
+ Set providers = Period.getProviderNames();
+ for (String provider : providers)
+ {
+ periodOptions.addPeriodProvider(Period.getProvider(provider));
+ }
+ return periodOptions;
+ }
+
+ private static String makeDataKeyForName(String propName, String prefix)
+ {
+ String[] nameParts = QName.splitPrefixedQName(propName);
+ return prefix + nameParts[0] + DATA_KEY_SEPARATOR + nameParts[1];
+ }
+
+ private interface FieldDefinitionCreator
+ {
+ T create(String fieldDefinitionName);
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/task/FieldInfo.java b/source/java/org/alfresco/repo/forms/processor/task/FieldInfo.java
new file mode 100644
index 0000000000..ebb3a5cfbe
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/task/FieldInfo.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.repo.forms.processor.task;
+
+import static org.alfresco.repo.forms.processor.node.FormFieldConstants.*;
+
+import org.alfresco.repo.forms.FieldDefinition;
+import org.alfresco.service.cmr.dictionary.AssociationDefinition;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.dictionary.PropertyDefinition;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+
+/**
+ * @author Nick Smith
+ */
+public class FieldInfo
+{
+ private final QName fullName;
+
+ private final FieldDefinition fieldDefinition;
+
+ private final String fieldName;
+
+ private final DictionaryService dictionaryService;
+
+ private final FieldDefinitionFactory factory;
+
+ private FieldType fieldType;
+
+ public FieldInfo(String fieldName, FieldCreationData data, FieldDefinitionFactory factory,
+ DictionaryService dictionaryService, NamespaceService namespaceService)
+ {
+ this.factory = factory;
+ this.dictionaryService = dictionaryService;
+ this.fieldName = fieldName;
+ this.fullName = makeNameAndFieldType(fieldName, namespaceService);
+ this.fieldDefinition = createDefinition(data);
+ }
+
+ private FieldDefinition createDefinition(final FieldCreationData data)
+ {
+ // Callback used to find the PropertyDefinition associated with this
+ // field (if any).
+ Getter propDefGetter = new Getter()
+ {
+ public PropertyDefinition get()
+ {
+ return data.getPropDefs().get(fullName);
+ }
+ };
+
+ // Callback used to find the PropertyDefinition associated with this
+ // field (if any).
+ Getter assocDefGetter = new Getter()
+ {
+ public AssociationDefinition get()
+ {
+ return data.getAssocDefs().get(fullName);
+ }
+ };
+
+ FieldDefinition fieldDef = createDefinition(data, propDefGetter, assocDefGetter);
+ if (fieldDef == null)
+ {
+ // If field is a forced field try to get it from dictionary
+ // service.
+ if (data.getForcedFields().contains(fieldName))
+ {
+ propDefGetter = new Getter()
+ {
+ public PropertyDefinition get()
+ {
+ return dictionaryService.getProperty(fullName);
+ }
+ };
+
+ new Getter()
+ {
+ public AssociationDefinition get()
+ {
+ return dictionaryService.getAssociation(fullName);
+ }
+ };
+ fieldDef = createDefinition(data);
+ }
+ }
+ // If no field definition found then set fieldType to Invalid.
+ if (fieldDef == null)
+ {
+ this.fieldType = FieldType.INVALID;
+ }
+ return fieldDef;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isValid()
+ {
+ return fieldDefinition != null;
+ }
+
+ private QName makeNameAndFieldType(String fieldName, NamespaceService namespaceService)
+ {
+ String[] parts = fieldName.split(":");
+ if (parts.length < 2 || parts.length > 3)
+ {
+ this.fieldType = FieldType.INVALID;
+ return QName.createQName(null, fieldName);
+ }
+ int indexer = 0;
+ if (parts.length == 3)
+ {
+ indexer = 1;
+ this.fieldType = FieldType.getType(parts[0]);
+ }
+ else
+ this.fieldType = FieldType.UNKNOWN;
+ String prefix = parts[0 + indexer];
+ String localName = parts[1 + indexer];
+ return QName.createQName(prefix, localName, namespaceService);
+ }
+
+ /**
+ * @param data
+ */
+ private FieldDefinition createDefinition(FieldCreationData data, Getter propDefGetter,
+ Getter assocDefGetter)
+ {
+ FieldDefinition fieldDef = null;
+ switch (fieldType)
+ {
+ case INVALID:// So fieldDef will stay null.
+ break;
+ case PROPERTY:
+ fieldDef = generatePropertyDefinition(data, propDefGetter);
+ break;
+ case ASSOCIATION:
+ fieldDef = generateAssociationDefinition(data, assocDefGetter);
+ break;
+ case UNKNOWN:
+ fieldDef = generatePropertyDefinition(data, propDefGetter);
+ if (fieldDef != null)
+ fieldType = FieldType.PROPERTY;
+ else
+ {
+ fieldDef = generateAssociationDefinition(data, assocDefGetter);
+ if (fieldDef != null) fieldType = FieldType.ASSOCIATION;
+ }
+ }
+ return fieldDef;
+ }
+
+ private FieldDefinition generateAssociationDefinition(FieldCreationData data,
+ Getter assocDefGetter)
+ {
+ AssociationDefinition assocDef = assocDefGetter.get();
+ if (assocDef != null)
+ return factory.makeAssociationFieldDefinition(assocDef, data.getGroup());
+ else
+ return null;
+ }
+
+ private FieldDefinition generatePropertyDefinition(FieldCreationData data, Getter propDefGetter)
+ {
+ PropertyDefinition propDef = propDefGetter.get();
+ if (propDef != null) //
+ return factory.makePropertyFieldDefinition(propDef, data.getGroup());
+ else
+ return null;
+ }
+
+ /**
+ * @return the fieldDefinition
+ */
+ public FieldDefinition getFieldDefinition()
+ {
+ return this.fieldDefinition;
+ }
+
+ /**
+ * @return the fullName
+ */
+ public QName getFullName()
+ {
+ return this.fullName;
+ }
+
+ /**
+ * @return the fieldName
+ */
+ public String getFieldName()
+ {
+ return this.fieldName;
+ }
+
+ private enum FieldType
+ {
+ ASSOCIATION, INVALID, PROPERTY, UNKNOWN;
+
+ public static FieldType getType(String type)
+ {
+ if (PROP.equals(type))
+ {
+ return PROPERTY;
+ }
+ else if (ASSOC.equals(type)) return ASSOCIATION;
+ return UNKNOWN;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/task/Getter.java b/source/java/org/alfresco/repo/forms/processor/task/Getter.java
new file mode 100644
index 0000000000..5c6f565598
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/task/Getter.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.repo.forms.processor.task;
+
+/**
+ * This interface may be used as a parameter in a method instead of passing in
+ * an object of type T. This can be useful if you wish to lazy-create a
+ * parameter, cache a parameter or otherwise control how the parameter is used.
+ *
+ * @author Nick Smith
+ */
+public interface Getter
+{
+ /**
+ * Returns an object of type T.
+ *
+ * @return
+ */
+ T get();
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/task/TaskFormProcessor.java b/source/java/org/alfresco/repo/forms/processor/task/TaskFormProcessor.java
new file mode 100644
index 0000000000..56c957eb5f
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/task/TaskFormProcessor.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.repo.forms.processor.task;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.repo.forms.FieldDefinition;
+import org.alfresco.repo.forms.Form;
+import org.alfresco.repo.forms.FormData;
+import org.alfresco.repo.forms.Item;
+import org.alfresco.repo.forms.FormData.FieldData;
+import org.alfresco.repo.forms.processor.FilteredFormProcessor;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.ParameterCheck;
+
+/**
+ * @author Nick Smith
+ */
+public class TaskFormProcessor extends FilteredFormProcessor
+{
+ /** Logger */
+ // private static final Log logger =
+ // LogFactory.getLog(TaskFormProcessor.class);
+
+ private final WorkflowService workflowService;
+
+ private final NamespaceService namespaceService;
+
+ private final DictionaryService dictionaryService;
+
+ private final FieldDefinitionFactory factory;
+
+ public TaskFormProcessor(WorkflowService workflowService, NamespaceService namespaceService,
+ DictionaryService dictionaryService)
+ {
+ this.workflowService = workflowService;
+ this.namespaceService = namespaceService;
+ this.dictionaryService = dictionaryService;
+ this.factory = new FieldDefinitionFactory(namespaceService);
+ }
+
+ /*
+ * @see
+ * org.alfresco.repo.forms.processor.FilteredFormProcessor#getTypedItem(
+ * org.alfresco.repo.forms.Item)
+ */
+ @Override
+ protected WorkflowTask getTypedItem(Item item)
+ {
+ ParameterCheck.mandatory("item", item);
+ String id = item.getId();
+ WorkflowTask task = workflowService.getTaskById(id);
+ return task;
+ }
+
+ /*
+ * @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(WorkflowTask item, List fields, List forcedFields, Form form,
+ Map context)
+ {
+ TypeDefinition typeDef = item.definition.metadata;
+ String type = typeDef.getName().toPrefixString(namespaceService);
+ setFormItemType(form, type);
+
+ // TODO Check this URL is OK.
+ setFormItemUrl(form, "/api/task/" + item.id);
+
+ FieldCreationData data = new FieldCreationData(item, forcedFields, null);
+ List fieldsToAdd = generateFields(data, fields);
+ for (FieldInfo fieldToAdd : fieldsToAdd)
+ {
+ if (fieldToAdd.isValid())
+ {
+ FieldDefinition fieldDef = fieldToAdd.getFieldDefinition();
+ form.addFieldDefinition(fieldDef);
+ Object value = data.getPropValues().get(fieldToAdd.getFullName());
+ if (value != null)
+ {
+ form.addData(fieldDef.getDataKeyName(), value);
+ }
+ }
+ }
+ }
+
+ private List generateFields(FieldCreationData data, List fields)
+ {
+ ArrayList fieldData = new ArrayList(fields.size());
+ for (String fieldName : fields)
+ {
+ fieldData.add(makeFieldInfo(data, fieldName));
+ }
+ return fieldData;
+ }
+
+ private FieldInfo makeFieldInfo(FieldCreationData data, String fieldName)
+ {
+ return new FieldInfo(fieldName, data, factory, dictionaryService, namespaceService);
+ }
+
+ /*
+ * @see
+ * org.alfresco.repo.forms.processor.FilteredFormProcessor#internalPersist
+ * (java.lang.Object, org.alfresco.repo.forms.FormData)
+ */
+ @Override
+ protected WorkflowTask internalPersist(WorkflowTask item, FormData data)
+ {
+ //TODO Implement this method properly.
+ Map props = new HashMap();
+ for (FieldData fieldData : data)
+ {
+ fieldData.getName();
+ }
+ workflowService.updateTask(item.id, props, null, null);
+ return null;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/forms/processor/task/TaskFormProcessorTest.java b/source/java/org/alfresco/repo/forms/processor/task/TaskFormProcessorTest.java
new file mode 100644
index 0000000000..15986e1e1f
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/task/TaskFormProcessorTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.repo.forms.processor.task;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+
+import org.alfresco.repo.forms.Item;
+import org.alfresco.repo.workflow.WorkflowModel;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.workflow.WorkflowException;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.NamespaceServiceMemoryImpl;
+import org.alfresco.service.namespace.QName;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+/**
+ * @author Nick Smith
+ */
+public class TaskFormProcessorTest extends TestCase
+{
+ /**
+ *
+ */
+ private static final String TASK_ID = "Real Id";
+
+ private WorkflowService workflowService;
+
+ TaskFormProcessor processor;
+
+ private WorkflowTask task;
+
+ public void testGetTypedItem() throws Exception
+ {
+ try
+ {
+ processor.getTypedItem(null);
+ fail("Should have thrown an Exception here!");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // Do nothing!
+ }
+ try
+ {
+ processor.getTypedItem(new Item("task", "bad id"));
+ fail("Should have thrown an Exception here!");
+ }
+ catch (WorkflowException e)
+ {
+ // Do nothing!
+ }
+
+ Item item = new Item("task", TASK_ID);
+ WorkflowTask task = processor.getTypedItem(item);
+ assertNotNull(task);
+ assertEquals(TASK_ID, task.id);
+ }
+
+ // public void testGenerateSimple()
+ // {
+ // Item item = new Item("task", TASK_ID);
+ // Form form = new Form(item);
+ // List fields = Arrays.asList("description");
+ // processor.internalGenerate(task, fields, null, form, null);
+ // }
+
+ // public void testPersist() throws Exception
+ // {
+ // FormData data = new FormData();
+ // processor.internalPersist(task, data);
+ // }
+
+ /*
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ task = makeTask();
+ workflowService = makeWorkflowService();
+ DictionaryService dictionaryService = makeDictionaryService();
+ NamespaceService namespaceService = makeNamespaceService();
+ processor = new TaskFormProcessor(workflowService, namespaceService, dictionaryService);
+ }
+
+ /**
+ *
+ */
+ private WorkflowTask makeTask()
+ {
+ WorkflowTask task = new WorkflowTask();
+ task.id = TASK_ID;
+ task.description = "Description";
+ HashMap properties = new HashMap();
+ QName descName = WorkflowModel.PROP_DESCRIPTION;
+ properties.put(descName, "Description");
+ return task;
+
+ }
+
+ private NamespaceService makeNamespaceService()
+ {
+ return new NamespaceServiceMemoryImpl();
+ }
+
+ private DictionaryService makeDictionaryService()
+ {
+ return mock(DictionaryService.class);
+ }
+
+ private WorkflowService makeWorkflowService()
+ {
+ WorkflowService service = mock(WorkflowService.class);
+ when(service.getTaskById(anyString())).thenAnswer(new Answer()
+ {
+
+ public WorkflowTask answer(InvocationOnMock invocation) throws Throwable
+ {
+ String id = (String) invocation.getArguments()[0];
+ if (TASK_ID.equals(id))
+ return task;
+ else
+ throw new WorkflowException("Task Id not found!");
+ }
+ });
+ return service;
+ }
+}
diff --git a/source/java/org/alfresco/service/cmr/dictionary/AssociationDefinition.java b/source/java/org/alfresco/service/cmr/dictionary/AssociationDefinition.java
index 669d2c9d8a..8fe3a67f29 100644
--- a/source/java/org/alfresco/service/cmr/dictionary/AssociationDefinition.java
+++ b/source/java/org/alfresco/service/cmr/dictionary/AssociationDefinition.java
@@ -33,7 +33,7 @@ import org.alfresco.service.namespace.QName;
* @author David Caruana
*
*/
-public interface AssociationDefinition
+public interface AssociationDefinition extends ClassAttributeDefinition
{
/**
diff --git a/source/java/org/alfresco/service/cmr/dictionary/ClassAttributeDefinition.java b/source/java/org/alfresco/service/cmr/dictionary/ClassAttributeDefinition.java
new file mode 100644
index 0000000000..c22fed1d6e
--- /dev/null
+++ b/source/java/org/alfresco/service/cmr/dictionary/ClassAttributeDefinition.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.service.cmr.dictionary;
+
+import org.alfresco.service.namespace.QName;
+
+/**
+ *
+ * @author Nick Smith
+ */
+public interface ClassAttributeDefinition
+{
+ /**
+ * @return defining model
+ */
+ public ModelDefinition getModel();
+
+ /**
+ * @return the qualified name
+ */
+ public QName getName();
+
+ /**
+ * @return the human-readable title
+ */
+ public String getTitle();
+
+ /**
+ * @return the human-readable description
+ */
+ public String getDescription();
+
+ /**
+ * Is this association or property maintained by the Repository?
+ *
+ * @return true => system maintained, false => client may maintain
+ */
+ public boolean isProtected();
+
+}
diff --git a/source/java/org/alfresco/service/cmr/dictionary/PropertyDefinition.java b/source/java/org/alfresco/service/cmr/dictionary/PropertyDefinition.java
index 4a8d9d201a..4ecab02fec 100644
--- a/source/java/org/alfresco/service/cmr/dictionary/PropertyDefinition.java
+++ b/source/java/org/alfresco/service/cmr/dictionary/PropertyDefinition.java
@@ -22,6 +22,7 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
+
package org.alfresco.service.cmr.dictionary;
import java.util.List;
@@ -34,33 +35,33 @@ import org.alfresco.service.namespace.QName;
*
* @author David Caruana
*/
-public interface PropertyDefinition
+public interface PropertyDefinition extends ClassAttributeDefinition
{
/**
- * @return defining model
+ * @return defining model
*/
public ModelDefinition getModel();
-
+
/**
* @return the qualified name of the property
*/
public QName getName();
/**
- * @return the human-readable class title
+ * @return the human-readable class title
*/
public String getTitle();
-
+
/**
- * @return the human-readable class description
+ * @return the human-readable class description
*/
public String getDescription();
-
+
/**
- * @return the default value
+ * @return the default value
*/
public String getDefaultValue();
-
+
/**
* @return the qualified name of the property type
*/
@@ -68,56 +69,59 @@ public interface PropertyDefinition
/**
* @return Returns the owning class's defintion
- */
+ */
public ClassDefinition getContainerClass();
-
+
public boolean isOverride();
-
+
/**
- * @return true => multi-valued, false => single-valued
+ * @return true => multi-valued, false => single-valued
*/
public boolean isMultiValued();
/**
- * @return true => mandatory, false => optional
+ * @return true => mandatory, false => optional
*/
public boolean isMandatory();
-
+
/**
* @return Returns true if the system enforces the presence of
- * {@link #isMandatory() mandatory} properties, or false if the system
- * just marks objects that don't have all mandatory properties present.
+ * {@link #isMandatory() mandatory} properties, or false if the
+ * system just marks objects that don't have all mandatory
+ * properties present.
*/
public boolean isMandatoryEnforced();
-
+
/**
- * @return true => system maintained, false => client may maintain
+ * @return true => system maintained, false => client may maintain
*/
public boolean isProtected();
/**
- * @return true => indexed, false => not indexed
+ * @return true => indexed, false => not indexed
*/
public boolean isIndexed();
-
+
/**
- * @return true => stored in index
+ * @return true => stored in index
*/
public boolean isStoredInIndex();
/**
- * @return IndexTokenisationMode.TREU => tokenised when it is indexed (the stored value will not be tokenised)
+ * @return IndexTokenisationMode.TREU => tokenised when it is indexed (the
+ * stored value will not be tokenised)
*/
public IndexTokenisationMode getIndexTokenisationMode();
-
+
/**
* All non atomic properties will be indexed at the same time.
- *
- * @return true => The attribute must be indexed in the commit of the transaction.
- * false => the indexing will be done in the background and may be out of date.
+ *
+ * @return true => The attribute must be indexed in the commit of the
+ * transaction. false => the indexing will be done in the background
+ * and may be out of date.
*/
public boolean isIndexedAtomically();
-
+
/**
* Get all constraints that apply to the property value
*