Index: projects/repository/source/java/org/alfresco/repo/forms/processor/filter/RootCategoryFilter.java =================================================================== --- projects/repository/source/java/org/alfresco/repo/forms/processor/filter/RootCategoryFilter.java (revision 0) +++ projects/repository/source/java/org/alfresco/repo/forms/processor/filter/RootCategoryFilter.java (revision 0) @@ -0,0 +1,154 @@ +/** + * + */ +package org.alfresco.repo.forms.processor.filter; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +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.FormData.FieldData; +import org.alfresco.repo.forms.processor.AbstractFilter; +import org.alfresco.repo.forms.processor.AbstractFormProcessor; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.TypeDefinition; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.CategoryService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; + +/** + * This filter supports form-based creation of complex root categories by + * transparently handling the resolution of the classification root + * {@link NodeRef}. + * + * @author Axel Faust, PRODYNA AG + * + */ +public class RootCategoryFilter extends AbstractFilter { + + private static final String ALFRESCO_CATEGORY_ROOT = "alfresco://category/root"; + private static final String FIELD_ASPECT = "aspect"; + + protected NamespaceService namespaceService; + protected DictionaryService dictionaryService; + protected CategoryService categoryService; + protected NodeService nodeService; + + @Override + public void beforeGenerate(TypeDefinition item, List fields, + List forcedFields, Form form, Map context) { + // NO-OP + } + + @Override + public void afterGenerate(TypeDefinition item, List fields, + List forcedFields, Form form, Map context) { + // NO-OP + } + + @Override + public void beforePersist(final TypeDefinition item, final FormData data) { + final QName name = item.getName(); + + if (this.dictionaryService.isSubClass(name, ContentModel.TYPE_CATEGORY)) { + + final FieldData aspect = data.getFieldData(FIELD_ASPECT); + final FieldData destination = data + .getFieldData(AbstractFormProcessor.DESTINATION); + + if (destination != null && aspect != null) { + + final String destinationRef = (String) destination.getValue(); + if (ALFRESCO_CATEGORY_ROOT.equalsIgnoreCase(destinationRef)) { + // resolve the virtual NodeRef to the appropriate + // classification node + + final String aspectName = (String) aspect.getValue(); + final QName aspectQName = QName.createQName(aspectName, + this.namespaceService); + + final NodeRef classificationNode; + + // this is currently hard-wired to the "common" store + // TODO: Support multi-store category management + final Collection rootCategories = this.categoryService + .getRootCategories( + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, + aspectQName); + if (!rootCategories.isEmpty()) { + classificationNode = rootCategories.iterator().next() + .getParentRef(); + } else { + // determine classificationNode by creating a temporary + // root category + final NodeRef tempRootCategory = this.categoryService + .createRootCategory( + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, + aspectQName, "##temp##"); + this.nodeService.addAspect(tempRootCategory, + ContentModel.ASPECT_TEMPORARY, + Collections. emptyMap()); + + classificationNode = this.nodeService.getPrimaryParent( + tempRootCategory).getParentRef(); + + // delete the temporary root category + this.categoryService.deleteCategory(tempRootCategory); + } + + // update the destination to refer to the classificationNode + data.addFieldData(AbstractFormProcessor.DESTINATION, + classificationNode.toString(), true); + } + } + } + } + + @Override + public void afterPersist(TypeDefinition item, FormData data, + NodeRef persistedObject) { + // NO-OP + } + + /** + * @param namespaceService + * the namespaceService to set + */ + public void setNamespaceService(NamespaceService namespaceService) { + this.namespaceService = namespaceService; + } + + /** + * @param dictionaryService + * the dictionaryService to set + */ + public void setDictionaryService(DictionaryService dictionaryService) { + this.dictionaryService = dictionaryService; + } + + /** + * @param categoryService + * the categoryService to set + */ + public void setCategoryService(CategoryService categoryService) { + this.categoryService = categoryService; + } + + /** + * @param nodeService + * the nodeService to set + */ + public void setNodeService(NodeService nodeService) { + this.nodeService = nodeService; + } + +} Index: projects/repository/source/java/org/alfresco/repo/forms/processor/node/TypeFormProcessor.java =================================================================== --- projects/repository/source/java/org/alfresco/repo/forms/processor/node/TypeFormProcessor.java (revision 32329) +++ projects/repository/source/java/org/alfresco/repo/forms/processor/node/TypeFormProcessor.java (working copy) @@ -186,9 +186,13 @@ // always be retrieved by looking up the created node's parent data.removeFieldData(DESTINATION); - // TODO: determine what association to use when creating the node in - // the destination, - // defaults to ContentModel.ASSOC_CONTAINS + QName assoc = ContentModel.ASSOC_CONTAINS; + FieldData destinationAssoc = data.getFieldData(DESTINATION_ASSOC); + if (destinationAssoc != null) + { + assoc = QName.createQName((String)destinationAssoc.getValue(), this.namespaceService); + data.removeFieldData(DESTINATION_ASSOC); + } // if a name property is present in the form data use it as the node // name, @@ -213,7 +217,7 @@ nodeProps.put(ContentModel.PROP_NAME, nodeName); nodeRef = this.nodeService.createNode( parentRef, - ContentModel.ASSOC_CONTAINS, + assoc, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName)), typeDef.getName(), nodeProps).getChildRef(); } Index: projects/repository/source/java/org/alfresco/repo/forms/processor/AbstractFormProcessor.java =================================================================== --- projects/repository/source/java/org/alfresco/repo/forms/processor/AbstractFormProcessor.java (revision 32329) +++ projects/repository/source/java/org/alfresco/repo/forms/processor/AbstractFormProcessor.java (working copy) @@ -37,6 +37,8 @@ { public static final String DESTINATION = "alf_destination"; + public static final String DESTINATION_ASSOC = "alf_destinationAssoc"; + private static final Log logger = LogFactory.getLog(AbstractFormProcessor.class); protected FormProcessorRegistry processorRegistry; Index: projects/repository/config/alfresco/form-services-context.xml =================================================================== --- projects/repository/config/alfresco/form-services-context.xml (revision 32329) +++ projects/repository/config/alfresco/form-services-context.xml (working copy) @@ -109,6 +109,16 @@ ref="nodeFilterRegistry" /> --> + + + + + + + + Index: projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get.properties =================================================================== --- projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get.properties (revision 32329) +++ projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get.properties (working copy) @@ -1,4 +1,6 @@ ## Top-level Root Node node.root=Category Root -title.category-manager=Category Manager \ No newline at end of file +title.category-manager=Category Manager +create-category.title=Create Category +edit-category.title=Edit Category \ No newline at end of file Index: projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager-dialog.ftl =================================================================== --- projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager-dialog.ftl (revision 0) +++ projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager-dialog.ftl (revision 0) @@ -0,0 +1,48 @@ +<#if formUI == "true"> + <@formLib.renderFormsRuntime formId=formId /> + + +
+
+
+ +
+ + <#if form.showCaption?exists && form.showCaption> +
*${msg("form.required.fields")}
+ + +
+ + <#if form.mode == "create" && form.destination?? && form.destination?length > 0> + + + + <#if form.mode == "create" && form.destinationAssoc?? && form.destinationAssoc?length > 0> + + + + <#if args.aspect??> + + + +
+ <#list form.structure as item> + <#if item.kind == "set"> + <@formLib.renderSet set=item /> + <#else> + <@formLib.renderField field=form.fields[item.id] /> + + +
+ +
+ +   +
+ +
+ +
+
+
\ No newline at end of file Index: projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get_de.properties =================================================================== --- projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get_de.properties (revision 32329) +++ projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get_de.properties (working copy) @@ -1,4 +1,6 @@ ## Top-level Root Node node.root=Kategorie Root -title.category-manager=Kategorie-Manager \ No newline at end of file +title.category-manager=Kategorie-Manager +create-category.title=Kategorie anlegen +edit-category.title=Kategorie bearbeiten \ No newline at end of file Index: projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get.html.ftl =================================================================== --- projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get.html.ftl (revision 32329) +++ projects/slingshot/config/alfresco/site-webscripts/org/alfresco/components/console/category-manager.get.html.ftl (working copy) @@ -2,7 +2,17 @@