Completion of MOB-837 (type support in forms)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14621 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell 2009-06-10 09:33:58 +00:00
parent e3c41b3fb2
commit 896bfd8986
7 changed files with 210 additions and 13 deletions

View File

@ -54,6 +54,9 @@
<bean id="nodeFilterRegistry"
class="org.alfresco.repo.forms.processor.FilterRegistry" />
<bean id="typeFilterRegistry"
class="org.alfresco.repo.forms.processor.FilterRegistry" />
<!-- Form processors -->
<bean id="baseFormProcessor" abstract="true" init-method="register"
@ -81,7 +84,7 @@
<bean id="typeFormProcessor"
class="org.alfresco.repo.forms.processor.node.TypeFormProcessor"
parent="filteredFormProcessor">
<!-- <property name="filterRegistry" ref="nodeFilterRegistry" /> -->
<property name="filterRegistry" ref="typeFilterRegistry" />
<property name="nodeService" ref="NodeService" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="dictionaryService" ref="DictionaryService" />
@ -98,7 +101,9 @@
<!--
<bean id="imageAspectFormFilter"
class="org.alfresco.repo.forms.processor.node.ImageAspectHandler"
parent="baseFormFilter" />
parent="baseFormFilter">
<property name="filterRegistry" ref="nodeFilterRegistry" />
</bean>
-->
<bean id="formServiceScript" parent="baseJavaScriptExtension" class="org.alfresco.repo.forms.script.ScriptFormService">

View File

@ -78,6 +78,7 @@ public interface FormService
*
* @param item The item to persist the form for
* @param data An object representing the form data to persist
* @return The object persisted
*/
public void saveForm(Item item, FormData data);
public Object saveForm(Item item, FormData data);
}

View File

@ -98,7 +98,7 @@ public class FormServiceImpl implements FormService
/*
* @see org.alfresco.repo.forms.FormService#saveForm(org.alfresco.repo.forms.Item, org.alfresco.repo.forms.FormData)
*/
public void saveForm(Item item, FormData data)
public Object saveForm(Item item, FormData data)
{
if (this.processorRegistry == null)
{
@ -116,7 +116,7 @@ public class FormServiceImpl implements FormService
}
else
{
processor.persist(item, data);
return processor.persist(item, data);
}
}
}

View File

@ -713,7 +713,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
}
@SuppressWarnings("unchecked")
public void testSaveForm() throws Exception
public void testSaveNodeForm() throws Exception
{
// create FormData object containing the values to update
FormData data = new FormData();
@ -804,8 +804,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
*/
}
// TODO: enable this once the RM caveat stuff is fixed
public void xtestGetAllCreateForm() throws Exception
public void testGetAllCreateForm() throws Exception
{
// get a form for the cm:content type
Form form = this.formService.getForm(new Item(TYPE_FORM_ITEM_KIND, "cm:content"));
@ -853,6 +852,102 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertNotNull("Expecting to find the cm:modifier field", modifierField);
}
public void testGetSelectedFieldsCreateForm() 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");
// get a form for the cm:content type
Form form = this.formService.getForm(new Item(TYPE_FORM_ITEM_KIND, "cm:content"), fields);
// check a form got returned
assertNotNull("Expecting form to be present", form);
// check item identifier matches
assertEquals(TYPE_FORM_ITEM_KIND, form.getItem().getKind());
assertEquals("cm:content", form.getItem().getId());
// check the type is correct
assertEquals(ContentModel.TYPE_CONTENT.toPrefixString(this.namespaceService),
form.getItem().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 1 field", 1, 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");
assertNotNull("Expecting to find the cm:name field", nameField);
// now force the title field to be present and check
List<String> forcedFields = new ArrayList<String>(2);
forcedFields.add("cm:title");
// get a form for the cm:content type
form = this.formService.getForm(new Item(TYPE_FORM_ITEM_KIND, "cm:content"), fields, forcedFields);
fieldDefs = form.getFieldDefinitions();
assertNotNull("Expecting to find fields", fieldDefs);
assertEquals("Expecting to find 2 fields", 2, fieldDefs.size());
}
public void testSaveTypeForm() throws Exception
{
// create FormData object containing the values to update
FormData data = new FormData();
// supply the name
String name = "new-" + this.documentName;
data.addData("prop_cm_name", name);
// supply the title property
String title = "This is the title property";
data.addData("prop_cm_title", title);
// persist the data (without a destination and make sure it fails)
try
{
this.formService.saveForm(new Item(TYPE_FORM_ITEM_KIND, "cm:content"), data);
fail("Expected the persist to fail as there was no destination");
}
catch (FormException fe)
{
// expected
}
// supply the destination
data.addData("destination", this.folder.toString());
// persist the data
NodeRef newNode = (NodeRef)this.formService.saveForm(new Item(TYPE_FORM_ITEM_KIND, "cm:content"), data);
// retrieve the data directly from the node service to ensure its there
Map<QName, Serializable> props = this.nodeService.getProperties(newNode);
String newName = (String)props.get(ContentModel.PROP_NAME);
String newTitle = (String)props.get(ContentModel.PROP_TITLE);
assertEquals(name, newName);
assertEquals(title, newTitle);
// check the titled aspect was automatically applied
assertTrue("Expecting the cm:titled to have been applied",
this.nodeService.hasAspect(this.document, ContentModel.ASPECT_TITLED));
}
public void testNoForm() throws Exception
{
// test that a form can not be retrieved for a non-existent item

View File

@ -98,8 +98,9 @@ public abstract class FilteredFormProcessor extends AbstractFormProcessor
* @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
* @return The object persisted
*/
public void persist(Item item, FormData data)
public Object persist(Item item, FormData data)
{
// get the typed object representing the item
Object typedItem = getTypedItem(item);
@ -124,6 +125,8 @@ public abstract class FilteredFormProcessor extends AbstractFormProcessor
filter.afterPersist(typedItem, data, persistedObject);
}
}
return persistedObject;
}
/**

View File

@ -77,6 +77,7 @@ public interface FormProcessor
*
* @param item The item to generate a Form object for
* @param data An object representing the data of the form
* @return The object persisted
*/
public void persist(Item item, FormData data);
public Object persist(Item item, FormData data);
}

View File

@ -24,19 +24,27 @@
*/
package org.alfresco.repo.forms.processor.node;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData;
import org.alfresco.repo.forms.FormException;
import org.alfresco.repo.forms.FormNotFoundException;
import org.alfresco.repo.forms.Item;
import org.alfresco.repo.forms.FormData.FieldData;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.InvalidQNameException;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -51,6 +59,12 @@ public class TypeFormProcessor extends NodeFormProcessor
/** Logger */
private static Log logger = LogFactory.getLog(TypeFormProcessor.class);
protected static final String DESTINATION = "destination";
protected static final String NAME_PROP_DATA = PROP + DATA_KEY_SEPARATOR + "cm" + DATA_KEY_SEPARATOR + "name";
/*
* @see org.alfresco.repo.forms.processor.node.NodeFormProcessor#getTypedItem(org.alfresco.repo.forms.Item)
*/
@Override
protected Object getTypedItem(Item item)
{
@ -80,6 +94,9 @@ public class TypeFormProcessor extends NodeFormProcessor
return typeDef;
}
/*
* @see org.alfresco.repo.forms.processor.node.NodeFormProcessor#internalGenerate(java.lang.Object, java.util.List, java.util.List, org.alfresco.repo.forms.Form)
*/
@Override
protected void internalGenerate(Object item, List<String> fields, List<String> forcedFields, Form form)
{
@ -178,6 +195,9 @@ public class TypeFormProcessor extends NodeFormProcessor
}
}
/*
* @see org.alfresco.repo.forms.processor.node.NodeFormProcessor#internalPersist(java.lang.Object, org.alfresco.repo.forms.FormData)
*/
@Override
protected Object internalPersist(Object item, FormData data)
{
@ -187,10 +207,82 @@ public class TypeFormProcessor extends NodeFormProcessor
// cast to the expected NodeRef representation
TypeDefinition typeDef = (TypeDefinition)item;
if (logger.isWarnEnabled())
logger.warn("Persisting of 'type' form items has not been implemented yet!");
// create a new instance of the type
NodeRef nodeRef = createNode(typeDef, data);
return item;
// persist the form data
persistNode(nodeRef, data);
// return the newly created node
return nodeRef;
}
/**
* Creates a new instance of the given type.
* <p>
* If the form data has the name property present it is used as
* the name of the node.
* </p><p>
* The new node is placed in the location defined by the "destination"
* data item in the form data (this will usually be a hidden field),
* this will also be the NodeRef representation of the parent for the
* new node.
* </p>
*
* @param typeDef The type defintion of the type to create
* @param data The form data
* @return NodeRef representing the newly created node
*/
protected NodeRef createNode(TypeDefinition typeDef, FormData data)
{
NodeRef nodeRef = null;
if (data != null)
{
Map<String, FieldData> fieldData = data.getData();
if (fieldData != null)
{
// firstly, ensure we have a destination to create the node in
NodeRef parentRef = null;
FieldData destination = fieldData.get(DESTINATION);
if (destination == null)
{
throw new FormException("Failed to persist form for '" +
typeDef.getName().toPrefixString(this.namespaceService) +
"' as destination data was not present.");
}
// create the parent NodeRef
parentRef = new NodeRef((String)destination.getValue());
// TODO: determine what association to use when creating the node in the destination,
// defaults to ContentModel.ASSOC_CONTAINS
// if a name property is present in the form data use it as the node name,
// otherwise generate a guid
String nodeName = null;
FieldData nameData = fieldData.get(NAME_PROP_DATA);
if (nameData != null)
{
nodeName = (String)nameData.getValue();
// remove the name data otherwise 'rename' gets called in persistNode
fieldData.remove(NAME_PROP_DATA);
}
if (nodeName == null || nodeName.length() == 0)
{
nodeName = GUID.generate();
}
// create the node
Map<QName, Serializable> nodeProps = new HashMap<QName, Serializable>(1);
nodeProps.put(ContentModel.PROP_NAME, nodeName);
nodeRef = this.nodeService.createNode(parentRef, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName)),
typeDef.getName(), nodeProps).getChildRef();
}
}
return nodeRef;
}
}