(fieldDefs.size());
+ for (FieldDefinition fieldDef : fieldDefs)
+ {
+ fieldDefMap.put(fieldDef.getName(), fieldDef);
+ }
+
+ // find the fields
+ PropertyFieldDefinition nameField = (PropertyFieldDefinition)fieldDefMap.get("cm:name");
+ PropertyFieldDefinition createdField = (PropertyFieldDefinition)fieldDefMap.get("cm:created");
+ PropertyFieldDefinition creatorField = (PropertyFieldDefinition)fieldDefMap.get("cm:creator");
+ PropertyFieldDefinition modifiedField = (PropertyFieldDefinition)fieldDefMap.get("cm:modified");
+ PropertyFieldDefinition modifierField = (PropertyFieldDefinition)fieldDefMap.get("cm:modifier");
+
+ // check fields are present
+ assertNotNull("Expecting to find the cm:name field", nameField);
+ assertNotNull("Expecting to find the cm:created field", createdField);
+ assertNotNull("Expecting to find the cm:creator field", creatorField);
+ assertNotNull("Expecting to find the cm:modified field", modifiedField);
+ assertNotNull("Expecting to find the cm:modifier field", modifierField);
+ }
+
public void testNoForm() throws Exception
{
// test that a form can not be retrieved for a non-existent item
diff --git a/source/java/org/alfresco/repo/forms/processor/node/NodeFormProcessor.java b/source/java/org/alfresco/repo/forms/processor/node/NodeFormProcessor.java
index 8085b3221f..fda1877605 100644
--- a/source/java/org/alfresco/repo/forms/processor/node/NodeFormProcessor.java
+++ b/source/java/org/alfresco/repo/forms/processor/node/NodeFormProcessor.java
@@ -26,6 +26,7 @@ package org.alfresco.repo.forms.processor.node;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -260,7 +261,7 @@ public class NodeFormProcessor extends FilteredFormProcessor
if (fields != null && fields.size() > 0)
{
- generateSelectedFields(nodeRef, fields, forcedFields, form);
+ generateSelectedFields(nodeRef, null, fields, forcedFields, form);
}
else
{
@@ -273,28 +274,52 @@ public class NodeFormProcessor extends FilteredFormProcessor
/**
* 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
+ *
+ * A NodeRef or TypeDefinition can be provided, however, if a NodeRef
+ * is provided all type information will be derived from the NodeRef
+ * and the TypeDefinition will be ignored.
+ *
+ * If any of the requested fields are not present on the type and
+ * they appear in the forcedFields list an attempt to find a model
* definition for those fields is made so they can be included.
+ *
*
- * @param nodeRef The NodeRef of the node being setup
+ * @param nodeRef The NodeRef of the item being generated
+ * @param typeDef The TypeDefiniton of the item being generated
* @param fields Restricted list of fields to include
* @param forcedFields List of field names that should be included
* even if the field is not currently present
* @param form The Form instance to populate
*/
- protected void generateSelectedFields(NodeRef nodeRef, List fields, List forcedFields, Form form)
+ protected void generateSelectedFields(NodeRef nodeRef, TypeDefinition typeDef,
+ List fields, List forcedFields, Form form)
{
+ // ensure a NodeRef or TypeDefinition is provided
+ if (nodeRef == null && typeDef == null)
+ {
+ throw new IllegalArgumentException("A NodeRef or TypeDefinition must be provided");
+ }
+
if (logger.isDebugEnabled())
logger.debug("Generating selected fields: " + fields + " and forcing: " + forcedFields);
- // get data dictionary definition for node
- QName type = this.nodeService.getType(nodeRef);
- TypeDefinition typeDef = this.dictionaryService.getAnonymousType(type,
- this.nodeService.getAspects(nodeRef));
+ // get data dictionary definition for node if it is provided
+ QName type = null;
+ Map propValues = Collections.emptyMap();
+
+ if (nodeRef != null)
+ {
+ type = this.nodeService.getType(nodeRef);
+ typeDef = this.dictionaryService.getAnonymousType(type, this.nodeService.getAspects(nodeRef));
+ propValues = this.nodeService.getProperties(nodeRef);
+ }
+ else
+ {
+ type = typeDef.getName();
+ }
+
Map propDefs = typeDef.getProperties();
- Map assocDefs = typeDef.getAssociations();
- Map propValues = this.nodeService.getProperties(nodeRef);
+ Map assocDefs = typeDef.getAssociations();
for (String fieldName : fields)
{
@@ -365,7 +390,8 @@ public class NodeFormProcessor extends FilteredFormProcessor
{
// generate the association field
generateAssociationField(assocDef,
- retrieveAssociationValues(nodeRef, assocDef), form);
+ (nodeRef != null) ? retrieveAssociationValues(nodeRef, assocDef) : null,
+ form);
foundField = true;
}
@@ -382,7 +408,8 @@ public class NodeFormProcessor extends FilteredFormProcessor
else if (logger.isDebugEnabled())
{
logger.debug("Ignoring field \"" + fieldName +
- "\" as it is not defined for the current node and it does not appear in the 'force' list");
+ "\" as it is not defined for the current " + ((nodeRef != null) ? "node" : "type") +
+ " and it does not appear in the 'force' list");
}
}
}
@@ -393,7 +420,7 @@ public class NodeFormProcessor extends FilteredFormProcessor
TRANSIENT_SIZE.equals(fieldName))
{
// if the node type is content or sublcass thereof generate appropriate field
- if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT))
+ if (nodeRef != null && this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT))
{
ContentData content = (ContentData)this.nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
if (content != null)
diff --git a/source/java/org/alfresco/repo/forms/processor/node/TypeFormProcessor.java b/source/java/org/alfresco/repo/forms/processor/node/TypeFormProcessor.java
new file mode 100644
index 0000000000..f47b770775
--- /dev/null
+++ b/source/java/org/alfresco/repo/forms/processor/node/TypeFormProcessor.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.forms.processor.node;
+
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.repo.forms.Form;
+import org.alfresco.repo.forms.FormData;
+import org.alfresco.repo.forms.FormNotFoundException;
+import org.alfresco.repo.forms.Item;
+import org.alfresco.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.namespace.InvalidQNameException;
+import org.alfresco.service.namespace.QName;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * FormProcessor implementation that can generate and persist Form objects
+ * for types in the Alfresco content model.
+ *
+ * @author Gavin Cornwell
+ */
+public class TypeFormProcessor extends NodeFormProcessor
+{
+ /** Logger */
+ private static Log logger = LogFactory.getLog(TypeFormProcessor.class);
+
+ @Override
+ protected Object getTypedItem(Item item)
+ {
+ TypeDefinition typeDef = null;
+
+ try
+ {
+ // convert the prefix type into full QName representation
+ // TODO: Also look for and deal with full QName as itemId
+ QName type = QName.createQName(item.getId(), this.namespaceService);
+
+ // retrieve the type from the dictionary
+ typeDef = this.dictionaryService.getType(type);
+
+ if (typeDef == null)
+ {
+ throw new FormNotFoundException(item,
+ new IllegalArgumentException("Type does not exist: " + item.getId()));
+ }
+ }
+ catch (InvalidQNameException iqne)
+ {
+ throw new FormNotFoundException(item, iqne);
+ }
+
+ // return the type definition object for the requested type
+ return typeDef;
+ }
+
+ @Override
+ protected void internalGenerate(Object item, List fields, List forcedFields, Form form)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Generating form for item: " + item);
+
+ // cast to the expected NodeRef representation
+ TypeDefinition typeDef = (TypeDefinition)item;
+
+ // generate the form for the node
+ generateType(typeDef, fields, forcedFields, form);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Generating form: " + form);
+ }
+
+ /**
+ * 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 generateType(TypeDefinition typeDef, List fields, List forcedFields, Form form)
+ {
+ // set the type and URL of the item
+ form.getItem().setType(typeDef.getName().toPrefixString(this.namespaceService));
+ form.getItem().setUrl("/api/classes/" + typeDef.getName().toPrefixString(this.namespaceService).replace(":", "_"));
+
+ if (fields != null && fields.size() > 0)
+ {
+ generateSelectedFields(null, typeDef, fields, forcedFields, form);
+ }
+ else
+ {
+ // setup field definitions and data
+ generateAllPropertyFields(typeDef, form);
+ generateAllAssociationFields(typeDef, form);
+ }
+ }
+
+ /**
+ * Sets up the field definitions for all the type's properties.
+ *
+ * @param typeDef The type being setup
+ * @param form The Form instance to populate
+ */
+ protected void generateAllPropertyFields(TypeDefinition typeDef, Form form)
+ {
+ // iterate round the property defintions and setup field definition
+ Map propDefs = typeDef.getProperties();
+ for (PropertyDefinition propDef : propDefs.values())
+ {
+ generatePropertyField(propDef, null, form);
+ }
+
+ // get all default aspects for the type and iterate round their
+ // property definitions too
+ List aspects = typeDef.getDefaultAspects(true);
+ for (AspectDefinition aspect : aspects)
+ {
+ propDefs = aspect.getProperties();
+ for (PropertyDefinition propDef : propDefs.values())
+ {
+ generatePropertyField(propDef, null, form);
+ }
+ }
+ }
+
+ /**
+ * Sets up the field definitions for all the type's associations.
+ *
+ * @param typeDef The type being setup
+ * @param form The Form instance to populate
+ */
+ protected void generateAllAssociationFields(TypeDefinition typeDef, Form form)
+ {
+ // iterate round the association defintions and setup field definition
+ Map assocDefs = typeDef.getAssociations();
+ for (AssociationDefinition assocDef : assocDefs.values())
+ {
+ this.generateAssociationField(assocDef, null, form);
+ }
+
+ // get all default aspects for the type and iterate round their
+ // association definitions too
+ List aspects = typeDef.getDefaultAspects(true);
+ for (AspectDefinition aspect : aspects)
+ {
+ assocDefs = aspect.getAssociations();
+ for (AssociationDefinition assocDef : assocDefs.values())
+ {
+ this.generateAssociationField(assocDef, null, form);
+ }
+ }
+ }
+
+ @Override
+ protected Object internalPersist(Object item, FormData data)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Persisting form for: " + item);
+
+ // 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!");
+
+ return item;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/forms/script/ScriptForm.java b/source/java/org/alfresco/repo/forms/script/ScriptForm.java
index 6093be3646..c91bb2a01d 100644
--- a/source/java/org/alfresco/repo/forms/script/ScriptForm.java
+++ b/source/java/org/alfresco/repo/forms/script/ScriptForm.java
@@ -51,8 +51,13 @@ public class ScriptForm implements Serializable
this.form = formObject;
fieldDefinitionData = new HashMap();
- for (FieldDefinition fd : form.getFieldDefinitions()) {
- fieldDefinitionData.put(fd.getName(), fd);
+ List fieldDefs = form.getFieldDefinitions();
+ if (fieldDefs != null)
+ {
+ for (FieldDefinition fd : fieldDefs)
+ {
+ fieldDefinitionData.put(fd.getName(), fd);
+ }
}
}
diff --git a/source/java/org/alfresco/repo/forms/script/ScriptFormData.java b/source/java/org/alfresco/repo/forms/script/ScriptFormData.java
index cb0e87eaba..2665d04e65 100644
--- a/source/java/org/alfresco/repo/forms/script/ScriptFormData.java
+++ b/source/java/org/alfresco/repo/forms/script/ScriptFormData.java
@@ -51,10 +51,13 @@ public class ScriptFormData implements Serializable
public ScriptableHashMap getData()
{
ScriptableHashMap result = new ScriptableHashMap();
- for (String k : formData.getData().keySet())
+ if (this.formData != null)
{
- ScriptFieldData wrappedFieldData = new ScriptFieldData(formData.getData().get(k));
- result.put(k, wrappedFieldData);
+ for (String k : formData.getData().keySet())
+ {
+ ScriptFieldData wrappedFieldData = new ScriptFieldData(formData.getData().get(k));
+ result.put(k, wrappedFieldData);
+ }
}
return result;
}