mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged DEV/FORMS-REFACTOR branch to HEAD
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14000 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -71,7 +71,7 @@
|
||||
<property name="handlerRegistry" ref="nodeHandlerRegistry" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="matchPattern">
|
||||
<value>workspace://[\w\-\/]*</value>
|
||||
<value>node</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
@@ -99,7 +99,6 @@
|
||||
<property name="extensionName">
|
||||
<value>formService</value>
|
||||
</property>
|
||||
<property name="serviceRegistry" ref="ServiceRegistry"/>
|
||||
<property name="formService" ref="FormService"/>
|
||||
</bean>
|
||||
|
||||
|
@@ -35,7 +35,7 @@ import java.util.List;
|
||||
*/
|
||||
public class Form
|
||||
{
|
||||
protected String item;
|
||||
protected Item item;
|
||||
protected String type;
|
||||
protected List<FieldDefinition> fieldDefinitions;
|
||||
protected Collection<FieldGroup> fieldGroups;
|
||||
@@ -44,20 +44,19 @@ public class Form
|
||||
/**
|
||||
* Constructs a Form
|
||||
*
|
||||
* @param item An identifier for the item the form is for
|
||||
* @param item The item the form is for
|
||||
*/
|
||||
public Form(String item)
|
||||
public Form(Item item)
|
||||
{
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an identifier for the item the form is for, in the case of a node
|
||||
* it will be a NodeRef, for a task, a task id etc.
|
||||
* Returns the item the form is for
|
||||
*
|
||||
* @return The item
|
||||
*/
|
||||
public String getItem()
|
||||
public Item getItem()
|
||||
{
|
||||
return this.item;
|
||||
}
|
||||
@@ -167,7 +166,8 @@ public class Form
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data this form should display
|
||||
* Sets the data this form should display. This will overwrite
|
||||
* any existing form data being held
|
||||
*
|
||||
* @param data FormData instance containing the data
|
||||
*/
|
||||
@@ -176,6 +176,22 @@ public class Form
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds some data to be displayed by the form
|
||||
*
|
||||
* @param fieldName Name of the field the data is for
|
||||
* @param fieldData The value
|
||||
*/
|
||||
public void addData(String fieldName, Object fieldData)
|
||||
{
|
||||
if (this.data == null)
|
||||
{
|
||||
this.data = new FormData();
|
||||
}
|
||||
|
||||
this.data.addData(fieldName, fieldData);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
|
@@ -35,13 +35,13 @@ public class FormException extends AlfrescoRuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 688834574410335422L;
|
||||
|
||||
public FormException(String msg)
|
||||
public FormException(String msgId)
|
||||
{
|
||||
super(msg);
|
||||
super(msgId);
|
||||
}
|
||||
|
||||
public FormException(String msg, Throwable cause)
|
||||
public FormException(String msgId, Throwable cause)
|
||||
{
|
||||
super(msg, cause);
|
||||
super(msgId, cause);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
|
||||
/**
|
||||
* Exception used by the Form service when a form can not be found for the given item
|
||||
*
|
||||
* @author Gavin Cornwell
|
||||
*/
|
||||
public class FormNotFoundException extends AlfrescoRuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 688834574410335422L;
|
||||
|
||||
public FormNotFoundException(Item item)
|
||||
{
|
||||
// TODO: replace strings with msg ids
|
||||
super("A form could not be found for item: " + item);
|
||||
}
|
||||
|
||||
public FormNotFoundException(Item item, Throwable cause)
|
||||
{
|
||||
// TODO: replace strings with msg ids
|
||||
super("A form could not be found for item: " + item, cause);
|
||||
}
|
||||
}
|
@@ -24,6 +24,8 @@
|
||||
*/
|
||||
package org.alfresco.repo.forms;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Form service API.
|
||||
@@ -35,18 +37,47 @@ package org.alfresco.repo.forms;
|
||||
public interface FormService
|
||||
{
|
||||
/**
|
||||
* Returns a form representation of the given item
|
||||
* Returns a form representation of the given item,
|
||||
* all known fields for the item are included.
|
||||
*
|
||||
* @param item The item to get a form for
|
||||
* @return The Form representation
|
||||
*/
|
||||
public Form getForm(String item);
|
||||
public Form getForm(Item item);
|
||||
|
||||
/**
|
||||
* Persists the given form representation for the given item
|
||||
* Returns a form representation of the given item consisting
|
||||
* only of the given fields.
|
||||
*
|
||||
* @param item The item to get a form for
|
||||
* @param fields Restricted list of fields to include, null
|
||||
* indicates all possible fields for the item
|
||||
* should be included
|
||||
* @return The Form representation
|
||||
*/
|
||||
public Form getForm(Item item, List<String> fields);
|
||||
|
||||
/**
|
||||
* Returns a form representation of the given item consisting
|
||||
* only of the given fields.
|
||||
*
|
||||
* @param item The item to get a form for
|
||||
* @param fields Restricted list of fields to include, null
|
||||
* indicates all possible fields for the item
|
||||
* should be included
|
||||
* @param forcedFields List of field names from 'fields' list
|
||||
* that should be forcibly included, it is
|
||||
* up to the form processor implementation
|
||||
* to determine how to enforce this
|
||||
* @return The Form representation
|
||||
*/
|
||||
public Form getForm(Item item, List<String> fields, List<String> forcedFields);
|
||||
|
||||
/**
|
||||
* Persists the given form representation for the given item.
|
||||
*
|
||||
* @param item The item to persist the form for
|
||||
* @param data An object representing the form data to persist
|
||||
*/
|
||||
public void saveForm(String item, FormData data);
|
||||
public void saveForm(Item item, FormData data);
|
||||
}
|
||||
|
@@ -24,9 +24,10 @@
|
||||
*/
|
||||
package org.alfresco.repo.forms;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.forms.processor.FormProcessor;
|
||||
import org.alfresco.repo.forms.processor.FormProcessorRegistry;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -53,10 +54,26 @@ public class FormServiceImpl implements FormService
|
||||
this.processorRegistry = registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.forms.FormService#getForm(java.lang.String)
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.FormService#getForm(org.alfresco.repo.forms.Item)
|
||||
*/
|
||||
public Form getForm(String item)
|
||||
public Form getForm(Item item)
|
||||
{
|
||||
return getForm(item, null, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.FormService#getForm(org.alfresco.repo.forms.Item, java.util.List)
|
||||
*/
|
||||
public Form getForm(Item item, List<String> fields)
|
||||
{
|
||||
return getForm(item, fields, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.FormService#getForm(org.alfresco.repo.forms.Item, java.util.List, java.util.List)
|
||||
*/
|
||||
public Form getForm(Item item, List<String> fields, List<String> forcedFields)
|
||||
{
|
||||
if (this.processorRegistry == null)
|
||||
{
|
||||
@@ -74,26 +91,14 @@ public class FormServiceImpl implements FormService
|
||||
}
|
||||
else
|
||||
{
|
||||
Form result = null;
|
||||
try
|
||||
{
|
||||
result = processor.generate(item);
|
||||
}
|
||||
catch (InvalidNodeRefException inrx)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug(inrx);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return processor.generate(item, fields, forcedFields);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.FormService#saveForm(java.lang.String, org.alfresco.repo.forms.FormData)
|
||||
* @see org.alfresco.repo.forms.FormService#saveForm(org.alfresco.repo.forms.Item, org.alfresco.repo.forms.FormData)
|
||||
*/
|
||||
public void saveForm(String item, FormData data)
|
||||
public void saveForm(Item item, FormData data)
|
||||
{
|
||||
if (this.processorRegistry == null)
|
||||
{
|
||||
|
@@ -69,7 +69,10 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
|
||||
private NodeRef document;
|
||||
private NodeRef associatedDoc;
|
||||
private NodeRef childDoc;
|
||||
private NodeRef folder;
|
||||
private String documentName;
|
||||
private String folderName;
|
||||
|
||||
private static String VALUE_TITLE = "This is the title for the test document";
|
||||
private static String VALUE_DESCRIPTION = "This is the description for the test document";
|
||||
@@ -88,6 +91,9 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
private static String LABEL_NAME = "Name";
|
||||
private static String LABEL_TITLE = "Title";
|
||||
private static String LABEL_DESCRIPTION = "Description";
|
||||
private static String LABEL_AUTHOR = "Author";
|
||||
private static String LABEL_MODIFIED = "Modified Date";
|
||||
private static String LABEL_MODIFIER = "Modifier";
|
||||
private static String LABEL_MIMETYPE = "Mimetype";
|
||||
private static String LABEL_ENCODING = "Encoding";
|
||||
private static String LABEL_SIZE = "Size";
|
||||
@@ -97,9 +103,10 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
private static String LABEL_SUBJECT = "Subject";
|
||||
private static String LABEL_SENT_DATE = "Sent Date";
|
||||
private static String LABEL_REFERENCES = "References";
|
||||
private static String LABEL_CONTAINS = "Contains";
|
||||
|
||||
private static final String USER_ONE = "UserOne_SiteServiceImplTest";
|
||||
|
||||
private static final String NODE_FORM_ITEM_KIND = "node";
|
||||
|
||||
/**
|
||||
* Called during the transaction setup
|
||||
@@ -129,8 +136,9 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"));
|
||||
|
||||
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>(1);
|
||||
folderProps.put(ContentModel.PROP_NAME, "testFolder" + guid);
|
||||
NodeRef folder = this.nodeService.createNode(
|
||||
this.folderName = "testFolder" + guid;
|
||||
folderProps.put(ContentModel.PROP_NAME, this.folderName);
|
||||
this.folder = this.nodeService.createNode(
|
||||
rootNode,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testFolder" + guid),
|
||||
@@ -142,7 +150,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
this.documentName = "testDocument" + guid + ".txt";
|
||||
docProps.put(ContentModel.PROP_NAME, this.documentName);
|
||||
this.document = this.nodeService.createNode(
|
||||
folder,
|
||||
this.folder,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testDocument" + guid + ".txt"),
|
||||
ContentModel.TYPE_CONTENT,
|
||||
@@ -151,12 +159,21 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
// create a node to use as target of association
|
||||
docProps.put(ContentModel.PROP_NAME, "associatedDocument" + guid + ".txt");
|
||||
this.associatedDoc = this.nodeService.createNode(
|
||||
folder,
|
||||
this.folder,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "associatedDocument" + guid + ".txt"),
|
||||
ContentModel.TYPE_CONTENT,
|
||||
docProps).getChildRef();
|
||||
|
||||
// create a node to use as a 2nd child node of the folder
|
||||
docProps.put(ContentModel.PROP_NAME, "childDocument" + guid + ".txt");
|
||||
this.childDoc = this.nodeService.createNode(
|
||||
this.folder,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "childDocument" + guid + ".txt"),
|
||||
ContentModel.TYPE_CONTENT,
|
||||
docProps).getChildRef();
|
||||
|
||||
// add some content to the nodes
|
||||
ContentWriter writer = this.contentService.getWriter(this.document, ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype(VALUE_MIMETYPE);
|
||||
@@ -190,9 +207,6 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
aspectProps.clear();
|
||||
this.nodeService.addAspect(document, ContentModel.ASPECT_REFERENCING, aspectProps);
|
||||
this.nodeService.createAssociation(this.document, this.associatedDoc, ContentModel.ASSOC_REFERENCES);
|
||||
|
||||
// setComplete();
|
||||
// endTransaction();
|
||||
}
|
||||
|
||||
private void createUser(String userName)
|
||||
@@ -213,15 +227,16 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetForm() throws Exception
|
||||
public void testGetAllDocForm() throws Exception
|
||||
{
|
||||
Form form = this.formService.getForm(this.document.toString());
|
||||
Form form = this.formService.getForm(new Item(NODE_FORM_ITEM_KIND, this.document.toString()));
|
||||
|
||||
// check a form got returned
|
||||
assertNotNull("Expecting form to be present", form);
|
||||
|
||||
// check item identifier matches
|
||||
assertEquals(this.document.toString(), form.getItem());
|
||||
assertEquals(NODE_FORM_ITEM_KIND, form.getItem().getKind());
|
||||
assertEquals(this.document.toString(), form.getItem().getId());
|
||||
|
||||
// check the type is correct
|
||||
assertEquals(ContentModel.TYPE_CONTENT.toPrefixString(this.namespaceService),
|
||||
@@ -233,7 +248,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
// check the field definitions
|
||||
Collection<FieldDefinition> fieldDefs = form.getFieldDefinitions();
|
||||
assertNotNull("Expecting to find fields", fieldDefs);
|
||||
assertEquals("Expecting to find 23 fields", 23, fieldDefs.size());
|
||||
assertEquals("Expecting to find 22 fields", 22, fieldDefs.size());
|
||||
|
||||
// create a Map of the field definitions
|
||||
// NOTE: we can safely do this as we know there are no duplicate field names and we're not
|
||||
@@ -364,6 +379,339 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
assertEquals(this.associatedDoc.toString(), targets.get(0));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetSelectedFieldsDocForm() throws Exception
|
||||
{
|
||||
// define a list of fields to retrieve from the node
|
||||
List<String> fields = new ArrayList<String>(8);
|
||||
fields.add("cm:name");
|
||||
fields.add("cm:title");
|
||||
fields.add("mimetype");
|
||||
fields.add("cm:modified");
|
||||
fields.add("cm:modifier");
|
||||
fields.add("cm:subjectline");
|
||||
fields.add("cm:sentdate");
|
||||
fields.add("cm:references");
|
||||
|
||||
Form form = this.formService.getForm(new Item(NODE_FORM_ITEM_KIND, this.document.toString()), fields);
|
||||
|
||||
// check a form got returned
|
||||
assertNotNull("Expecting form to be present", form);
|
||||
|
||||
// check item identifier matches
|
||||
assertEquals(NODE_FORM_ITEM_KIND, form.getItem().getKind());
|
||||
assertEquals(this.document.toString(), form.getItem().getId());
|
||||
|
||||
// check the type is correct
|
||||
assertEquals(ContentModel.TYPE_CONTENT.toPrefixString(this.namespaceService),
|
||||
form.getType());
|
||||
|
||||
// check there is no group info
|
||||
assertNull("Expecting the form groups to be null!", form.getFieldGroups());
|
||||
|
||||
// check the field definitions
|
||||
Collection<FieldDefinition> fieldDefs = form.getFieldDefinitions();
|
||||
assertNotNull("Expecting to find fields", fieldDefs);
|
||||
assertEquals("Expecting to find " + fields.size() + " fields", fields.size(), fieldDefs.size());
|
||||
|
||||
// create a Map of the field definitions
|
||||
// NOTE: we can safely do this as we know there are no duplicate field names and we're not
|
||||
// concerned with ordering!
|
||||
Map<String, FieldDefinition> fieldDefMap = new HashMap<String, FieldDefinition>(fieldDefs.size());
|
||||
for (FieldDefinition fieldDef : fieldDefs)
|
||||
{
|
||||
fieldDefMap.put(fieldDef.getName(), fieldDef);
|
||||
}
|
||||
|
||||
// find the fields
|
||||
PropertyFieldDefinition nameField = (PropertyFieldDefinition)fieldDefMap.get("cm:name");
|
||||
PropertyFieldDefinition titleField = (PropertyFieldDefinition)fieldDefMap.get("cm:title");
|
||||
PropertyFieldDefinition mimetypeField = (PropertyFieldDefinition)fieldDefMap.get("mimetype");
|
||||
PropertyFieldDefinition modifiedField = (PropertyFieldDefinition)fieldDefMap.get("cm:modified");
|
||||
PropertyFieldDefinition modifierField = (PropertyFieldDefinition)fieldDefMap.get("cm:modifier");
|
||||
PropertyFieldDefinition subjectField = (PropertyFieldDefinition)fieldDefMap.get("cm:subjectline");
|
||||
PropertyFieldDefinition sentDateField = (PropertyFieldDefinition)fieldDefMap.get("cm:sentdate");
|
||||
AssociationFieldDefinition referencesField = (AssociationFieldDefinition)fieldDefMap.get("cm:references");
|
||||
|
||||
// check fields are present
|
||||
assertNotNull("Expecting to find the cm:name field", nameField);
|
||||
assertNotNull("Expecting to find the cm:title field", titleField);
|
||||
assertNotNull("Expecting to find the mimetype field", mimetypeField);
|
||||
assertNotNull("Expecting to find the cm:modified field", modifiedField);
|
||||
assertNotNull("Expecting to find the cm:modifier field", modifierField);
|
||||
assertNotNull("Expecting to find the cm:subjectline field", subjectField);
|
||||
assertNotNull("Expecting to find the cm:sentdate field", sentDateField);
|
||||
assertNotNull("Expecting to find the cm:references field", referencesField);
|
||||
|
||||
// check the labels of all the fields
|
||||
assertEquals("Expecting cm:name label to be " + LABEL_NAME,
|
||||
LABEL_NAME, nameField.getLabel());
|
||||
assertEquals("Expecting cm:title label to be " + LABEL_TITLE,
|
||||
LABEL_TITLE, titleField.getLabel());
|
||||
assertEquals("Expecting mimetype label to be " + LABEL_MIMETYPE,
|
||||
LABEL_MIMETYPE, mimetypeField.getLabel());
|
||||
assertEquals("Expecting cm:modified label to be " + LABEL_MODIFIED,
|
||||
LABEL_MODIFIED, modifiedField.getLabel());
|
||||
assertEquals("Expecting cm:modifier label to be " + LABEL_MODIFIER,
|
||||
LABEL_MODIFIER, modifierField.getLabel());
|
||||
assertEquals("Expecting cm:subjectline label to be " + LABEL_SUBJECT,
|
||||
LABEL_SUBJECT, subjectField.getLabel());
|
||||
assertEquals("Expecting cm:sentdate label to be " + LABEL_SENT_DATE,
|
||||
LABEL_SENT_DATE, sentDateField.getLabel());
|
||||
assertEquals("Expecting cm:references label to be " + LABEL_REFERENCES,
|
||||
LABEL_REFERENCES, referencesField.getLabel());
|
||||
|
||||
// check the details of the modified field
|
||||
assertEquals("Expecting cm:modified type to be d:datetime", "d:datetime", modifiedField.getDataType());
|
||||
assertTrue("Expecting cm:modified to be mandatory", modifiedField.isMandatory());
|
||||
assertFalse("Expecting cm:modified to be single valued", modifiedField.isRepeating());
|
||||
|
||||
// check the details of the association field
|
||||
assertEquals("Expecting cm:references endpoint type to be cm:content", "cm:content",
|
||||
referencesField.getEndpointType());
|
||||
assertEquals("Expecting cm:references endpoint direction to be TARGET",
|
||||
Direction.TARGET.toString(),
|
||||
referencesField.getEndpointDirection().toString());
|
||||
assertFalse("Expecting cm:references endpoint to be optional",
|
||||
referencesField.isEndpointMandatory());
|
||||
assertTrue("Expecting cm:references endpoint to be 1 to many",
|
||||
referencesField.isEndpointMany());
|
||||
|
||||
// check the form data
|
||||
FormData data = form.getFormData();
|
||||
assertNotNull("Expecting form data", data);
|
||||
Map<String, FormData.FieldData> fieldData = data.getData();
|
||||
assertNotNull("Expecting field data", fieldData);
|
||||
assertEquals(this.documentName, fieldData.get("prop:cm:name").getValue());
|
||||
assertEquals(VALUE_TITLE, fieldData.get("prop:cm:title").getValue());
|
||||
assertEquals(VALUE_MIMETYPE, fieldData.get("prop:mimetype").getValue());
|
||||
assertEquals(VALUE_SUBJECT, fieldData.get("prop:cm:subjectline").getValue());
|
||||
assertEquals(USER_ONE, fieldData.get("prop:cm:modifier").getValue());
|
||||
|
||||
Date modifiedDate = (Date)fieldData.get("prop:cm:modified").getValue();
|
||||
assertNotNull("Expecting to find modified date", modifiedDate);
|
||||
assertTrue("Expecting modified field to return a Date", (modifiedDate instanceof Date));
|
||||
|
||||
Calendar calTestValue = Calendar.getInstance();
|
||||
calTestValue.setTime(VALUE_SENT_DATE);
|
||||
Calendar calServiceValue = Calendar.getInstance();
|
||||
calServiceValue.setTime((Date)fieldData.get("prop:cm:sentdate").getValue());
|
||||
assertEquals(calTestValue.getTimeInMillis(), calServiceValue.getTimeInMillis());
|
||||
|
||||
List<String> targets = (List<String>)fieldData.get("assoc:cm:references").getValue();
|
||||
assertEquals("Expecting 1 target", 1, targets.size());
|
||||
assertEquals(this.associatedDoc.toString(), targets.get(0));
|
||||
}
|
||||
|
||||
public void testMissingFieldsDocForm() throws Exception
|
||||
{
|
||||
// define a list of fields to retrieve from the node
|
||||
List<String> fields = new ArrayList<String>(8);
|
||||
fields.add("cm:name");
|
||||
fields.add("cm:title");
|
||||
|
||||
// add fields that will not be present
|
||||
fields.add("cm:author");
|
||||
fields.add("wrong-name");
|
||||
|
||||
Form form = this.formService.getForm(new Item(NODE_FORM_ITEM_KIND, this.document.toString()), fields);
|
||||
|
||||
// check a form got returned
|
||||
assertNotNull("Expecting form to be present", form);
|
||||
|
||||
// check the field definitions
|
||||
Collection<FieldDefinition> fieldDefs = form.getFieldDefinitions();
|
||||
assertNotNull("Expecting to find fields", fieldDefs);
|
||||
assertEquals("Expecting to find " + (fields.size()-2) + " fields", fields.size()-2, fieldDefs.size());
|
||||
|
||||
// create a Map of the field definitions
|
||||
// NOTE: we can safely do this as we know there are no duplicate field names and we're not
|
||||
// concerned with ordering!
|
||||
Map<String, FieldDefinition> fieldDefMap = new HashMap<String, FieldDefinition>(fieldDefs.size());
|
||||
for (FieldDefinition fieldDef : fieldDefs)
|
||||
{
|
||||
fieldDefMap.put(fieldDef.getName(), fieldDef);
|
||||
}
|
||||
|
||||
// find the fields
|
||||
PropertyFieldDefinition nameField = (PropertyFieldDefinition)fieldDefMap.get("cm:name");
|
||||
PropertyFieldDefinition titleField = (PropertyFieldDefinition)fieldDefMap.get("cm:title");
|
||||
PropertyFieldDefinition authorField = (PropertyFieldDefinition)fieldDefMap.get("cm:author");
|
||||
|
||||
// check fields are present
|
||||
assertNotNull("Expecting to find the cm:name field", nameField);
|
||||
assertNotNull("Expecting to find the cm:title field", titleField);
|
||||
assertNull("Expecting cm:author field to be missing", authorField);
|
||||
|
||||
// check the labels of all the fields
|
||||
assertEquals("Expecting cm:name label to be " + LABEL_NAME,
|
||||
LABEL_NAME, nameField.getLabel());
|
||||
assertEquals("Expecting cm:title label to be " + LABEL_TITLE,
|
||||
LABEL_TITLE, titleField.getLabel());
|
||||
|
||||
// check the form data
|
||||
FormData data = form.getFormData();
|
||||
assertNotNull("Expecting form data", data);
|
||||
Map<String, FormData.FieldData> fieldData = data.getData();
|
||||
assertNotNull("Expecting field data", fieldData);
|
||||
assertEquals(this.documentName, fieldData.get("prop:cm:name").getValue());
|
||||
assertEquals(VALUE_TITLE, fieldData.get("prop:cm:title").getValue());
|
||||
}
|
||||
|
||||
public void testForcedFieldsDocForm() throws Exception
|
||||
{
|
||||
// define a list of fields to retrieve from the node
|
||||
List<String> fields = new ArrayList<String>(4);
|
||||
fields.add("cm:name");
|
||||
fields.add("cm:title");
|
||||
|
||||
// add fields that will not be present
|
||||
fields.add("cm:author");
|
||||
fields.add("cm:never");
|
||||
fields.add("wrong-name");
|
||||
|
||||
// try and force the missing fields to appear
|
||||
List<String> forcedFields = new ArrayList<String>(2);
|
||||
forcedFields.add("cm:author");
|
||||
forcedFields.add("cm:never");
|
||||
forcedFields.add("wrong-name");
|
||||
|
||||
Form form = this.formService.getForm(new Item(NODE_FORM_ITEM_KIND, this.document.toString()), fields, forcedFields);
|
||||
|
||||
// check a form got returned
|
||||
assertNotNull("Expecting form to be present", form);
|
||||
|
||||
// check the field definitions
|
||||
Collection<FieldDefinition> fieldDefs = form.getFieldDefinitions();
|
||||
assertNotNull("Expecting to find fields", fieldDefs);
|
||||
assertEquals("Expecting to find " + (fields.size()-2) + " fields", fields.size()-2, fieldDefs.size());
|
||||
|
||||
// create a Map of the field definitions
|
||||
// NOTE: we can safely do this as we know there are no duplicate field names and we're not
|
||||
// concerned with ordering!
|
||||
Map<String, FieldDefinition> fieldDefMap = new HashMap<String, FieldDefinition>(fieldDefs.size());
|
||||
for (FieldDefinition fieldDef : fieldDefs)
|
||||
{
|
||||
fieldDefMap.put(fieldDef.getName(), fieldDef);
|
||||
}
|
||||
|
||||
// find the fields
|
||||
PropertyFieldDefinition nameField = (PropertyFieldDefinition)fieldDefMap.get("cm:name");
|
||||
PropertyFieldDefinition titleField = (PropertyFieldDefinition)fieldDefMap.get("cm:title");
|
||||
PropertyFieldDefinition authorField = (PropertyFieldDefinition)fieldDefMap.get("cm:author");
|
||||
PropertyFieldDefinition neverField = (PropertyFieldDefinition)fieldDefMap.get("cm:never");
|
||||
PropertyFieldDefinition wrongField = (PropertyFieldDefinition)fieldDefMap.get("wrong-name");
|
||||
|
||||
// check fields are present
|
||||
assertNotNull("Expecting to find the cm:name field", nameField);
|
||||
assertNotNull("Expecting to find the cm:title field", titleField);
|
||||
assertNotNull("Expecting to find the cm:author field", authorField);
|
||||
assertNull("Expecting cm:never field to be missing", neverField);
|
||||
assertNull("Expecting wrong-name field to be missing", wrongField);
|
||||
|
||||
// check the labels of all the fields
|
||||
assertEquals("Expecting cm:name label to be " + LABEL_NAME,
|
||||
LABEL_NAME, nameField.getLabel());
|
||||
assertEquals("Expecting cm:title label to be " + LABEL_TITLE,
|
||||
LABEL_TITLE, titleField.getLabel());
|
||||
assertEquals("Expecting cm:author label to be " + LABEL_AUTHOR,
|
||||
LABEL_AUTHOR, authorField.getLabel());
|
||||
|
||||
// check the form data
|
||||
FormData data = form.getFormData();
|
||||
assertNotNull("Expecting form data", data);
|
||||
Map<String, FormData.FieldData> fieldData = data.getData();
|
||||
assertNotNull("Expecting field data", fieldData);
|
||||
assertEquals(this.documentName, fieldData.get("prop:cm:name").getValue());
|
||||
assertEquals(VALUE_TITLE, fieldData.get("prop:cm:title").getValue());
|
||||
assertNull("Didn't expect to find a value for cm:author", fieldData.get("prop:cm:author"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetAllFolderForm() throws Exception
|
||||
{
|
||||
Form form = this.formService.getForm(new Item(NODE_FORM_ITEM_KIND, this.folder.toString()));
|
||||
|
||||
// check a form got returned
|
||||
assertNotNull("Expecting form to be present", form);
|
||||
|
||||
// check item identifier matches
|
||||
assertEquals(NODE_FORM_ITEM_KIND, form.getItem().getKind());
|
||||
assertEquals(this.folder.toString(), form.getItem().getId());
|
||||
|
||||
// check the type is correct
|
||||
assertEquals(ContentModel.TYPE_FOLDER.toPrefixString(this.namespaceService),
|
||||
form.getType());
|
||||
|
||||
// check there is no group info
|
||||
assertNull("Expecting the form groups to be null!", form.getFieldGroups());
|
||||
|
||||
// check the field definitions
|
||||
Collection<FieldDefinition> fieldDefs = form.getFieldDefinitions();
|
||||
assertNotNull("Expecting to find fields", fieldDefs);
|
||||
assertEquals("Expecting to find 11 fields", 11, fieldDefs.size());
|
||||
|
||||
// create a Map of the field definitions
|
||||
// NOTE: we can safely do this as we know there are no duplicate field names and we're not
|
||||
// concerned with ordering!
|
||||
Map<String, FieldDefinition> fieldDefMap = new HashMap<String, FieldDefinition>(fieldDefs.size());
|
||||
for (FieldDefinition fieldDef : fieldDefs)
|
||||
{
|
||||
fieldDefMap.put(fieldDef.getName(), fieldDef);
|
||||
}
|
||||
|
||||
// find the fields
|
||||
PropertyFieldDefinition nameField = (PropertyFieldDefinition)fieldDefMap.get("cm:name");
|
||||
AssociationFieldDefinition containsField = (AssociationFieldDefinition)fieldDefMap.get("cm:contains");
|
||||
|
||||
// check fields are present
|
||||
assertNotNull("Expecting to find the cm:name field", nameField);
|
||||
assertNotNull("Expecting to find the cm:contains field", containsField);
|
||||
|
||||
// check the labels of all the fields
|
||||
assertEquals("Expecting cm:name label to be " + LABEL_NAME,
|
||||
LABEL_NAME, nameField.getLabel());
|
||||
assertEquals("Expecting cm:contains label to be " + LABEL_CONTAINS,
|
||||
LABEL_CONTAINS, containsField.getLabel());
|
||||
|
||||
// check details of name field
|
||||
assertEquals("Expecting cm:name type to be d:text", "d:text", nameField.getDataType());
|
||||
assertTrue("Expecting cm:name to be mandatory", nameField.isMandatory());
|
||||
assertFalse("Expecting cm:name to be single valued", nameField.isRepeating());
|
||||
|
||||
// check the details of the association field
|
||||
assertEquals("Expecting cm:contains endpoint type to be sys:base", "sys:base",
|
||||
containsField.getEndpointType());
|
||||
assertEquals("Expecting cm:contains endpoint direction to be TARGET",
|
||||
Direction.TARGET.toString(),
|
||||
containsField.getEndpointDirection().toString());
|
||||
assertFalse("Expecting cm:contains endpoint to be optional",
|
||||
containsField.isEndpointMandatory());
|
||||
assertTrue("Expecting cm:contains endpoint to be 1 to many",
|
||||
containsField.isEndpointMany());
|
||||
|
||||
// check the form data
|
||||
FormData data = form.getFormData();
|
||||
assertNotNull("Expecting form data", data);
|
||||
Map<String, FormData.FieldData> fieldData = data.getData();
|
||||
assertNotNull("Expecting field data", fieldData);
|
||||
assertEquals(this.folderName, fieldData.get("prop:cm:name").getValue());
|
||||
|
||||
List<String> children = (List<String>)fieldData.get("assoc:cm:contains").getValue();
|
||||
assertEquals("Expecting 3 children", 3, children.size());
|
||||
assertEquals(this.document.toString(), children.get(0));
|
||||
assertEquals(this.associatedDoc.toString(), children.get(1));
|
||||
assertEquals(this.childDoc.toString(), children.get(2));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetSelectedFieldsFolderForm() throws Exception
|
||||
{
|
||||
// attempt to get a form with fields that are not appropriate
|
||||
// for a folder type i.e. mimetype and encoding
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSaveForm() throws Exception
|
||||
{
|
||||
@@ -398,7 +746,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
data.addData("cm:wrong", "This should not be persisted");
|
||||
|
||||
// persist the data
|
||||
this.formService.saveForm(this.document.toString(), data);
|
||||
this.formService.saveForm(new Item(NODE_FORM_ITEM_KIND, this.document.toString()), data);
|
||||
|
||||
// retrieve the data directly from the node service to ensure its been changed
|
||||
Map<QName, Serializable> updatedProps = this.nodeService.getProperties(this.document);
|
||||
@@ -429,29 +777,13 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
}
|
||||
}
|
||||
|
||||
// public void testApplyAspectProgrammatically() throws Exception
|
||||
// {
|
||||
// NodeRef nrSrc = new NodeRef("workspace://SpacesStore/320c74ad-dc79-4812-adf1-8160c37fdecb");
|
||||
// NodeRef nrDest = new NodeRef("workspace://SpacesStore/5ac5ccac-3409-4f4a-9338-a39ee1acd2cb");
|
||||
//
|
||||
// Map<QName, Serializable> aspectProps = new HashMap<QName, Serializable>(2);
|
||||
// // add referencing aspect (has association)
|
||||
// this.nodeService.addAspect(nrSrc, ContentModel.ASPECT_REFERENCING, aspectProps);
|
||||
// this.nodeService.createAssociation(nrSrc, nrDest, ContentModel.ASSOC_REFERENCES);
|
||||
//
|
||||
// setComplete();
|
||||
// endTransaction();
|
||||
//
|
||||
// System.out.println("did it work?");
|
||||
// }
|
||||
//
|
||||
public void testNoForm() throws Exception
|
||||
{
|
||||
// test that a form can not be retrieved for a non-existent item
|
||||
try
|
||||
{
|
||||
this.formService.getForm("Invalid Item");
|
||||
fail("Expecting getForm for 'Invalid Item' to fail");
|
||||
this.formService.getForm(new Item("Invalid Kind", "Invalid Id"));
|
||||
fail("Expecting getForm for 'Invalid Kind/Item' to fail");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -459,14 +791,22 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
}
|
||||
|
||||
String missingNode = this.document.toString().replace("-", "x");
|
||||
Form form = this.formService.getForm(missingNode);
|
||||
assertNull("Expecting getForm for a missing node to be null", form);
|
||||
|
||||
try
|
||||
{
|
||||
this.formService.getForm(new Item(NODE_FORM_ITEM_KIND, missingNode));
|
||||
fail("Expecting getForm for a missing node to fail");
|
||||
}
|
||||
catch (FormNotFoundException fnne)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
// test that a form can not be saved for a non-existent item
|
||||
try
|
||||
{
|
||||
this.formService.saveForm("Invalid Item", new FormData());
|
||||
fail("Expecting saveForm for 'Invalid Item' to fail");
|
||||
this.formService.saveForm(new Item("Invalid Kind", "Invalid Id"), new FormData());
|
||||
fail("Expecting saveForm for 'Invalid Kind/Item' to fail");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -475,7 +815,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
|
||||
try
|
||||
{
|
||||
this.formService.saveForm(missingNode, new FormData());
|
||||
this.formService.saveForm(new Item(NODE_FORM_ITEM_KIND, missingNode), new FormData());
|
||||
fail("Expecting saveForm for a missing node to fail");
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -488,7 +828,10 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
||||
{
|
||||
Map<String, Object> model = new HashMap<String, Object>();
|
||||
model.put("testDoc", this.document.toString());
|
||||
model.put("testDocName", this.documentName);
|
||||
model.put("testAssociatedDoc", this.associatedDoc.toString());
|
||||
model.put("folder", this.folder.toString());
|
||||
model.put("folderName", this.folderName);
|
||||
|
||||
ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/forms/script/test_formService.js");
|
||||
this.scriptService.executeScript(location, model);
|
||||
|
82
source/java/org/alfresco/repo/forms/Item.java
Normal file
82
source/java/org/alfresco/repo/forms/Item.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
|
||||
/**
|
||||
* Represents an item a form is generated for.
|
||||
*
|
||||
* @author Gavin Cornwell
|
||||
*/
|
||||
public class Item
|
||||
{
|
||||
private String kind;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Constructs an item.
|
||||
*
|
||||
* @param kind The kind of item, for example, 'node', 'task'
|
||||
* @param id The identifier of the item
|
||||
*/
|
||||
public Item(String kind, String id)
|
||||
{
|
||||
ParameterCheck.mandatoryString("kind", kind);
|
||||
ParameterCheck.mandatoryString("id", id);
|
||||
|
||||
this.kind = kind;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the kind of item.
|
||||
*
|
||||
* @return The kind of item
|
||||
*/
|
||||
public String getKind()
|
||||
{
|
||||
return this.kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier of the item
|
||||
*
|
||||
* @return The identifier of the item
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "[" + this.kind + "]" + this.id;
|
||||
}
|
||||
}
|
@@ -27,6 +27,7 @@ package org.alfresco.repo.forms.processor;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.repo.forms.Item;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -114,14 +115,14 @@ public abstract class AbstractFormProcessor implements FormProcessor
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessor#isApplicable(java.lang.String)
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessor#isApplicable(org.alfresco.repo.forms.Item)
|
||||
*/
|
||||
public boolean isApplicable(String item)
|
||||
public boolean isApplicable(Item item)
|
||||
{
|
||||
// this form processor matches if the match pattern provided matches
|
||||
// the item provided
|
||||
// the kind of the item provided
|
||||
|
||||
Matcher matcher = patternMatcher.matcher(item);
|
||||
Matcher matcher = patternMatcher.matcher(item.getKind());
|
||||
boolean matches = matcher.matches();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
|
@@ -24,9 +24,12 @@
|
||||
*/
|
||||
package org.alfresco.repo.forms.processor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.forms.Form;
|
||||
import org.alfresco.repo.forms.FormData;
|
||||
import org.alfresco.repo.forms.FormException;
|
||||
import org.alfresco.repo.forms.Item;
|
||||
|
||||
/**
|
||||
* Abstract base class for all FormProcessor implementations that wish to use the
|
||||
@@ -52,11 +55,13 @@ public abstract class AbstractFormProcessorByHandlers extends AbstractFormProces
|
||||
* Generates a Form for the given item, constructed by calling each
|
||||
* applicable registered handler
|
||||
*
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessor#generate(java.lang.String)
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessor#generate(org.alfresco.repo.forms.Item, java.util.List, java.util.List)
|
||||
* @param item The item to generate a form for
|
||||
* @param fields Restricted list of fields to include
|
||||
* @param forcedFields List of fields to forcibly include
|
||||
* @return The generated Form
|
||||
*/
|
||||
public Form generate(String item)
|
||||
public Form generate(Item item, List<String> fields, List<String> forcedFields)
|
||||
{
|
||||
if (this.handlerRegistry == null)
|
||||
{
|
||||
@@ -72,7 +77,7 @@ public abstract class AbstractFormProcessorByHandlers extends AbstractFormProces
|
||||
// execute each applicable handler
|
||||
for (Handler handler: this.handlerRegistry.getApplicableHandlers(typedItem))
|
||||
{
|
||||
form = handler.handleGenerate(typedItem, form);
|
||||
form = handler.handleGenerate(typedItem, fields, forcedFields, form);
|
||||
}
|
||||
|
||||
return form;
|
||||
@@ -82,11 +87,11 @@ public abstract class AbstractFormProcessorByHandlers extends AbstractFormProces
|
||||
* Persists the given form data for the given item, completed by calling
|
||||
* each applicable registered handler
|
||||
*
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessor#persist(java.lang.String, org.alfresco.repo.forms.FormData)
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessor#persist(org.alfresco.repo.forms.Item, org.alfresco.repo.forms.FormData)
|
||||
* @param item The item to save the form for
|
||||
* @param data The object representing the form data
|
||||
*/
|
||||
public void persist(String item, FormData data)
|
||||
public void persist(Item item, FormData data)
|
||||
{
|
||||
if (this.handlerRegistry == null)
|
||||
{
|
||||
@@ -113,5 +118,5 @@ public abstract class AbstractFormProcessorByHandlers extends AbstractFormProces
|
||||
* @param item The item to get a typed object for
|
||||
* @return The typed object
|
||||
*/
|
||||
protected abstract Object getTypedItem(String item);
|
||||
protected abstract Object getTypedItem(Item item);
|
||||
}
|
||||
|
@@ -85,7 +85,7 @@ public abstract class AbstractHandler implements Handler
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessorHandler#isApplicable(java.lang.String)
|
||||
* @see org.alfresco.repo.forms.processor.Handler#isApplicable(java.lang.String)
|
||||
*/
|
||||
public boolean isApplicable(Object item)
|
||||
{
|
||||
|
@@ -24,8 +24,11 @@
|
||||
*/
|
||||
package org.alfresco.repo.forms.processor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.forms.Form;
|
||||
import org.alfresco.repo.forms.FormData;
|
||||
import org.alfresco.repo.forms.Item;
|
||||
|
||||
/**
|
||||
* Interface definition of a form processor which is responsible
|
||||
@@ -44,7 +47,7 @@ public interface FormProcessor
|
||||
* @param item The item the form is being generated for
|
||||
* @return true if the processor is applicable
|
||||
*/
|
||||
public boolean isApplicable(String item);
|
||||
public boolean isApplicable(Item item);
|
||||
|
||||
/**
|
||||
* Determines whether this form processor is active
|
||||
@@ -57,9 +60,16 @@ public interface FormProcessor
|
||||
* Returns a Form representation for an item
|
||||
*
|
||||
* @param item The item to generate a Form object for
|
||||
* @param fields Restricted list of fields to include, null
|
||||
* indicates all possible fields for the item
|
||||
* should be included
|
||||
* @param forcedFields List of field names from 'fields' list
|
||||
* that should be forcibly included, it is
|
||||
* up to the form processor implementation
|
||||
* to determine how to enforce this
|
||||
* @return The Form representation
|
||||
*/
|
||||
public Form generate(String item);
|
||||
public Form generate(Item item, List<String> fields, List<String> forcedFields);
|
||||
|
||||
/**
|
||||
* Persists the given object representing the form data
|
||||
@@ -68,5 +78,5 @@ public interface FormProcessor
|
||||
* @param item The item to generate a Form object for
|
||||
* @param data An object representing the data of the form
|
||||
*/
|
||||
public void persist(String item, FormData data);
|
||||
public void persist(Item item, FormData data);
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ package org.alfresco.repo.forms.processor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.forms.Item;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -85,7 +86,7 @@ public class FormProcessorRegistry
|
||||
* @param item The item to find a form processor for
|
||||
* @return An applicable FormProcessor
|
||||
*/
|
||||
public FormProcessor getApplicableFormProcessor(String item)
|
||||
public FormProcessor getApplicableFormProcessor(Item item)
|
||||
{
|
||||
FormProcessor selectedProcessor = null;
|
||||
|
||||
|
@@ -24,6 +24,8 @@
|
||||
*/
|
||||
package org.alfresco.repo.forms.processor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.forms.Form;
|
||||
import org.alfresco.repo.forms.FormData;
|
||||
|
||||
@@ -35,8 +37,6 @@ import org.alfresco.repo.forms.FormData;
|
||||
*/
|
||||
public interface Handler
|
||||
{
|
||||
// TODO: Investigate whether Generics can be used instead of Object
|
||||
|
||||
/**
|
||||
* Determines whether the handler is applicable for the given item.
|
||||
* <p>
|
||||
@@ -63,11 +63,14 @@ public interface Handler
|
||||
* to a more appropriate object, for example all the Node based handlers
|
||||
* can expect a NodeRef object and therefore cast to that.
|
||||
*
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessor#generate(org.alfresco.repo.forms.Item, java.util.List, java.util.List)
|
||||
* @param item The item to generate a Form for
|
||||
* @param fields Restricted list of fields to include
|
||||
* @param forcedFields List of fields to forcibly include
|
||||
* @param form The Form object
|
||||
* @return The modified Form object
|
||||
*/
|
||||
public Form handleGenerate(Object item, Form form);
|
||||
public Form handleGenerate(Object item, List<String> fields, List<String> forcedFields, Form form);
|
||||
|
||||
/**
|
||||
* Handles the persistence of form data for the given item.
|
||||
|
@@ -24,9 +24,13 @@
|
||||
*/
|
||||
package org.alfresco.repo.forms.processor;
|
||||
|
||||
import org.alfresco.repo.forms.FormNotFoundException;
|
||||
import org.alfresco.repo.forms.Item;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* FormProcessor implementation that can generate and persist Form objects
|
||||
@@ -36,6 +40,9 @@ import org.alfresco.service.cmr.repository.NodeService;
|
||||
*/
|
||||
public class NodeFormProcessor extends AbstractFormProcessorByHandlers
|
||||
{
|
||||
/** Logger */
|
||||
private static Log logger = LogFactory.getLog(NodeFormProcessor.class);
|
||||
|
||||
/** Services */
|
||||
protected NodeService nodeService;
|
||||
|
||||
@@ -50,18 +57,50 @@ public class NodeFormProcessor extends AbstractFormProcessorByHandlers
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.processor.AbstractFormProcessor#getTypedItem(java.lang.String)
|
||||
* @see org.alfresco.repo.forms.processor.AbstractFormProcessorByHandlers#getTypedItem(org.alfresco.repo.forms.Item)
|
||||
*/
|
||||
@Override
|
||||
protected Object getTypedItem(String item)
|
||||
protected Object getTypedItem(Item item)
|
||||
{
|
||||
// create NodeRef representation
|
||||
NodeRef nodeRef = new NodeRef(item);
|
||||
// create NodeRef representation, the id could already be in a valid
|
||||
// NodeRef format or it may be in a URL friendly format
|
||||
NodeRef nodeRef = null;
|
||||
if (NodeRef.isNodeRef(item.getId()))
|
||||
{
|
||||
nodeRef = new NodeRef(item.getId());
|
||||
}
|
||||
else
|
||||
{
|
||||
// split the string into the 3 required parts
|
||||
String[] parts = item.getId().split("/");
|
||||
if (parts.length == 3)
|
||||
{
|
||||
try
|
||||
{
|
||||
nodeRef = new NodeRef(parts[0], parts[1], parts[2]);
|
||||
}
|
||||
catch (IllegalArgumentException iae)
|
||||
{
|
||||
// ignored for now, dealt with below
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("NodeRef creation failed for: " + item.getId(), iae);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check we have a valid node ref
|
||||
if (nodeRef == null)
|
||||
{
|
||||
throw new FormNotFoundException(item,
|
||||
new IllegalArgumentException(item.getId()));
|
||||
}
|
||||
|
||||
// check the node itself exists
|
||||
if (this.nodeService.exists(nodeRef) == false)
|
||||
{
|
||||
throw new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef);
|
||||
throw new FormNotFoundException(item,
|
||||
new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -26,7 +26,6 @@ package org.alfresco.repo.forms.processor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -163,9 +162,9 @@ public class NodeHandler extends AbstractHandler
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessorHandler#handleGenerate(java.lang.Object, org.alfresco.repo.forms.Form)
|
||||
* @see org.alfresco.repo.forms.processor.Handler#handleGenerate(java.lang.Object, java.util.List, java.util.List, org.alfresco.repo.forms.Form)
|
||||
*/
|
||||
public Form handleGenerate(Object item, Form form)
|
||||
public Form handleGenerate(Object item, List<String> fields, List<String> forcedFields, Form form)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Generating form for: " + item);
|
||||
@@ -174,7 +173,7 @@ public class NodeHandler extends AbstractHandler
|
||||
NodeRef nodeRef = (NodeRef)item;
|
||||
|
||||
// generate the form for the node
|
||||
generateNode(nodeRef, form);
|
||||
generateNode(nodeRef, fields, forcedFields, form);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Returning form: " + form);
|
||||
@@ -182,117 +181,219 @@ public class NodeHandler extends AbstractHandler
|
||||
return form;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessorHandler#handlePersist(java.lang.Object, org.alfresco.repo.forms.FormData)
|
||||
*/
|
||||
public void handlePersist(Object item, FormData data)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Persisting form for: " + item);
|
||||
|
||||
// cast to the expected NodeRef representation
|
||||
NodeRef nodeRef = (NodeRef)item;
|
||||
|
||||
// persist the node
|
||||
persistNode(nodeRef, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the Form object for the given NodeRef
|
||||
*
|
||||
* @param nodeRef The NodeRef to generate a Form for
|
||||
* @param fields Restricted list of fields to include
|
||||
* @param forcedFields List of fields to forcibly include
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateNode(NodeRef nodeRef, Form form)
|
||||
protected void generateNode(NodeRef nodeRef, List<String> fields, List<String> forcedFields, Form form)
|
||||
{
|
||||
// set the type
|
||||
QName type = this.nodeService.getType(nodeRef);
|
||||
form.setType(type.toPrefixString(this.namespaceService));
|
||||
|
||||
if (fields != null && fields.size() > 0)
|
||||
{
|
||||
generateSelectedFields(nodeRef, fields, forcedFields, form);
|
||||
}
|
||||
else
|
||||
{
|
||||
// setup field definitions and data
|
||||
FormData formData = new FormData();
|
||||
generatePropertyFields(nodeRef, form, formData);
|
||||
generateAssociationFields(nodeRef, form, formData);
|
||||
generateChildAssociationFields(nodeRef, form, formData);
|
||||
generateTransientFields(nodeRef, form, formData);
|
||||
form.setFormData(formData);
|
||||
generateAllPropertyFields(nodeRef, form);
|
||||
generateAllAssociationFields(nodeRef, form);
|
||||
generateAllChildAssociationFields(nodeRef, form);
|
||||
generateTransientFields(nodeRef, form);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists the given FormData on the given NodeRef
|
||||
* Sets up the field definitions for all the requested fields.
|
||||
* If any of the requested fields are not present on the node 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 to persist the form data on
|
||||
* @param data The FormData to persist
|
||||
* @param nodeRef The NodeRef of the node being setup
|
||||
* @param fields Restricted list of fields to include
|
||||
* @param forcedFields List of field names that should be included
|
||||
* even if the field is not currently present
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void persistNode(NodeRef nodeRef, FormData data)
|
||||
protected void generateSelectedFields(NodeRef nodeRef, List<String> fields, List<String> forcedFields, Form form)
|
||||
{
|
||||
// get the property definitions for the type of node being persisted
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Generating selected fields: " + fields + " and forcing: " + forcedFields);
|
||||
|
||||
// get data dictionary definition for node
|
||||
QName type = this.nodeService.getType(nodeRef);
|
||||
Collection<QName> aspects = this.getAspectsToInclude(nodeRef);
|
||||
TypeDefinition typeDef = this.dictionaryService.getAnonymousType(type, aspects);
|
||||
TypeDefinition typeDef = this.dictionaryService.getAnonymousType(type,
|
||||
this.nodeService.getAspects(nodeRef));
|
||||
Map<QName, PropertyDefinition> propDefs = typeDef.getProperties();
|
||||
Map<QName, AssociationDefinition> assocDefs = typeDef.getAssociations();
|
||||
Map<QName, ChildAssociationDefinition> childAssocDefs = typeDef.getChildAssociations();
|
||||
Map<QName, PropertyDefinition> propDefs = typeDef.getProperties();
|
||||
Map<QName, Serializable> propValues = this.nodeService.getProperties(nodeRef);
|
||||
|
||||
Map<QName, Serializable> propsToPersist = new HashMap<QName, Serializable>(data.getData().size());
|
||||
List<AbstractAssocCommand> assocsToPersist = new ArrayList<AbstractAssocCommand>();
|
||||
for (String fieldName : fields)
|
||||
{
|
||||
// try and split the field name
|
||||
String[] parts = fieldName.split(":");
|
||||
if (parts.length == 2)
|
||||
{
|
||||
// create qname of field name
|
||||
String qNamePrefix = parts[0];
|
||||
String localName = parts[1];
|
||||
QName fullQName = QName.createQName(qNamePrefix, localName, namespaceService);
|
||||
|
||||
for (String dataKey : data.getData().keySet())
|
||||
// lookup property def on node
|
||||
PropertyDefinition propDef = propDefs.get(fullQName);
|
||||
if (propDef != null)
|
||||
{
|
||||
FieldData fieldData = data.getData().get(dataKey);
|
||||
// NOTE: ignore file fields for now, not supported yet!
|
||||
if (fieldData.isFile() == false)
|
||||
{
|
||||
String fieldName = fieldData.getName();
|
||||
|
||||
if (fieldName.startsWith(PROP_PREFIX))
|
||||
{
|
||||
processPropertyPersist(nodeRef, propDefs, fieldData, propsToPersist);
|
||||
// generate the property field
|
||||
generatePropertyField(propDef, propValues.get(propDef.getName()), form);
|
||||
}
|
||||
else if (fieldName.startsWith(ASSOC_PREFIX))
|
||||
else
|
||||
{
|
||||
processAssociationPersist(nodeRef, assocDefs, childAssocDefs, fieldData, assocsToPersist);
|
||||
// look for association defined for the type
|
||||
AssociationDefinition assocDef = assocDefs.get(fullQName);
|
||||
if (assocDef != null)
|
||||
{
|
||||
// generate the association field
|
||||
generateAssociationField(assocDef,
|
||||
this.nodeService.getTargetAssocs(nodeRef, fullQName), form);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChildAssociationDefinition childAssocDef = childAssocDefs.get(fullQName);
|
||||
if (childAssocDef != null)
|
||||
{
|
||||
// generate the association field
|
||||
// TODO: see if we can get just the specific child assoc data
|
||||
generateAssociationField(childAssocDef,
|
||||
this.nodeService.getChildAssocs(nodeRef), form);
|
||||
}
|
||||
else
|
||||
{
|
||||
// still not found the field, is it a force'd field?
|
||||
if (forcedFields != null && forcedFields.size() > 0 &&
|
||||
forcedFields.contains(fieldName))
|
||||
{
|
||||
generateForcedField(fullQName, form);
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("Ignoring unrecognised field '" + fieldName + "'");
|
||||
logger.warn("Ignoring field \"" + fieldName +
|
||||
"\" as it is not defined for the current node and it does not appear in the 'force' list");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// persist the properties using addProperties as this changes the repo values of
|
||||
// those properties included in the Map, but leaves any other property values unchanged,
|
||||
// whereas setProperties causes the deletion of properties that are not included in the Map.
|
||||
this.nodeService.addProperties(nodeRef, propsToPersist);
|
||||
|
||||
for (AbstractAssocCommand cmd : assocsToPersist)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO If there is an attempt to add and remove the same assoc in one request,
|
||||
// we could drop each request and do nothing.
|
||||
cmd.updateAssociations(nodeService);
|
||||
// see if the fieldName is a well known transient property
|
||||
if (TRANSIENT_MIMETYPE.equals(fieldName) || TRANSIENT_ENCODING.equals(fieldName) ||
|
||||
TRANSIENT_SIZE.equals(fieldName))
|
||||
{
|
||||
// if the node type is content or sublcass thereof generate appropriate field
|
||||
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
ContentData content = (ContentData)this.nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
if (TRANSIENT_MIMETYPE.equals(fieldName))
|
||||
{
|
||||
generateMimetypePropertyField(content, form);
|
||||
}
|
||||
else if (TRANSIENT_ENCODING.equals(fieldName))
|
||||
{
|
||||
generateEncodingPropertyField(content, form);
|
||||
}
|
||||
else if (TRANSIENT_SIZE.equals(fieldName))
|
||||
{
|
||||
generateSizePropertyField(content, form);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("Ignoring unrecognised field \"" + fieldName + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for the node's properties.
|
||||
* Generates a field definition for the given field that is being forced
|
||||
* to show
|
||||
*
|
||||
* @param fieldName QName of the field to force
|
||||
* @param form The Form instance to populated
|
||||
*/
|
||||
protected void generateForcedField(QName fieldName, Form form)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to force the inclusion of field \"" +
|
||||
fieldName.toPrefixString(this.namespaceService) + "\"");
|
||||
|
||||
// lookup the field as a property in the model
|
||||
PropertyDefinition propDef = this.dictionaryService.getProperty(fieldName);
|
||||
if (propDef != null)
|
||||
{
|
||||
// generate the property field
|
||||
generatePropertyField(propDef, null, form);
|
||||
}
|
||||
else
|
||||
{
|
||||
// lookup the field as an association in the model
|
||||
AssociationDefinition assocDef = this.dictionaryService.getAssociation(fieldName);
|
||||
if (assocDef != null)
|
||||
{
|
||||
// generate the association field
|
||||
generateAssociationField(assocDef, null, form);
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("Ignoring field \"" + fieldName.toPrefixString(this.namespaceService) +
|
||||
"\" as it is not defined for the current node and can not be found in any model");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for all the node's properties.
|
||||
*
|
||||
* @param nodeRef The NodeRef of the node being setup
|
||||
* @param form The Form instance to populate
|
||||
* @param formData The FormData instance to populate
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generatePropertyFields(NodeRef nodeRef, Form form, FormData formData)
|
||||
protected void generateAllPropertyFields(NodeRef nodeRef, Form form)
|
||||
{
|
||||
// get data dictionary definition for node
|
||||
QName type = this.nodeService.getType(nodeRef);
|
||||
Collection<QName> aspects = this.getAspectsToInclude(nodeRef);
|
||||
TypeDefinition typeDef = this.dictionaryService.getAnonymousType(type, aspects);
|
||||
TypeDefinition typeDef = this.dictionaryService.getAnonymousType(type,
|
||||
this.nodeService.getAspects(nodeRef));
|
||||
|
||||
// iterate round the property definitions, create the equivalent
|
||||
// field definition and setup the data for the property
|
||||
// iterate round the property definitions for the node and create
|
||||
// the equivalent field definition and setup the data for the property
|
||||
Map<QName, PropertyDefinition> propDefs = typeDef.getProperties();
|
||||
Map<QName, Serializable> propValues = this.nodeService.getProperties(nodeRef);
|
||||
for (PropertyDefinition propDef : propDefs.values())
|
||||
{
|
||||
generatePropertyField(propDef, propValues.get(propDef.getName()), form);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a field definition for the given property
|
||||
*
|
||||
* @param propDef The PropertyDefinition of the field to generate
|
||||
* @param propValue The value of the property field
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generatePropertyField(PropertyDefinition propDef, Serializable propValue, Form form)
|
||||
{
|
||||
String propName = propDef.getName().toPrefixString(this.namespaceService);
|
||||
PropertyFieldDefinition fieldDef = new PropertyFieldDefinition(
|
||||
@@ -349,34 +450,115 @@ public class NodeHandler extends AbstractHandler
|
||||
|
||||
form.addFieldDefinition(fieldDef);
|
||||
|
||||
// get the field value and add to the form data object
|
||||
Serializable fieldData = propValues.get(propDef.getName());
|
||||
if (fieldData != null)
|
||||
// add the property value to the form
|
||||
if (propValue != null)
|
||||
{
|
||||
if (fieldData instanceof List)
|
||||
if (propValue instanceof List)
|
||||
{
|
||||
// temporarily add repeating field data as a comma
|
||||
// separated list, this will be changed to using
|
||||
// a separate field for each value once we have full
|
||||
// UI support in place.
|
||||
fieldData = makeListString((List)fieldData);
|
||||
propValue = makeListString((List)propValue);
|
||||
}
|
||||
|
||||
formData.addData(PROP_PREFIX + fieldDef.getName(), fieldData);
|
||||
form.addData(PROP_PREFIX + fieldDef.getName(), propValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for any transient fields that may be
|
||||
* useful, for example, 'mimetype', 'size' and 'encoding'.
|
||||
*
|
||||
* @param nodeRef The NodeRef of the node being setup
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateTransientFields(NodeRef nodeRef, Form form)
|
||||
{
|
||||
// if the node is content add the 'mimetype', 'size' and 'encoding' fields.
|
||||
QName type = this.nodeService.getType(nodeRef);
|
||||
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
ContentData content = (ContentData)this.nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
// setup mimetype field
|
||||
generateMimetypePropertyField(content, form);
|
||||
|
||||
// setup encoding field
|
||||
generateEncodingPropertyField(content, form);
|
||||
|
||||
// setup size field
|
||||
generateSizePropertyField(content, form);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for the node's associations.
|
||||
* Generates the field definition for the transient mimetype property
|
||||
*
|
||||
* @param content The ContentData object to generate the field from
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateMimetypePropertyField(ContentData content, Form form)
|
||||
{
|
||||
PropertyFieldDefinition mimetypeField = new PropertyFieldDefinition(
|
||||
TRANSIENT_MIMETYPE, DataTypeDefinition.TEXT.toPrefixString(
|
||||
this.namespaceService));
|
||||
mimetypeField.setLabel(I18NUtil.getMessage(MSG_MIMETYPE_LABEL));
|
||||
mimetypeField.setDescription(I18NUtil.getMessage(MSG_MIMETYPE_DESC));
|
||||
form.addFieldDefinition(mimetypeField);
|
||||
form.addData(PROP_PREFIX + TRANSIENT_MIMETYPE, content.getMimetype());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the field definition for the transient encoding property
|
||||
*
|
||||
* @param content The ContentData object to generate the field from
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateEncodingPropertyField(ContentData content, Form form)
|
||||
{
|
||||
PropertyFieldDefinition encodingField = new PropertyFieldDefinition(
|
||||
TRANSIENT_ENCODING, DataTypeDefinition.TEXT.toPrefixString(
|
||||
this.namespaceService));
|
||||
encodingField.setLabel(I18NUtil.getMessage(MSG_ENCODING_LABEL));
|
||||
encodingField.setDescription(I18NUtil.getMessage(MSG_ENCODING_DESC));
|
||||
form.addFieldDefinition(encodingField);
|
||||
form.addData(PROP_PREFIX + TRANSIENT_ENCODING, content.getEncoding());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the field definition for the transient size property
|
||||
*
|
||||
* @param content The ContentData object to generate the field from
|
||||
* @param form The Form instance to populate
|
||||
*/
|
||||
protected void generateSizePropertyField(ContentData content, Form form)
|
||||
{
|
||||
PropertyFieldDefinition sizeField = new PropertyFieldDefinition(
|
||||
TRANSIENT_SIZE, DataTypeDefinition.LONG.toPrefixString(
|
||||
this.namespaceService));
|
||||
sizeField.setLabel(I18NUtil.getMessage(MSG_SIZE_LABEL));
|
||||
sizeField.setDescription(I18NUtil.getMessage(MSG_SIZE_DESC));
|
||||
sizeField.setProtectedField(true);
|
||||
form.addFieldDefinition(sizeField);
|
||||
form.addData(PROP_PREFIX + TRANSIENT_SIZE, new Long(content.getSize()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for all the node's associations.
|
||||
*
|
||||
* @param nodeRef The NodeRef of the node being setup
|
||||
* @param form The Form instance to populate
|
||||
* @param formData The FormData instance to populate
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generateAssociationFields(NodeRef nodeRef, Form form, FormData formData)
|
||||
protected void generateAllAssociationFields(NodeRef nodeRef, Form form)
|
||||
{
|
||||
// ********************************************************
|
||||
// re-factor this to gen. all assocs defs and not values
|
||||
// ********************************************************
|
||||
|
||||
// add target association data
|
||||
List<AssociationRef> associations = this.nodeService.getTargetAssocs(nodeRef,
|
||||
RegexQNamePattern.MATCH_ALL);
|
||||
@@ -431,11 +613,11 @@ public class NodeHandler extends AbstractHandler
|
||||
|
||||
// add the value as a List (or add to the list if the form data
|
||||
// is already present)
|
||||
FieldData fieldData = formData.getData().get(prefixedAssocName);
|
||||
FieldData fieldData = form.getFormData().getData().get(prefixedAssocName);
|
||||
if (fieldData == null)
|
||||
{
|
||||
targets = new ArrayList<String>(4);
|
||||
formData.addData(prefixedAssocName, targets);
|
||||
form.addData(prefixedAssocName, targets);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -448,7 +630,7 @@ public class NodeHandler extends AbstractHandler
|
||||
else
|
||||
{
|
||||
// there should only be one value
|
||||
formData.addData(prefixedAssocName, assocValue);
|
||||
form.addData(prefixedAssocName, assocValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -459,9 +641,8 @@ public class NodeHandler extends AbstractHandler
|
||||
*
|
||||
* @param nodeRef The NodeRef of the node being setup
|
||||
* @param form The Form instance to populate
|
||||
* @param formData The FormData instance to populate
|
||||
*/
|
||||
protected void generateChildAssociationFields(NodeRef nodeRef, Form form, FormData formData)
|
||||
protected void generateAllChildAssociationFields(NodeRef nodeRef, Form form)
|
||||
{
|
||||
List<ChildAssociationRef> childAssocs = this.nodeService.getChildAssocs(nodeRef);
|
||||
if (childAssocs.isEmpty())
|
||||
@@ -527,7 +708,7 @@ public class NodeHandler extends AbstractHandler
|
||||
|
||||
// We don't want the whitespace or enclosing square brackets that come
|
||||
// with java.util.List.toString(), hence the custom String construction.
|
||||
StringBuilder assocValue = new StringBuilder();
|
||||
/*StringBuilder assocValue = new StringBuilder();
|
||||
for (Iterator<ChildAssociationRef> iter = values.iterator(); iter.hasNext(); )
|
||||
{
|
||||
ChildAssociationRef nextChild = iter.next();
|
||||
@@ -537,55 +718,142 @@ public class NodeHandler extends AbstractHandler
|
||||
assocValue.append(",");
|
||||
}
|
||||
}
|
||||
formData.addData(ASSOC_PREFIX + associationName, assocValue.toString());
|
||||
form.addData(ASSOC_PREFIX + associationName, assocValue.toString());*/
|
||||
|
||||
List<String> nodeRefs = new ArrayList<String>(4);
|
||||
for (Iterator<ChildAssociationRef> iter = values.iterator(); iter.hasNext(); )
|
||||
{
|
||||
ChildAssociationRef nextChild = iter.next();
|
||||
nodeRefs.add(nextChild.getChildRef().toString());
|
||||
}
|
||||
form.addData(ASSOC_PREFIX + associationName, nodeRefs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the field definitions for any transient fields that may be
|
||||
* useful, for example, 'mimetype', 'size' and 'encoding'.
|
||||
* Sets up a field definition for the given association
|
||||
*
|
||||
* @param nodeRef The NodeRef of the node being setup
|
||||
* @param assocDef The AssociationDefinition of the field to generate
|
||||
* @param assocValues The values of the association field
|
||||
* @param form The Form instance to populate
|
||||
* @param formData The FormData instance to populate
|
||||
*/
|
||||
protected void generateTransientFields(NodeRef nodeRef, Form form, FormData formData)
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generateAssociationField(AssociationDefinition assocDef,
|
||||
List assocValues, Form form)
|
||||
{
|
||||
// if the node is content add the 'mimetype', 'size' and 'encoding' fields.
|
||||
QName type = this.nodeService.getType(nodeRef);
|
||||
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||
String assocName = assocDef.getName().toPrefixString(this.namespaceService);
|
||||
AssociationFieldDefinition fieldDef = new AssociationFieldDefinition(assocName,
|
||||
assocDef.getTargetClass().getName().toPrefixString(
|
||||
this.namespaceService), Direction.TARGET);
|
||||
String title = assocDef.getTitle();
|
||||
if (title == null)
|
||||
{
|
||||
ContentData content = (ContentData)this.nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
// setup mimetype field
|
||||
PropertyFieldDefinition mimetypeField = new PropertyFieldDefinition(
|
||||
TRANSIENT_MIMETYPE, DataTypeDefinition.TEXT.toPrefixString(
|
||||
this.namespaceService));
|
||||
mimetypeField.setLabel(I18NUtil.getMessage(MSG_MIMETYPE_LABEL));
|
||||
mimetypeField.setDescription(I18NUtil.getMessage(MSG_MIMETYPE_DESC));
|
||||
form.addFieldDefinition(mimetypeField);
|
||||
formData.addData(PROP_PREFIX + TRANSIENT_MIMETYPE, content.getMimetype());
|
||||
|
||||
// setup encoding field
|
||||
PropertyFieldDefinition encodingField = new PropertyFieldDefinition(
|
||||
TRANSIENT_ENCODING, DataTypeDefinition.TEXT.toPrefixString(
|
||||
this.namespaceService));
|
||||
encodingField.setLabel(I18NUtil.getMessage(MSG_ENCODING_LABEL));
|
||||
encodingField.setDescription(I18NUtil.getMessage(MSG_ENCODING_DESC));
|
||||
form.addFieldDefinition(encodingField);
|
||||
formData.addData(PROP_PREFIX + TRANSIENT_ENCODING, content.getEncoding());
|
||||
|
||||
// setup size field
|
||||
PropertyFieldDefinition sizeField = new PropertyFieldDefinition(
|
||||
TRANSIENT_SIZE, DataTypeDefinition.LONG.toPrefixString(
|
||||
this.namespaceService));
|
||||
sizeField.setLabel(I18NUtil.getMessage(MSG_SIZE_LABEL));
|
||||
sizeField.setDescription(I18NUtil.getMessage(MSG_SIZE_DESC));
|
||||
sizeField.setProtectedField(true);
|
||||
form.addFieldDefinition(sizeField);
|
||||
formData.addData(PROP_PREFIX + TRANSIENT_SIZE, new Long(content.getSize()));
|
||||
title = assocName;
|
||||
}
|
||||
fieldDef.setLabel(title);
|
||||
fieldDef.setDescription(assocDef.getDescription());
|
||||
fieldDef.setProtectedField(assocDef.isProtected());
|
||||
fieldDef.setEndpointMandatory(assocDef.isTargetMandatory());
|
||||
fieldDef.setEndpointMany(assocDef.isTargetMany());
|
||||
|
||||
// add definition to the form
|
||||
form.addFieldDefinition(fieldDef);
|
||||
|
||||
// add the association value to the form
|
||||
String prefixedAssocName = ASSOC_PREFIX + assocName;
|
||||
|
||||
// determine the type of association values data and extract accordingly
|
||||
List<String> values = new ArrayList<String>(4);
|
||||
for (Object value : assocValues)
|
||||
{
|
||||
if (value instanceof ChildAssociationRef)
|
||||
{
|
||||
values.add(((ChildAssociationRef)value).getChildRef().toString());
|
||||
}
|
||||
else if (value instanceof AssociationRef)
|
||||
{
|
||||
values.add(((AssociationRef)value).getTargetRef().toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
values.add(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the list as the value for the association.
|
||||
// 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
|
||||
// to display the current values to the user
|
||||
form.addData(prefixedAssocName, values);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.alfresco.repo.forms.processor.FormProcessorHandler#handlePersist(java.lang.Object, org.alfresco.repo.forms.FormData)
|
||||
*/
|
||||
public void handlePersist(Object item, FormData data)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Persisting form for: " + item);
|
||||
|
||||
// cast to the expected NodeRef representation
|
||||
NodeRef nodeRef = (NodeRef)item;
|
||||
|
||||
// persist the node
|
||||
persistNode(nodeRef, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists the given FormData on the given NodeRef
|
||||
*
|
||||
* @param nodeRef The NodeRef to persist the form data on
|
||||
* @param data The FormData to persist
|
||||
*/
|
||||
protected void persistNode(NodeRef nodeRef, FormData data)
|
||||
{
|
||||
// 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));
|
||||
Map<QName, AssociationDefinition> assocDefs = typeDef.getAssociations();
|
||||
Map<QName, ChildAssociationDefinition> childAssocDefs = typeDef.getChildAssociations();
|
||||
Map<QName, PropertyDefinition> propDefs = typeDef.getProperties();
|
||||
|
||||
Map<QName, Serializable> propsToPersist = new HashMap<QName, Serializable>(data.getData().size());
|
||||
List<AbstractAssocCommand> assocsToPersist = new ArrayList<AbstractAssocCommand>();
|
||||
|
||||
for (String dataKey : data.getData().keySet())
|
||||
{
|
||||
FieldData fieldData = data.getData().get(dataKey);
|
||||
// NOTE: ignore file fields for now, not supported yet!
|
||||
if (fieldData.isFile() == false)
|
||||
{
|
||||
String fieldName = fieldData.getName();
|
||||
|
||||
if (fieldName.startsWith(PROP_PREFIX))
|
||||
{
|
||||
processPropertyPersist(nodeRef, propDefs, fieldData, propsToPersist);
|
||||
}
|
||||
else if (fieldName.startsWith(ASSOC_PREFIX))
|
||||
{
|
||||
processAssociationPersist(nodeRef, assocDefs, childAssocDefs, fieldData, assocsToPersist);
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("Ignoring unrecognised field '" + fieldName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// persist the properties using addProperties as this changes the repo values of
|
||||
// those properties included in the Map, but leaves any other property values unchanged,
|
||||
// whereas setProperties causes the deletion of properties that are not included in the Map.
|
||||
this.nodeService.addProperties(nodeRef, propsToPersist);
|
||||
|
||||
for (AbstractAssocCommand cmd : assocsToPersist)
|
||||
{
|
||||
//TODO If there is an attempt to add and remove the same assoc in one request,
|
||||
// we could drop each request and do nothing.
|
||||
cmd.updateAssociations(nodeService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -946,33 +1214,6 @@ public class NodeHandler extends AbstractHandler
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Collection of aspects for the given noderef to use
|
||||
* for generating and persisting the form.
|
||||
*
|
||||
* @param nodeRef The NodeRef of the node to get aspects for
|
||||
* @return The Collection of aspects
|
||||
*/
|
||||
protected Collection<QName> getAspectsToInclude(NodeRef nodeRef)
|
||||
{
|
||||
List<QName> currentAspects = new ArrayList<QName>();
|
||||
currentAspects.addAll(this.nodeService.getAspects(nodeRef));
|
||||
|
||||
// TODO: make the list of aspects to ensure are present configurable
|
||||
|
||||
// make sure the titled and author aspects are present
|
||||
if (currentAspects.contains(ContentModel.ASPECT_TITLED) == false)
|
||||
{
|
||||
currentAspects.add(ContentModel.ASPECT_TITLED);
|
||||
}
|
||||
if (currentAspects.contains(ContentModel.ASPECT_AUTHOR) == false)
|
||||
{
|
||||
currentAspects.add(ContentModel.ASPECT_AUTHOR);
|
||||
}
|
||||
|
||||
return currentAspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comma separated list string of the given list object.
|
||||
*
|
||||
|
@@ -58,9 +58,14 @@ public class ScriptForm implements Serializable
|
||||
}
|
||||
}
|
||||
|
||||
public String getItem()
|
||||
public String getItemKind()
|
||||
{
|
||||
return form.getItem();
|
||||
return form.getItem().getKind();
|
||||
}
|
||||
|
||||
public String getItemId()
|
||||
{
|
||||
return form.getItem().getId();
|
||||
}
|
||||
|
||||
public String getType()
|
||||
|
@@ -24,11 +24,14 @@
|
||||
*/
|
||||
package org.alfresco.repo.forms.script;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.forms.Form;
|
||||
import org.alfresco.repo.forms.FormData;
|
||||
import org.alfresco.repo.forms.FormService;
|
||||
import org.alfresco.repo.forms.Item;
|
||||
import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -40,22 +43,10 @@ import org.apache.commons.logging.LogFactory;
|
||||
public class ScriptFormService extends BaseScopableProcessorExtension
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ScriptFormService.class);
|
||||
/** Service Registry */
|
||||
private ServiceRegistry serviceRegistry;
|
||||
|
||||
/** The site service */
|
||||
private FormService formService;
|
||||
|
||||
/**
|
||||
* Sets the Service Registry
|
||||
*
|
||||
* @param serviceRegistry
|
||||
*/
|
||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the form service
|
||||
*
|
||||
@@ -68,25 +59,79 @@ public class ScriptFormService extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the form for the given item
|
||||
* Returns a form representation of the given item,
|
||||
* all known fields for the item are included.
|
||||
*
|
||||
* @param item The item to retrieve a form for
|
||||
* @param itemKind The kind of item to retrieve a form for
|
||||
* @param itemId The identifier of the item to retrieve a form for
|
||||
* @return The form
|
||||
*/
|
||||
public ScriptForm getForm(String item)
|
||||
public ScriptForm getForm(String itemKind, String itemId)
|
||||
{
|
||||
Form result = formService.getForm(item);
|
||||
return getForm(itemKind, itemId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form representation of the given item consisting
|
||||
* only of the given fields.
|
||||
*
|
||||
* @param itemKind The kind of item to retrieve a form for
|
||||
* @param itemId The identifier of the item to retrieve a form for
|
||||
* @param fields String array of fields to include, null
|
||||
* indicates all possible fields for the item
|
||||
* should be included
|
||||
* @return The form
|
||||
*/
|
||||
public ScriptForm getForm(String itemKind, String itemId, String[] fields)
|
||||
{
|
||||
return getForm(itemKind, itemId, fields, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form representation of the given item consisting
|
||||
* only of the given fields.
|
||||
*
|
||||
* @param itemKind The kind of item to retrieve a form for
|
||||
* @param itemId The identifier of the item to retrieve a form for
|
||||
* @param fields String array of fields to include, null
|
||||
* indicates all possible fields for the item
|
||||
* should be included
|
||||
* @param forcedFields List of field names from 'fields' list
|
||||
* that should be forcibly included, it is
|
||||
* up to the form processor implementation
|
||||
* to determine how to enforce this
|
||||
* @return The form
|
||||
*/
|
||||
public ScriptForm getForm(String itemKind, String itemId,
|
||||
String[] fields, String[] forcedFields)
|
||||
{
|
||||
// create List<String> representations of field params if necessary
|
||||
List<String> fieldsList = null;
|
||||
List<String> forcedFieldsList = null;
|
||||
|
||||
if (fields != null)
|
||||
{
|
||||
fieldsList = Arrays.asList(fields);
|
||||
}
|
||||
|
||||
if (forcedFields != null)
|
||||
{
|
||||
forcedFieldsList = Arrays.asList(forcedFields);
|
||||
}
|
||||
|
||||
Form result = formService.getForm(new Item(itemKind, itemId), fieldsList, forcedFieldsList);
|
||||
return result == null ? null : new ScriptForm(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists the given data object for the item provided
|
||||
*
|
||||
* @param item The item to persist the data for
|
||||
* @param itemKind The kind of item to retrieve a form for
|
||||
* @param itemId The identifier of the item to retrieve a form for
|
||||
* @param postData The post data, this can be a Map of name value
|
||||
* pairs, a webscript FormData object or a JSONObject
|
||||
*/
|
||||
public void saveForm(String item, Object postData)
|
||||
public void saveForm(String itemKind, String itemId, Object postData)
|
||||
{
|
||||
// A note on data conversion as passed in to this method:
|
||||
// Each of the 3 submission methods (multipart/formdata, JSON Post and
|
||||
@@ -109,6 +154,6 @@ public class ScriptFormService extends BaseScopableProcessorExtension
|
||||
return;
|
||||
}
|
||||
|
||||
formService.saveForm(item, dataForFormService);
|
||||
formService.saveForm(new Item(itemKind, itemId), dataForFormService);
|
||||
}
|
||||
}
|
||||
|
@@ -3,24 +3,35 @@ function testGetFormForNonExistentContentNode()
|
||||
// Replace all the digits in the ID with an 'x'.
|
||||
// Surely that node will not exist...
|
||||
var corruptedTestDoc = testDoc.replace(/\d/g, "x");
|
||||
var form = formService.getForm(corruptedTestDoc);
|
||||
var form = null;
|
||||
|
||||
try
|
||||
{
|
||||
form = formService.getForm("node", corruptedTestDoc);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
test.assertNull(form, "Form should have not been found: " + testDoc);
|
||||
}
|
||||
|
||||
function testGetFormForContentNode()
|
||||
{
|
||||
// Get a known form and check its various attributes/properties.
|
||||
var form = formService.getForm(testDoc);
|
||||
test.assertNotNull(form, "Form should have been found: " + testDoc);
|
||||
var form = formService.getForm("node", testDoc);
|
||||
test.assertNotNull(form, "Form should have been found for: " + testDoc);
|
||||
|
||||
test.assertEquals(testDoc, form.item);
|
||||
test.assertEquals("node", form.itemKind);
|
||||
test.assertEquals(testDoc, form.itemId);
|
||||
test.assertEquals('cm:content', form.type);
|
||||
|
||||
test.assertNull(form.fieldGroups, "form.fieldGroups should be null.");
|
||||
|
||||
var fieldDefs = form.fieldDefinitions;
|
||||
test.assertNotNull(fieldDefs, "field definitions should not be null.");
|
||||
test.assertEquals(23, fieldDefs.length);
|
||||
test.assertEquals(22, fieldDefs.length);
|
||||
|
||||
// as we know there are no duplicates we can safely create a map of the
|
||||
// field definitions for the purposes of this test
|
||||
@@ -101,6 +112,7 @@ function testGetFormForContentNode()
|
||||
test.assertNotNull(fieldData, "fieldData should not be null.");
|
||||
test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
|
||||
|
||||
test.assertEquals(testDocName, fieldData["prop:cm:name"].value);
|
||||
test.assertEquals("This is the title for the test document", fieldData["prop:cm:title"].value);
|
||||
test.assertEquals("This is the description for the test document", fieldData["prop:cm:description"].value);
|
||||
test.assertEquals("fred@customer.com", fieldData["prop:cm:originator"].value);
|
||||
@@ -126,6 +138,195 @@ function testGetFormForContentNode()
|
||||
test.assertEquals(testAssociatedDoc, targets);
|
||||
}
|
||||
|
||||
function testGetFormForFolderNode()
|
||||
{
|
||||
// Get a known form and check its various attributes/properties.
|
||||
var form = formService.getForm("node", folder);
|
||||
test.assertNotNull(form, "Form should have been found for: " + testDoc);
|
||||
|
||||
test.assertEquals("node", form.itemKind);
|
||||
test.assertEquals(folder, form.itemId);
|
||||
test.assertEquals('cm:folder', form.type);
|
||||
|
||||
test.assertNull(form.fieldGroups, "form.fieldGroups should be null.");
|
||||
|
||||
var fieldDefs = form.fieldDefinitions;
|
||||
test.assertNotNull(fieldDefs, "field definitions should not be null.");
|
||||
test.assertEquals(11, fieldDefs.length);
|
||||
|
||||
// as we know there are no duplicates we can safely create a map of the
|
||||
// field definitions for the purposes of this test
|
||||
var fieldDefnDataHash = {};
|
||||
var fieldDef = null;
|
||||
for (var x = 0; x < fieldDefs.length; x++)
|
||||
{
|
||||
fieldDef = fieldDefs[x];
|
||||
fieldDefnDataHash[fieldDef.name] = fieldDef;
|
||||
}
|
||||
|
||||
var nameField = fieldDefnDataHash['cm:name'];
|
||||
var containsField = fieldDefnDataHash['cm:contains'];
|
||||
|
||||
test.assertNotNull(nameField, "Expecting to find the cm:name field");
|
||||
test.assertNotNull(containsField, "Expecting to find the cm:contains field");
|
||||
|
||||
// check the labels of all the fields
|
||||
test.assertEquals("Name", nameField.label);
|
||||
test.assertEquals("Contains", containsField.label);
|
||||
|
||||
// check details of name field
|
||||
test.assertEquals("d:text", nameField.dataType);
|
||||
test.assertTrue(nameField.mandatory);
|
||||
// Expecting cm:name to be single-valued.
|
||||
test.assertFalse(nameField.repeating, "nameField.repeating was not false.");
|
||||
|
||||
// compare the association details
|
||||
test.assertEquals("TARGET", "" + containsField.endpointDirection);
|
||||
test.assertFalse(containsField.endpointMandatory, "containsField.endpointMandatory was not false.");
|
||||
test.assertTrue(containsField.endpointMany, "constainsField.endpointMany was not true.");
|
||||
|
||||
// check the form data
|
||||
var formData = form.formData;
|
||||
test.assertNotNull(formData, "formData should not be null.");
|
||||
var fieldData = formData.data;
|
||||
test.assertNotNull(fieldData, "fieldData should not be null.");
|
||||
test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
|
||||
|
||||
test.assertEquals(folderName, fieldData["prop:cm:name"].value);
|
||||
var children = fieldData["assoc:cm:contains"].value;
|
||||
test.assertNotNull(children, "children should not be null.");
|
||||
var childrenArr = children.split(",");
|
||||
test.assertTrue(childrenArr.length == 3, "Expecting there to be 3 children");
|
||||
}
|
||||
|
||||
function testGetFormWithSelectedFields()
|
||||
{
|
||||
// Define list of fields to retrieve
|
||||
var fields = [];
|
||||
fields.push("cm:name");
|
||||
fields.push("cm:title");
|
||||
fields.push("mimetype");
|
||||
fields.push("cm:modified");
|
||||
// add field that will be missing
|
||||
fields.push("cm:author");
|
||||
|
||||
// Get a a form for the given fields
|
||||
var form = formService.getForm("node", testDoc, fields);
|
||||
test.assertNotNull(form, "Form should have been found for: " + testDoc);
|
||||
|
||||
var fieldDefs = form.fieldDefinitions;
|
||||
test.assertNotNull(fieldDefs, "field definitions should not be null.");
|
||||
test.assertEquals(4, fieldDefs.length);
|
||||
|
||||
// as we know there are no duplicates we can safely create a map of the
|
||||
// field definitions for the purposes of this test
|
||||
var fieldDefnDataHash = {};
|
||||
var fieldDef = null;
|
||||
for (var x = 0; x < fieldDefs.length; x++)
|
||||
{
|
||||
fieldDef = fieldDefs[x];
|
||||
fieldDefnDataHash[fieldDef.name] = fieldDef;
|
||||
}
|
||||
|
||||
var nameField = fieldDefnDataHash['cm:name'];
|
||||
var titleField = fieldDefnDataHash['cm:title'];
|
||||
var mimetypeField = fieldDefnDataHash['mimetype'];
|
||||
var modifiedField = fieldDefnDataHash['cm:modified'];
|
||||
var authorField = fieldDefnDataHash['cm:author'];
|
||||
|
||||
test.assertNotNull(nameField, "Expecting to find the cm:name field");
|
||||
test.assertNotNull(titleField, "Expecting to find the cm:title field");
|
||||
test.assertNotNull(mimetypeField, "Expecting to find the mimetype field");
|
||||
test.assertNotNull(modifiedField, "Expecting to find the cm:modified field");
|
||||
test.assertTrue(authorField === undefined, "Expecting cm:author field to be missing");
|
||||
|
||||
// check the labels of all the fields
|
||||
test.assertEquals("Name", nameField.label);
|
||||
test.assertEquals("Title", titleField.label);
|
||||
test.assertEquals("Mimetype", mimetypeField.label);
|
||||
test.assertEquals("Modified Date", modifiedField.label);
|
||||
|
||||
// check the form data
|
||||
var formData = form.formData;
|
||||
test.assertNotNull(formData, "formData should not be null.");
|
||||
var fieldData = formData.data;
|
||||
test.assertNotNull(fieldData, "fieldData should not be null.");
|
||||
test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
|
||||
|
||||
test.assertEquals(testDocName, fieldData["prop:cm:name"].value);
|
||||
test.assertEquals("This is the title for the test document", fieldData["prop:cm:title"].value);
|
||||
}
|
||||
|
||||
function testGetFormWithForcedFields()
|
||||
{
|
||||
// Define list of fields to retrieve
|
||||
var fields = [];
|
||||
fields.push("cm:name");
|
||||
fields.push("cm:title");
|
||||
fields.push("mimetype");
|
||||
fields.push("cm:modified");
|
||||
fields.push("cm:author");
|
||||
fields.push("cm:wrong");
|
||||
|
||||
// define a list of fields to force
|
||||
var force = [];
|
||||
force.push("cm:author");
|
||||
force.push("cm:wrong");
|
||||
|
||||
// Get a a form for the given fields
|
||||
var form = formService.getForm("node", testDoc, fields, force);
|
||||
test.assertNotNull(form, "Form should have been found for: " + testDoc);
|
||||
|
||||
var fieldDefs = form.fieldDefinitions;
|
||||
test.assertNotNull(fieldDefs, "field definitions should not be null.");
|
||||
test.assertEquals(5, fieldDefs.length);
|
||||
|
||||
// as we know there are no duplicates we can safely create a map of the
|
||||
// field definitions for the purposes of this test
|
||||
var fieldDefnDataHash = {};
|
||||
var fieldDef = null;
|
||||
for (var x = 0; x < fieldDefs.length; x++)
|
||||
{
|
||||
fieldDef = fieldDefs[x];
|
||||
fieldDefnDataHash[fieldDef.name] = fieldDef;
|
||||
}
|
||||
|
||||
var nameField = fieldDefnDataHash['cm:name'];
|
||||
var titleField = fieldDefnDataHash['cm:title'];
|
||||
var mimetypeField = fieldDefnDataHash['mimetype'];
|
||||
var modifiedField = fieldDefnDataHash['cm:modified'];
|
||||
var authorField = fieldDefnDataHash['cm:author'];
|
||||
var wrongField = fieldDefnDataHash['cm:wrong'];
|
||||
|
||||
test.assertNotNull(nameField, "Expecting to find the cm:name field");
|
||||
test.assertNotNull(titleField, "Expecting to find the cm:title field");
|
||||
test.assertNotNull(mimetypeField, "Expecting to find the mimetype field");
|
||||
test.assertNotNull(modifiedField, "Expecting to find the cm:modified field");
|
||||
test.assertNotNull(authorField, "Expecting to find the cm:author field");
|
||||
test.assertTrue(wrongField === undefined, "Expecting cm:wrong field to be missing");
|
||||
|
||||
// check the labels of all the fields
|
||||
test.assertEquals("Name", nameField.label);
|
||||
test.assertEquals("Title", titleField.label);
|
||||
test.assertEquals("Mimetype", mimetypeField.label);
|
||||
test.assertEquals("Modified Date", modifiedField.label);
|
||||
test.assertEquals("Author", authorField.label);
|
||||
|
||||
// check the form data
|
||||
var formData = form.formData;
|
||||
test.assertNotNull(formData, "formData should not be null.");
|
||||
var fieldData = formData.data;
|
||||
test.assertNotNull(fieldData, "fieldData should not be null.");
|
||||
test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
|
||||
|
||||
test.assertEquals(testDocName, fieldData["prop:cm:name"].value);
|
||||
test.assertEquals("This is the title for the test document", fieldData["prop:cm:title"].value);
|
||||
test.assertNull(fieldData["prop:cm:author"], "Expecting cm:author to be null");
|
||||
}
|
||||
|
||||
// Execute tests
|
||||
testGetFormForNonExistentContentNode();
|
||||
testGetFormForContentNode();
|
||||
testGetFormForFolderNode();
|
||||
testGetFormWithSelectedFields();
|
||||
testGetFormWithForcedFields();
|
||||
|
Reference in New Issue
Block a user