FormService improvements

- A 'dataKeyName' property has been added to the field definition to point to the corresponding data
- FormProcessors can now return a submission url to use on the client
- FormProcessors are now responsible for returning a sensible URL to represent the 'item' being processed
- Updated all affected tests

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14021 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2009-04-20 14:53:04 +00:00
parent c09c6ac692
commit 966201871c
9 changed files with 211 additions and 106 deletions

View File

@@ -137,6 +137,7 @@ public class AssociationFieldDefinition extends FieldDefinition
buffer.append(", description=").append(this.description); buffer.append(", description=").append(this.description);
buffer.append(", binding=").append(this.binding); buffer.append(", binding=").append(this.binding);
buffer.append(", defaultValue=").append(this.defaultValue); buffer.append(", defaultValue=").append(this.defaultValue);
buffer.append(", dataKeyName=").append(this.dataKeyName);
buffer.append(", group=").append(this.group); buffer.append(", group=").append(this.group);
buffer.append(", protectedField=").append(this.protectedField); buffer.append(", protectedField=").append(this.protectedField);
buffer.append(")"); buffer.append(")");

View File

@@ -36,6 +36,7 @@ public abstract class FieldDefinition
protected String description; protected String description;
protected String binding; protected String binding;
protected String defaultValue; protected String defaultValue;
protected String dataKeyName;
protected FieldGroup group; protected FieldGroup group;
protected boolean protectedField = false; protected boolean protectedField = false;
@@ -141,6 +142,26 @@ public abstract class FieldDefinition
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
} }
/**
* Returns the name of the key being used to hold the data for the field
*
* @return Name of the key being used to hold the data for the field
*/
public String getDataKeyName()
{
return this.dataKeyName;
}
/**
* Sets the name of the key to be used to hold the data for the field
*
* @param dataKeyName The name of the key to be used to hold the data for the field
*/
public void setDataKeyName(String dataKeyName)
{
this.dataKeyName = dataKeyName;
}
/** /**
* Returns the group the field may be a part of * Returns the group the field may be a part of
* *

View File

@@ -36,7 +36,7 @@ import java.util.List;
public class Form public class Form
{ {
protected Item item; protected Item item;
protected String type; protected String submissionUrl;
protected List<FieldDefinition> fieldDefinitions; protected List<FieldDefinition> fieldDefinitions;
protected Collection<FieldGroup> fieldGroups; protected Collection<FieldGroup> fieldGroups;
protected FormData data; protected FormData data;
@@ -62,24 +62,23 @@ public class Form
} }
/** /**
* Returns the type of the item the form is for, could be a content model type, a * Returns the submission URL to use for the form
* workflow task type, an XML schema etc.
* *
* @return The type of the item * @return URL to submit to
*/ */
public String getType() public String getSubmissionUrl()
{ {
return this.type; return this.submissionUrl;
} }
/** /**
* Sets the type of the item this Form represents * Sets the submission URL the form should use
* *
* @param type The type * @param url URL to submit to
*/ */
public void setType(String type) public void setSubmissionUrl(String url)
{ {
this.type = type; this.submissionUrl = url;
} }
/** /**
@@ -201,7 +200,7 @@ public class Form
StringBuilder buffer = new StringBuilder(super.toString()); StringBuilder buffer = new StringBuilder(super.toString());
buffer.append(" ("); buffer.append(" (");
buffer.append("item=").append(this.item); buffer.append("item=").append(this.item);
buffer.append(", type=").append(this.type); buffer.append(", submissionUrl=").append(this.submissionUrl);
buffer.append(", fieldGroups=").append(this.fieldGroups); buffer.append(", fieldGroups=").append(this.fieldGroups);
buffer.append("\nfieldDefinitions=").append(this.fieldDefinitions); buffer.append("\nfieldDefinitions=").append(this.fieldDefinitions);
buffer.append("\nformData=").append(this.data); buffer.append("\nformData=").append(this.data);

View File

@@ -240,7 +240,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
// check the type is correct // check the type is correct
assertEquals(ContentModel.TYPE_CONTENT.toPrefixString(this.namespaceService), assertEquals(ContentModel.TYPE_CONTENT.toPrefixString(this.namespaceService),
form.getType()); form.getItem().getType());
// check there is no group info // check there is no group info
assertNull("Expecting the form groups to be null!", form.getFieldGroups()); assertNull("Expecting the form groups to be null!", form.getFieldGroups());
@@ -351,16 +351,16 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertNotNull("Expecting form data", data); assertNotNull("Expecting form data", data);
Map<String, FormData.FieldData> fieldData = data.getData(); Map<String, FormData.FieldData> fieldData = data.getData();
assertNotNull("Expecting field data", fieldData); assertNotNull("Expecting field data", fieldData);
assertEquals(VALUE_TITLE, fieldData.get("prop:cm:title").getValue()); assertEquals(VALUE_TITLE, fieldData.get(titleField.getDataKeyName()).getValue());
assertEquals(VALUE_DESCRIPTION, fieldData.get("prop:cm:description").getValue()); assertEquals(VALUE_DESCRIPTION, fieldData.get(descField.getDataKeyName()).getValue());
assertEquals(VALUE_MIMETYPE, fieldData.get("prop:mimetype").getValue()); assertEquals(VALUE_MIMETYPE, fieldData.get(mimetypeField.getDataKeyName()).getValue());
assertEquals(VALUE_ENCODING, fieldData.get("prop:encoding").getValue()); assertEquals(VALUE_ENCODING, fieldData.get(encodingField.getDataKeyName()).getValue());
assertEquals(VALUE_ORIGINATOR, fieldData.get("prop:cm:originator").getValue()); assertEquals(VALUE_ORIGINATOR, fieldData.get(originatorField.getDataKeyName()).getValue());
assertEquals(VALUE_ADDRESSEE, fieldData.get("prop:cm:addressee").getValue()); assertEquals(VALUE_ADDRESSEE, fieldData.get(addresseeField.getDataKeyName()).getValue());
assertEquals(VALUE_SUBJECT, fieldData.get("prop:cm:subjectline").getValue()); assertEquals(VALUE_SUBJECT, fieldData.get(subjectField.getDataKeyName()).getValue());
assertTrue("Expecting size to be > 0", ((Long)fieldData.get("prop:size").getValue()).longValue() > 0); assertTrue("Expecting size to be > 0", ((Long)fieldData.get(sizeField.getDataKeyName()).getValue()).longValue() > 0);
String addressees = (String)fieldData.get("prop:cm:addressees").getValue(); String addressees = (String)fieldData.get(addresseesField.getDataKeyName()).getValue();
assertNotNull(addressees); assertNotNull(addressees);
assertTrue("Expecting the addressees value to have at least 1 comma", addressees.indexOf(",") != -1); assertTrue("Expecting the addressees value to have at least 1 comma", addressees.indexOf(",") != -1);
String[] addresseesArr = StringUtils.delimitedListToStringArray(addressees, ","); String[] addresseesArr = StringUtils.delimitedListToStringArray(addressees, ",");
@@ -371,10 +371,10 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
Calendar calTestValue = Calendar.getInstance(); Calendar calTestValue = Calendar.getInstance();
calTestValue.setTime(VALUE_SENT_DATE); calTestValue.setTime(VALUE_SENT_DATE);
Calendar calServiceValue = Calendar.getInstance(); Calendar calServiceValue = Calendar.getInstance();
calServiceValue.setTime((Date)fieldData.get("prop:cm:sentdate").getValue()); calServiceValue.setTime((Date)fieldData.get(sentDateField.getDataKeyName()).getValue());
assertEquals(calTestValue.getTimeInMillis(), calServiceValue.getTimeInMillis()); assertEquals(calTestValue.getTimeInMillis(), calServiceValue.getTimeInMillis());
List<String> targets = (List<String>)fieldData.get("assoc:cm:references").getValue(); List<String> targets = (List<String>)fieldData.get(referencesField.getDataKeyName()).getValue();
assertEquals("Expecting 1 target", 1, targets.size()); assertEquals("Expecting 1 target", 1, targets.size());
assertEquals(this.associatedDoc.toString(), targets.get(0)); assertEquals(this.associatedDoc.toString(), targets.get(0));
} }
@@ -404,7 +404,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
// check the type is correct // check the type is correct
assertEquals(ContentModel.TYPE_CONTENT.toPrefixString(this.namespaceService), assertEquals(ContentModel.TYPE_CONTENT.toPrefixString(this.namespaceService),
form.getType()); form.getItem().getType());
// check there is no group info // check there is no group info
assertNull("Expecting the form groups to be null!", form.getFieldGroups()); assertNull("Expecting the form groups to be null!", form.getFieldGroups());
@@ -482,23 +482,23 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertNotNull("Expecting form data", data); assertNotNull("Expecting form data", data);
Map<String, FormData.FieldData> fieldData = data.getData(); Map<String, FormData.FieldData> fieldData = data.getData();
assertNotNull("Expecting field data", fieldData); assertNotNull("Expecting field data", fieldData);
assertEquals(this.documentName, fieldData.get("prop:cm:name").getValue()); assertEquals(this.documentName, fieldData.get(nameField.getDataKeyName()).getValue());
assertEquals(VALUE_TITLE, fieldData.get("prop:cm:title").getValue()); assertEquals(VALUE_TITLE, fieldData.get(titleField.getDataKeyName()).getValue());
assertEquals(VALUE_MIMETYPE, fieldData.get("prop:mimetype").getValue()); assertEquals(VALUE_MIMETYPE, fieldData.get(mimetypeField.getDataKeyName()).getValue());
assertEquals(VALUE_SUBJECT, fieldData.get("prop:cm:subjectline").getValue()); assertEquals(VALUE_SUBJECT, fieldData.get(subjectField.getDataKeyName()).getValue());
assertEquals(USER_ONE, fieldData.get("prop:cm:modifier").getValue()); assertEquals(USER_ONE, fieldData.get(modifierField.getDataKeyName()).getValue());
Date modifiedDate = (Date)fieldData.get("prop:cm:modified").getValue(); Date modifiedDate = (Date)fieldData.get(modifiedField.getDataKeyName()).getValue();
assertNotNull("Expecting to find modified date", modifiedDate); assertNotNull("Expecting to find modified date", modifiedDate);
assertTrue("Expecting modified field to return a Date", (modifiedDate instanceof Date)); assertTrue("Expecting modified field to return a Date", (modifiedDate instanceof Date));
Calendar calTestValue = Calendar.getInstance(); Calendar calTestValue = Calendar.getInstance();
calTestValue.setTime(VALUE_SENT_DATE); calTestValue.setTime(VALUE_SENT_DATE);
Calendar calServiceValue = Calendar.getInstance(); Calendar calServiceValue = Calendar.getInstance();
calServiceValue.setTime((Date)fieldData.get("prop:cm:sentdate").getValue()); calServiceValue.setTime((Date)fieldData.get(sentDateField.getDataKeyName()).getValue());
assertEquals(calTestValue.getTimeInMillis(), calServiceValue.getTimeInMillis()); assertEquals(calTestValue.getTimeInMillis(), calServiceValue.getTimeInMillis());
List<String> targets = (List<String>)fieldData.get("assoc:cm:references").getValue(); List<String> targets = (List<String>)fieldData.get(referencesField.getDataKeyName()).getValue();
assertEquals("Expecting 1 target", 1, targets.size()); assertEquals("Expecting 1 target", 1, targets.size());
assertEquals(this.associatedDoc.toString(), targets.get(0)); assertEquals(this.associatedDoc.toString(), targets.get(0));
} }
@@ -554,8 +554,8 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertNotNull("Expecting form data", data); assertNotNull("Expecting form data", data);
Map<String, FormData.FieldData> fieldData = data.getData(); Map<String, FormData.FieldData> fieldData = data.getData();
assertNotNull("Expecting field data", fieldData); assertNotNull("Expecting field data", fieldData);
assertEquals(this.documentName, fieldData.get("prop:cm:name").getValue()); assertEquals(this.documentName, fieldData.get(nameField.getDataKeyName()).getValue());
assertEquals(VALUE_TITLE, fieldData.get("prop:cm:title").getValue()); assertEquals(VALUE_TITLE, fieldData.get(titleField.getDataKeyName()).getValue());
} }
public void testForcedFieldsDocForm() throws Exception public void testForcedFieldsDocForm() throws Exception
@@ -622,9 +622,9 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertNotNull("Expecting form data", data); assertNotNull("Expecting form data", data);
Map<String, FormData.FieldData> fieldData = data.getData(); Map<String, FormData.FieldData> fieldData = data.getData();
assertNotNull("Expecting field data", fieldData); assertNotNull("Expecting field data", fieldData);
assertEquals(this.documentName, fieldData.get("prop:cm:name").getValue()); assertEquals(this.documentName, fieldData.get(nameField.getDataKeyName()).getValue());
assertEquals(VALUE_TITLE, fieldData.get("prop:cm:title").getValue()); assertEquals(VALUE_TITLE, fieldData.get(titleField.getDataKeyName()).getValue());
assertNull("Didn't expect to find a value for cm:author", fieldData.get("prop:cm:author")); assertNull("Didn't expect to find a value for cm:author", fieldData.get(authorField.getDataKeyName()));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -641,7 +641,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
// check the type is correct // check the type is correct
assertEquals(ContentModel.TYPE_FOLDER.toPrefixString(this.namespaceService), assertEquals(ContentModel.TYPE_FOLDER.toPrefixString(this.namespaceService),
form.getType()); form.getItem().getType());
// check there is no group info // check there is no group info
assertNull("Expecting the form groups to be null!", form.getFieldGroups()); assertNull("Expecting the form groups to be null!", form.getFieldGroups());
@@ -695,19 +695,18 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertNotNull("Expecting form data", data); assertNotNull("Expecting form data", data);
Map<String, FormData.FieldData> fieldData = data.getData(); Map<String, FormData.FieldData> fieldData = data.getData();
assertNotNull("Expecting field data", fieldData); assertNotNull("Expecting field data", fieldData);
assertEquals(this.folderName, fieldData.get("prop:cm:name").getValue()); assertEquals(this.folderName, fieldData.get(nameField.getDataKeyName()).getValue());
List<String> children = (List<String>)fieldData.get("assoc:cm:contains").getValue(); List<String> children = (List<String>)fieldData.get(containsField.getDataKeyName()).getValue();
assertEquals("Expecting 3 children", 3, children.size()); assertEquals("Expecting 3 children", 3, children.size());
assertEquals(this.document.toString(), children.get(0)); assertEquals(this.document.toString(), children.get(0));
assertEquals(this.associatedDoc.toString(), children.get(1)); assertEquals(this.associatedDoc.toString(), children.get(1));
assertEquals(this.childDoc.toString(), children.get(2)); assertEquals(this.childDoc.toString(), children.get(2));
} }
@SuppressWarnings("unchecked")
public void testGetSelectedFieldsFolderForm() throws Exception public void testGetSelectedFieldsFolderForm() throws Exception
{ {
// attempt to get a form with fields that are not appropriate // TODO: attempt to get a form with fields that are not appropriate
// for a folder type i.e. mimetype and encoding // for a folder type i.e. mimetype and encoding
} }
@@ -720,30 +719,30 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
// update the name // update the name
String newName = "new-" + this.documentName; String newName = "new-" + this.documentName;
data.addData("prop:cm:name", newName); data.addData("prop_cm_name", newName);
// update the title property // update the title property
String newTitle = "This is the new title property"; String newTitle = "This is the new title property";
data.addData("prop:cm:title", newTitle); data.addData("prop_cm_title", newTitle);
// update the mimetype // update the mimetype
String newMimetype = MimetypeMap.MIMETYPE_HTML; String newMimetype = MimetypeMap.MIMETYPE_HTML;
data.addData("prop:mimetype", newMimetype); data.addData("prop_mimetype", newMimetype);
// update the originator // update the originator
String newOriginator = "jane@example.com"; String newOriginator = "jane@example.com";
data.addData("prop:cm:originator", newOriginator); data.addData("prop_cm_originator", newOriginator);
// update the adressees, add another // update the adressees, add another
String newAddressees = VALUE_ADDRESSEES1 + "," + VALUE_ADDRESSEES2 + "," + VALUE_ADDRESSEES3; String newAddressees = VALUE_ADDRESSEES1 + "," + VALUE_ADDRESSEES2 + "," + VALUE_ADDRESSEES3;
data.addData("prop:cm:addressees", newAddressees); data.addData("prop_cm_addressees", newAddressees);
// set the date to null (using an empty string) // set the date to null (using an empty string)
data.addData("prop:cm:sentdate", ""); data.addData("prop_cm_sentdate", "");
// try and update non-existent properties (make sure there are no exceptions) // try and update non-existent properties (make sure there are no exceptions)
data.addData("prop:cm:wrong", "This should not be persisted"); data.addData("prop_cm_wrong", "This should not be persisted");
data.addData("cm:wrong", "This should not be persisted"); data.addData("cm_wrong", "This should not be persisted");
// persist the data // persist the data
this.formService.saveForm(new Item(NODE_FORM_ITEM_KIND, this.document.toString()), data); this.formService.saveForm(new Item(NODE_FORM_ITEM_KIND, this.document.toString()), data);

View File

@@ -28,13 +28,18 @@ import org.alfresco.util.ParameterCheck;
/** /**
* Represents an item a form is generated for. * Represents an item a form is generated for.
* <p>This class can be augmented with the item's type and a
* representational URL by the form processor used to process
* the item.</p>
* *
* @author Gavin Cornwell * @author Gavin Cornwell
*/ */
public class Item public class Item
{ {
private String kind; protected String kind;
private String id; protected String id;
protected String type;
protected String url;
/** /**
* Constructs an item. * Constructs an item.
@@ -71,12 +76,65 @@ public class Item
return this.id; return this.id;
} }
/**
* Returns the type of the item the form is for, could be a content model type, a
* workflow task type, an XML schema etc.
*
* @return The type of the item
*/
public String getType()
{
return this.type;
}
/**
* Returns a URL that represents the item
*
* @return A URL representing the item
*/
public String getUrl()
{
return this.url;
}
/**
* Sets the type of the item
*
* @param type The type
*/
public void setType(String type)
{
this.type = type;
}
/**
* Sets the URL that represents the item
*
* @param url The URL
*/
public void setUrl(String url)
{
this.url = url;
}
/* /*
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@Override @Override
public String toString() public String toString()
{ {
return "[" + this.kind + "]" + this.id; StringBuilder builder = new StringBuilder("[");
builder.append(this.kind).append("]").append(this.id);
if (this.type != null)
{
builder.append(", type=").append(this.type);
}
if (this.url != null)
{
builder.append(", url=").append(this.url);
}
return builder.toString();
} }
} }

View File

@@ -137,6 +137,7 @@ public class PropertyFieldDefinition extends FieldDefinition
buffer.append(", description=").append(this.description); buffer.append(", description=").append(this.description);
buffer.append(", binding=").append(this.binding); buffer.append(", binding=").append(this.binding);
buffer.append(", defaultValue=").append(this.defaultValue); buffer.append(", defaultValue=").append(this.defaultValue);
buffer.append(", dataKeyName=").append(this.dataKeyName);
buffer.append(", group=").append(this.group); buffer.append(", group=").append(this.group);
buffer.append(", protectedField=").append(this.protectedField); buffer.append(", protectedField=").append(this.protectedField);
buffer.append(", mandatory=").append(this.mandatory); buffer.append(", mandatory=").append(this.mandatory);

View File

@@ -78,10 +78,11 @@ public class NodeHandler extends AbstractHandler
{ {
private static final Log logger = LogFactory.getLog(NodeHandler.class); private static final Log logger = LogFactory.getLog(NodeHandler.class);
protected static final String PROP_PREFIX = "prop:"; protected static final String PROP_PREFIX = "prop_";
protected static final String ASSOC_PREFIX = "assoc:"; protected static final String ASSOC_PREFIX = "assoc_";
protected static final String ASSOC_ADD_SUFFIX = "_added"; protected static final String ASSOC_ADD_SUFFIX = "_added";
protected static final String ASSOC_REMOVE_SUFFIX = "_removed"; protected static final String ASSOC_REMOVE_SUFFIX = "_removed";
protected static final String DATA_KEY_SEPARATOR = "_";
protected static final String TRANSIENT_MIMETYPE = "mimetype"; protected static final String TRANSIENT_MIMETYPE = "mimetype";
protected static final String TRANSIENT_SIZE = "size"; protected static final String TRANSIENT_SIZE = "size";
@@ -105,7 +106,7 @@ public class NodeHandler extends AbstractHandler
* These names will look like <code>"prop:cm:name"</code>. * These names will look like <code>"prop:cm:name"</code>.
* The pattern can also be used to extract the "cm" and the "name" parts. * The pattern can also be used to extract the "cm" and the "name" parts.
*/ */
protected Pattern propertyNamePattern = Pattern.compile(PROP_PREFIX + "(.*){1}?:(.*){1}?"); protected Pattern propertyNamePattern = Pattern.compile(PROP_PREFIX + "(.*){1}?_(.*){1}?");
/** /**
* A regular expression which can be used to match tranisent property names. * A regular expression which can be used to match tranisent property names.
@@ -119,7 +120,7 @@ public class NodeHandler extends AbstractHandler
* These names will look like <code>"assoc:cm:references_added"</code>. * These names will look like <code>"assoc:cm:references_added"</code>.
* The pattern can also be used to extract the "cm", the "name" and the suffix parts. * The pattern can also be used to extract the "cm", the "name" and the suffix parts.
*/ */
protected Pattern associationNamePattern = Pattern.compile(ASSOC_PREFIX + "(.*){1}?:(.*){1}?(_[a-zA-Z]+)"); protected Pattern associationNamePattern = Pattern.compile(ASSOC_PREFIX + "(.*){1}?_(.*){1}?(_[a-zA-Z]+)");
/** /**
* Sets the node service * Sets the node service
@@ -191,9 +192,14 @@ public class NodeHandler extends AbstractHandler
*/ */
protected void generateNode(NodeRef nodeRef, List<String> fields, List<String> forcedFields, Form form) protected void generateNode(NodeRef nodeRef, List<String> fields, List<String> forcedFields, Form form)
{ {
// set the type // set the type and URL of the item
QName type = this.nodeService.getType(nodeRef); QName type = this.nodeService.getType(nodeRef);
form.setType(type.toPrefixString(this.namespaceService)); form.getItem().setType(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());
if (fields != null && fields.size() > 0) if (fields != null && fields.size() > 0)
{ {
@@ -396,6 +402,7 @@ public class NodeHandler extends AbstractHandler
protected void generatePropertyField(PropertyDefinition propDef, Serializable propValue, Form form) protected void generatePropertyField(PropertyDefinition propDef, Serializable propValue, Form form)
{ {
String propName = propDef.getName().toPrefixString(this.namespaceService); String propName = propDef.getName().toPrefixString(this.namespaceService);
String[] nameParts = QName.splitPrefixedQName(propName);
PropertyFieldDefinition fieldDef = new PropertyFieldDefinition( PropertyFieldDefinition fieldDef = new PropertyFieldDefinition(
propName, propDef.getDataType().getName().toPrefixString( propName, propDef.getDataType().getName().toPrefixString(
this.namespaceService)); this.namespaceService));
@@ -412,6 +419,10 @@ public class NodeHandler extends AbstractHandler
fieldDef.setProtectedField(propDef.isProtected()); fieldDef.setProtectedField(propDef.isProtected());
fieldDef.setRepeating(propDef.isMultiValued()); fieldDef.setRepeating(propDef.isMultiValued());
// define the data key name and set
String dataKeyName = PROP_PREFIX + nameParts[0] + DATA_KEY_SEPARATOR + nameParts[1];
fieldDef.setDataKeyName(dataKeyName);
// setup constraints for the property // setup constraints for the property
List<ConstraintDefinition> constraints = propDef.getConstraints(); List<ConstraintDefinition> constraints = propDef.getConstraints();
if (constraints != null && constraints.size() > 0) if (constraints != null && constraints.size() > 0)
@@ -462,7 +473,7 @@ public class NodeHandler extends AbstractHandler
propValue = makeListString((List)propValue); propValue = makeListString((List)propValue);
} }
form.addData(PROP_PREFIX + fieldDef.getName(), propValue); form.addData(dataKeyName, propValue);
} }
} }
@@ -502,13 +513,15 @@ public class NodeHandler extends AbstractHandler
*/ */
protected void generateMimetypePropertyField(ContentData content, Form form) protected void generateMimetypePropertyField(ContentData content, Form form)
{ {
String dataKeyName = PROP_PREFIX + TRANSIENT_MIMETYPE;
PropertyFieldDefinition mimetypeField = new PropertyFieldDefinition( PropertyFieldDefinition mimetypeField = new PropertyFieldDefinition(
TRANSIENT_MIMETYPE, DataTypeDefinition.TEXT.toPrefixString( TRANSIENT_MIMETYPE, DataTypeDefinition.TEXT.toPrefixString(
this.namespaceService)); this.namespaceService));
mimetypeField.setLabel(I18NUtil.getMessage(MSG_MIMETYPE_LABEL)); mimetypeField.setLabel(I18NUtil.getMessage(MSG_MIMETYPE_LABEL));
mimetypeField.setDescription(I18NUtil.getMessage(MSG_MIMETYPE_DESC)); mimetypeField.setDescription(I18NUtil.getMessage(MSG_MIMETYPE_DESC));
mimetypeField.setDataKeyName(dataKeyName);
form.addFieldDefinition(mimetypeField); form.addFieldDefinition(mimetypeField);
form.addData(PROP_PREFIX + TRANSIENT_MIMETYPE, content.getMimetype()); form.addData(dataKeyName, content.getMimetype());
} }
/** /**
@@ -519,13 +532,15 @@ public class NodeHandler extends AbstractHandler
*/ */
protected void generateEncodingPropertyField(ContentData content, Form form) protected void generateEncodingPropertyField(ContentData content, Form form)
{ {
String dataKeyName = PROP_PREFIX + TRANSIENT_ENCODING;
PropertyFieldDefinition encodingField = new PropertyFieldDefinition( PropertyFieldDefinition encodingField = new PropertyFieldDefinition(
TRANSIENT_ENCODING, DataTypeDefinition.TEXT.toPrefixString( TRANSIENT_ENCODING, DataTypeDefinition.TEXT.toPrefixString(
this.namespaceService)); this.namespaceService));
encodingField.setLabel(I18NUtil.getMessage(MSG_ENCODING_LABEL)); encodingField.setLabel(I18NUtil.getMessage(MSG_ENCODING_LABEL));
encodingField.setDescription(I18NUtil.getMessage(MSG_ENCODING_DESC)); encodingField.setDescription(I18NUtil.getMessage(MSG_ENCODING_DESC));
encodingField.setDataKeyName(dataKeyName);
form.addFieldDefinition(encodingField); form.addFieldDefinition(encodingField);
form.addData(PROP_PREFIX + TRANSIENT_ENCODING, content.getEncoding()); form.addData(dataKeyName, content.getEncoding());
} }
/** /**
@@ -536,14 +551,16 @@ public class NodeHandler extends AbstractHandler
*/ */
protected void generateSizePropertyField(ContentData content, Form form) protected void generateSizePropertyField(ContentData content, Form form)
{ {
String dataKeyName = PROP_PREFIX + TRANSIENT_SIZE;
PropertyFieldDefinition sizeField = new PropertyFieldDefinition( PropertyFieldDefinition sizeField = new PropertyFieldDefinition(
TRANSIENT_SIZE, DataTypeDefinition.LONG.toPrefixString( TRANSIENT_SIZE, DataTypeDefinition.LONG.toPrefixString(
this.namespaceService)); this.namespaceService));
sizeField.setLabel(I18NUtil.getMessage(MSG_SIZE_LABEL)); sizeField.setLabel(I18NUtil.getMessage(MSG_SIZE_LABEL));
sizeField.setDescription(I18NUtil.getMessage(MSG_SIZE_DESC)); sizeField.setDescription(I18NUtil.getMessage(MSG_SIZE_DESC));
sizeField.setDataKeyName(dataKeyName);
sizeField.setProtectedField(true); sizeField.setProtectedField(true);
form.addFieldDefinition(sizeField); form.addFieldDefinition(sizeField);
form.addData(PROP_PREFIX + TRANSIENT_SIZE, new Long(content.getSize())); form.addData(dataKeyName, new Long(content.getSize()));
} }
/** /**
@@ -575,6 +592,7 @@ public class NodeHandler extends AbstractHandler
QName assocType = assoc.getTypeQName(); QName assocType = assoc.getTypeQName();
String assocName = assocType.toPrefixString(this.namespaceService); String assocName = assocType.toPrefixString(this.namespaceService);
String assocValue = assoc.getTargetRef().toString(); String assocValue = assoc.getTargetRef().toString();
String dataKeyName = ASSOC_PREFIX + assocName.replace(":", DATA_KEY_SEPARATOR);
// setup the field definition for the association if it hasn't before // setup the field definition for the association if it hasn't before
AssociationFieldDefinition fieldDef = assocFieldDefs.get(assocName); AssociationFieldDefinition fieldDef = assocFieldDefs.get(assocName);
@@ -599,25 +617,24 @@ public class NodeHandler extends AbstractHandler
fieldDef.setProtectedField(assocDef.isProtected()); fieldDef.setProtectedField(assocDef.isProtected());
fieldDef.setEndpointMandatory(assocDef.isTargetMandatory()); fieldDef.setEndpointMandatory(assocDef.isTargetMandatory());
fieldDef.setEndpointMany(assocDef.isTargetMany()); fieldDef.setEndpointMany(assocDef.isTargetMany());
fieldDef.setDataKeyName(dataKeyName);
// add definition to Form and to internal cache // add definition to Form and to internal cache
form.addFieldDefinition(fieldDef); form.addFieldDefinition(fieldDef);
assocFieldDefs.put(assocName, fieldDef); assocFieldDefs.put(assocName, fieldDef);
} }
String prefixedAssocName = ASSOC_PREFIX + assocName;
if (fieldDef.isEndpointMany()) if (fieldDef.isEndpointMany())
{ {
List<String> targets = null; List<String> targets = null;
// add the value as a List (or add to the list if the form data // add the value as a List (or add to the list if the form data
// is already present) // is already present)
FieldData fieldData = form.getFormData().getData().get(prefixedAssocName); FieldData fieldData = form.getFormData().getData().get(dataKeyName);
if (fieldData == null) if (fieldData == null)
{ {
targets = new ArrayList<String>(4); targets = new ArrayList<String>(4);
form.addData(prefixedAssocName, targets); form.addData(dataKeyName, targets);
} }
else else
{ {
@@ -630,7 +647,7 @@ public class NodeHandler extends AbstractHandler
else else
{ {
// there should only be one value // there should only be one value
form.addData(prefixedAssocName, assocValue); form.addData(dataKeyName, assocValue);
} }
} }
} }
@@ -665,6 +682,7 @@ public class NodeHandler extends AbstractHandler
// get the name of the association // get the name of the association
QName assocTypeName = childAssoc.getTypeQName(); QName assocTypeName = childAssoc.getTypeQName();
String assocName = assocTypeName.toPrefixString(this.namespaceService); String assocName = assocTypeName.toPrefixString(this.namespaceService);
String dataKeyName = ASSOC_PREFIX + assocName.replace(":", DATA_KEY_SEPARATOR);
// setup the field definition for the association if it hasn't before // setup the field definition for the association if it hasn't before
AssociationFieldDefinition fieldDef = childAssocFieldDefs.get(assocName); AssociationFieldDefinition fieldDef = childAssocFieldDefs.get(assocName);
@@ -690,6 +708,7 @@ public class NodeHandler extends AbstractHandler
fieldDef.setProtectedField(assocDef.isProtected()); fieldDef.setProtectedField(assocDef.isProtected());
fieldDef.setEndpointMandatory(assocDef.isTargetMandatory()); fieldDef.setEndpointMandatory(assocDef.isTargetMandatory());
fieldDef.setEndpointMany(assocDef.isTargetMany()); fieldDef.setEndpointMany(assocDef.isTargetMany());
fieldDef.setDataKeyName(dataKeyName);
// add definition to Form and to internal cache // add definition to Form and to internal cache
form.addFieldDefinition(fieldDef); form.addFieldDefinition(fieldDef);
@@ -726,7 +745,7 @@ public class NodeHandler extends AbstractHandler
ChildAssociationRef nextChild = iter.next(); ChildAssociationRef nextChild = iter.next();
nodeRefs.add(nextChild.getChildRef().toString()); nodeRefs.add(nextChild.getChildRef().toString());
} }
form.addData(ASSOC_PREFIX + associationName, nodeRefs); form.addData(ASSOC_PREFIX + associationName.replace(":", DATA_KEY_SEPARATOR), nodeRefs);
} }
} }
@@ -742,6 +761,7 @@ public class NodeHandler extends AbstractHandler
List assocValues, Form form) List assocValues, Form form)
{ {
String assocName = assocDef.getName().toPrefixString(this.namespaceService); String assocName = assocDef.getName().toPrefixString(this.namespaceService);
String[] nameParts = QName.splitPrefixedQName(assocName);
AssociationFieldDefinition fieldDef = new AssociationFieldDefinition(assocName, AssociationFieldDefinition fieldDef = new AssociationFieldDefinition(assocName,
assocDef.getTargetClass().getName().toPrefixString( assocDef.getTargetClass().getName().toPrefixString(
this.namespaceService), Direction.TARGET); this.namespaceService), Direction.TARGET);
@@ -756,12 +776,14 @@ public class NodeHandler extends AbstractHandler
fieldDef.setEndpointMandatory(assocDef.isTargetMandatory()); fieldDef.setEndpointMandatory(assocDef.isTargetMandatory());
fieldDef.setEndpointMany(assocDef.isTargetMany()); fieldDef.setEndpointMany(assocDef.isTargetMany());
// define the data key name and set
String dataKeyName = ASSOC_PREFIX + nameParts[0] + DATA_KEY_SEPARATOR + nameParts[1];
fieldDef.setDataKeyName(dataKeyName);
// add definition to the form // add definition to the form
form.addFieldDefinition(fieldDef); form.addFieldDefinition(fieldDef);
// add the association value to the form // add the association value to the form
String prefixedAssocName = ASSOC_PREFIX + assocName;
// determine the type of association values data and extract accordingly // determine the type of association values data and extract accordingly
List<String> values = new ArrayList<String>(4); List<String> values = new ArrayList<String>(4);
for (Object value : assocValues) for (Object value : assocValues)
@@ -784,7 +806,7 @@ public class NodeHandler extends AbstractHandler
// TODO: Do we also return a well known named list of association names // TODO: Do we also return a well known named list of association names
// for each noderef so that clients do not have extra work to do // for each noderef so that clients do not have extra work to do
// to display the current values to the user // to display the current values to the user
form.addData(prefixedAssocName, values); form.addData(dataKeyName, values);
} }
/* /*

View File

@@ -25,14 +25,12 @@
package org.alfresco.repo.forms.script; package org.alfresco.repo.forms.script;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.forms.FieldDefinition; import org.alfresco.repo.forms.FieldDefinition;
import org.alfresco.repo.forms.FieldGroup;
import org.alfresco.repo.forms.Form; import org.alfresco.repo.forms.Form;
/** /**
@@ -68,15 +66,19 @@ public class ScriptForm implements Serializable
return form.getItem().getId(); return form.getItem().getId();
} }
public String getType() public String getItemType()
{ {
return form.getType(); return form.getItem().getType();
} }
//TODO Wrap this type in a script type? public String getItemUrl()
public Collection<FieldGroup> getFieldGroups()
{ {
return form.getFieldGroups(); return form.getItem().getUrl();
}
public String getSubmissionUrl()
{
return form.getSubmissionUrl();
} }
public FieldDefinition[] getFieldDefinitions() public FieldDefinition[] getFieldDefinitions()

View File

@@ -25,9 +25,10 @@ function testGetFormForContentNode()
test.assertEquals("node", form.itemKind); test.assertEquals("node", form.itemKind);
test.assertEquals(testDoc, form.itemId); test.assertEquals(testDoc, form.itemId);
test.assertEquals('cm:content', form.type); test.assertEquals('cm:content', form.itemType);
test.assertEquals('/api/node/' + testDoc.replace(":/", ""), form.itemUrl);
test.assertNull(form.fieldGroups, "form.fieldGroups should be null."); test.assertNull(form.submissionUrl, "form.submissionUrl should be null.");
var fieldDefs = form.fieldDefinitions; var fieldDefs = form.fieldDefinitions;
test.assertNotNull(fieldDefs, "field definitions should not be null."); test.assertNotNull(fieldDefs, "field definitions should not be null.");
@@ -112,14 +113,14 @@ function testGetFormForContentNode()
test.assertNotNull(fieldData, "fieldData should not be null."); test.assertNotNull(fieldData, "fieldData should not be null.");
test.assertNotNull(fieldData.length, "fieldData.length should not be null."); test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
test.assertEquals(testDocName, fieldData["prop:cm:name"].value); test.assertEquals(testDocName, fieldData[nameField.dataKeyName].value);
test.assertEquals("This is the title for the test document", fieldData["prop:cm:title"].value); test.assertEquals("This is the title for the test document", fieldData[titleField.dataKeyName].value);
test.assertEquals("This is the description for the test document", fieldData["prop:cm:description"].value); test.assertEquals("This is the description for the test document", fieldData[descField.dataKeyName].value);
test.assertEquals("fred@customer.com", fieldData["prop:cm:originator"].value); test.assertEquals("fred@customer.com", fieldData[originatorField.dataKeyName].value);
test.assertEquals("bill@example.com", fieldData["prop:cm:addressee"].value); test.assertEquals("bill@example.com", fieldData[addresseeField.dataKeyName].value);
test.assertEquals("The subject is...", fieldData["prop:cm:subjectline"].value); test.assertEquals("The subject is...", fieldData[subjectField.dataKeyName].value);
var addressees = fieldData["prop:cm:addressees"].value; var addressees = fieldData[addresseesField.dataKeyName].value;
test.assertNotNull(addressees); test.assertNotNull(addressees);
test.assertTrue(addressees.indexOf(",") != -1); test.assertTrue(addressees.indexOf(",") != -1);
var addresseesArr = addressees.split(","); var addresseesArr = addressees.split(",");
@@ -127,12 +128,12 @@ function testGetFormForContentNode()
test.assertEquals("harry@example.com", addresseesArr[0]); test.assertEquals("harry@example.com", addresseesArr[0]);
test.assertEquals("jane@example.com", addresseesArr[1]); test.assertEquals("jane@example.com", addresseesArr[1]);
var sentDate = fieldData["prop:cm:sentdate"].getValue(); var sentDate = fieldData[sentDateField.dataKeyName].getValue();
test.assertTrue((typeof sentDate === "object"), "Expecting sentData to be an object"); test.assertTrue((typeof sentDate === "object"), "Expecting sentData to be an object");
var month = sentDate.getMonth(); var month = sentDate.getMonth();
test.assertTrue((month >= 0 && month < 12), "Expecting valid month"); test.assertTrue((month >= 0 && month < 12), "Expecting valid month");
var targets = fieldData["assoc:cm:references"].value; var targets = fieldData[referencesField.dataKeyName].value;
test.assertNotNull(targets, "targets should not be null."); test.assertNotNull(targets, "targets should not be null.");
test.assertEquals(testAssociatedDoc, targets); test.assertEquals(testAssociatedDoc, targets);
@@ -146,9 +147,10 @@ function testGetFormForFolderNode()
test.assertEquals("node", form.itemKind); test.assertEquals("node", form.itemKind);
test.assertEquals(folder, form.itemId); test.assertEquals(folder, form.itemId);
test.assertEquals('cm:folder', form.type); test.assertEquals('cm:folder', form.itemType);
test.assertEquals('/api/node/' + folder.replace(":/", ""), form.itemUrl);
test.assertNull(form.fieldGroups, "form.fieldGroups should be null."); test.assertNull(form.submissionUrl, "form.submissionUrl should be null.");
var fieldDefs = form.fieldDefinitions; var fieldDefs = form.fieldDefinitions;
test.assertNotNull(fieldDefs, "field definitions should not be null."); test.assertNotNull(fieldDefs, "field definitions should not be null.");
@@ -192,8 +194,8 @@ function testGetFormForFolderNode()
test.assertNotNull(fieldData, "fieldData should not be null."); test.assertNotNull(fieldData, "fieldData should not be null.");
test.assertNotNull(fieldData.length, "fieldData.length should not be null."); test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
test.assertEquals(folderName, fieldData["prop:cm:name"].value); test.assertEquals(folderName, fieldData[nameField.dataKeyName].value);
var children = fieldData["assoc:cm:contains"].value; var children = fieldData[containsField.dataKeyName].value;
test.assertNotNull(children, "children should not be null."); test.assertNotNull(children, "children should not be null.");
var childrenArr = children.split(","); var childrenArr = children.split(",");
test.assertTrue(childrenArr.length == 3, "Expecting there to be 3 children"); test.assertTrue(childrenArr.length == 3, "Expecting there to be 3 children");
@@ -253,8 +255,8 @@ function testGetFormWithSelectedFields()
test.assertNotNull(fieldData, "fieldData should not be null."); test.assertNotNull(fieldData, "fieldData should not be null.");
test.assertNotNull(fieldData.length, "fieldData.length should not be null."); test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
test.assertEquals(testDocName, fieldData["prop:cm:name"].value); test.assertEquals(testDocName, fieldData[nameField.dataKeyName].value);
test.assertEquals("This is the title for the test document", fieldData["prop:cm:title"].value); test.assertEquals("This is the title for the test document", fieldData[titleField.dataKeyName].value);
} }
function testGetFormWithForcedFields() function testGetFormWithForcedFields()
@@ -319,9 +321,9 @@ function testGetFormWithForcedFields()
test.assertNotNull(fieldData, "fieldData should not be null."); test.assertNotNull(fieldData, "fieldData should not be null.");
test.assertNotNull(fieldData.length, "fieldData.length should not be null."); test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
test.assertEquals(testDocName, fieldData["prop:cm:name"].value); test.assertEquals(testDocName, fieldData[nameField.dataKeyName].value);
test.assertEquals("This is the title for the test document", fieldData["prop:cm:title"].value); test.assertEquals("This is the title for the test document", fieldData[titleField.dataKeyName].value);
test.assertNull(fieldData["prop:cm:author"], "Expecting cm:author to be null"); test.assertNull(fieldData[authorField.dataKeyName], "Expecting cm:author to be null");
} }
// Execute tests // Execute tests