- Refactored low level form service to implement MOB-946 (add ability to do pre and post form processing)

- Added ignore patterns to new wdr-deployment project's build folder

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14558 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2009-06-05 14:09:34 +00:00
parent a3c3a40916
commit a269ac3298
10 changed files with 262 additions and 265 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -28,31 +28,31 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Abstract base class for all Handler implementations.
* Abstract base class for all Filter implementations.
*
* @author Gavin Cornwell
*/
public abstract class AbstractHandler implements Handler
public abstract class AbstractFilter implements Filter
{
private static final Log logger = LogFactory.getLog(AbstractHandler.class);
private static final Log logger = LogFactory.getLog(AbstractFilter.class);
protected HandlerRegistry handlerRegistry;
protected FilterRegistry filterRegistry;
protected boolean active = true;
/**
* Sets the handler registry
* Sets the filter registry
*
* @param handlerRegistry The FormProcessorHandlerRegistry instance
* @param filterRegistry The FilterRegistry instance
*/
public void setHandlerRegistry(HandlerRegistry handlerRegistry)
public void setFilterRegistry(FilterRegistry filterRegistry)
{
this.handlerRegistry = handlerRegistry;
this.filterRegistry = filterRegistry;
}
/**
* Sets whether this processor is active
* Sets whether this filter is active
*
* @param active true if the processor should be active
* @param active true if the filter should be active
*/
public void setActive(boolean active)
{
@@ -60,39 +60,30 @@ public abstract class AbstractHandler implements Handler
}
/**
* Registers this handler with the handler registry
* Registers this filter with the filter registry
*/
public void register()
{
if (handlerRegistry == null)
if (filterRegistry == null)
{
if (logger.isWarnEnabled())
logger.warn("Property 'handlerRegistry' has not been set. Ignoring auto-registration of handler: " + this);
logger.warn("Property 'filterRegistry' has not been set. Ignoring auto-registration of filter: " + this);
return;
}
// register this instance
handlerRegistry.addHandler(this);
filterRegistry.addFilter(this);
}
/*
* @see org.alfresco.repo.forms.processor.Handler#isActive()
* @see org.alfresco.repo.forms.processor.Filter#isActive()
*/
public boolean isActive()
{
return this.active;
}
/*
* @see org.alfresco.repo.forms.processor.Handler#isApplicable(java.lang.String)
*/
public boolean isApplicable(Object item)
{
// by default all handlers are applicable
return true;
}
/*
* @see java.lang.Object#toString()
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -30,57 +30,80 @@ import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData;
/**
* Interface definition for a handler which is used to process all or part
* of a form, if it is applicable to the item being processed and it's active
* Interface definition for a filter which is called before and after
* a form is generated and persisted.
*
* @author Gavin Cornwell
*/
public interface Handler
public interface Filter
{
/**
* Determines whether the handler is applicable for the given item.
* <p>
* Handlers all relating to the same type of form can cast the Object
* to a more appropriate object, for example all the Node based handlers
* can expect a NodeRef object and therefore cast to that.
* Determines whether the filter is active
*
* @param item An object representing the item to handle
* @return true if the handler is applicable
*/
public boolean isApplicable(Object item);
/**
* Determines whether the handler is active
*
* @return true if the handler is active
* @return true if the filter is active
*/
public boolean isActive();
/**
* Handles the generation of a Form.
* Callback used to indicate that a form is about to be generated for
* the given items and fields.
*
* <p>
* Handlers all relating to the same type of form can cast the Object
* NOTE: Filters all relating to the same type of form can cast the Object
* 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, List<String> fields, List<String> forcedFields, Form form);
public void beforeGenerate(Object item, List<String> fields, List<String> forcedFields, Form form);
/**
* Handles the persistence of form data for the given item.
* Callback used to indicate that a form has just been generated for
* the given items and fields.
*
* <p>
* Handlers all relating to the same type of form can cast the item Object
* NOTE: Filters all relating to the same type of form can cast the Object
* to a more appropriate object, for example all the Node based handlers
* can expect a NodeRef object and therefore cast to that.
*
* @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
*/
public void afterGenerate(Object item, List<String> fields, List<String> forcedFields, Form form);
/**
* Callback used to indicate that the given form data is about to be
* persisted for the given item.
*
* <p>
* NOTE: Filters all relating to the same type of form can cast the item Object
* to a more appropriate object, for example all the Node based handlers
* can expect a NodeRef object and therefore cast to that.
*
* @param item The item to persist the form data for
* @param data The form data
*/
public void handlePersist(Object item, FormData data);
public void beforePersist(Object item, FormData data);
/**
* Callback used to indicate that the given form data was just persisted
* for the item and the given persistedObject was created or modified.
*
* <p>
* NOTE: Filters all relating to the same type of form can cast the item
* and persistedObject Objects to a more appropriate object, for example
* all the Node based handlers can expect a NodeRef object and therefore
* cast to that.
*
* @param item The item to persist the form data for
* @param data The form data
* @param persistedObject The object created or modified as a result of
* the form persistence
*/
public void afterPersist(Object item, FormData data, Object persistedObject);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -31,70 +31,76 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Holds a list of handlers for a type of form processor, the handlers are called
* in sequence to check their applicability, if the handler applies to the item
* being processed it's generate or persist method is called.
*
* @see org.alfresco.repo.forms.processor.Handler
* Holds a list of filters for a type of form processor.
* <p>
* Each filter is called before and after the processor generates and
* persists the form, thus allowing the form and the effected objects
* to be manipulated prior to generation or persistence or after the
* fact.
* </p>
* <p>
* Each filter is responsible for determing whether it applies to the item
* being processed.
* </p>
*
* @see org.alfresco.repo.forms.processor.Filter
* @author Gavin Cornwell
*/
public class HandlerRegistry
public class FilterRegistry
{
private static final Log logger = LogFactory.getLog(HandlerRegistry.class);
private static final Log logger = LogFactory.getLog(FilterRegistry.class);
protected List<Handler> handlers;
protected List<Filter> filters;
/**
* Constructs the registry
*/
public HandlerRegistry()
public FilterRegistry()
{
this.handlers = new ArrayList<Handler>(4);
this.filters = new ArrayList<Filter>(4);
}
/**
* Registers a handler
* Registers a filter
*
* @param handler The Handler to regsiter
* @param filter The Filter to regsiter
*/
public void addHandler(Handler handler)
public void addFilter(Filter filter)
{
if (handler.isActive())
if (filter.isActive())
{
this.handlers.add(handler);
this.filters.add(filter);
if (logger.isDebugEnabled())
logger.debug("Registered handler: " + handler + " in register: " + this);
logger.debug("Registered filter: " + filter + " in register: " + this);
}
else if (logger.isWarnEnabled())
{
logger.warn("Ignored registration of handler " + handler + "as it was marked as inactive");
logger.warn("Ignored registration of filter " + filter + " as it was marked as inactive");
}
}
/**
* Returns a list of handlers applicable for the given item
* Returns a list of active filters
*
* @param item The item the form is being processed for
* @return List of applicable Handler objects
* @return List of active Filter objects
*/
public List<Handler> getApplicableHandlers(Object item)
public List<Filter> getFilters()
{
List<Handler> applicableHandlers = new ArrayList<Handler>(4);
List<Filter> activeFilters = new ArrayList<Filter>(4);
// iterate round the handlers and add each active applicable
// handler to the list
for (Handler handler : this.handlers)
// iterate round the filters and add each active filter to the list
for (Filter filter: this.filters)
{
if (handler.isActive() && handler.isApplicable(item))
if (filter.isActive())
{
applicableHandlers.add(handler);
activeFilters.add(filter);
}
}
if (logger.isDebugEnabled())
logger.debug("Returning applicable handlers: " + applicableHandlers);
logger.debug("Returning active filters: " + activeFilters);
return applicableHandlers;
return activeFilters;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -28,32 +28,30 @@ 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
* handler mechanism.
* filter mechanism.
*
* @author Gavin Cornwell
*/
public abstract class AbstractFormProcessorByHandlers extends AbstractFormProcessor
public abstract class FilteredFormProcessor extends AbstractFormProcessor
{
protected HandlerRegistry handlerRegistry;
protected FilterRegistry filterRegistry;
/**
* Sets the form processor handler registry
* Sets the filter registry
*
* @param handlerRegistry The FormProcessorHandlerRegistry instance
* @param filterRegistry The FilterRegistry instance
*/
public void setHandlerRegistry(HandlerRegistry handlerRegistry)
public void setFilterRegistry(FilterRegistry filterRegistry)
{
this.handlerRegistry = handlerRegistry;
this.filterRegistry = filterRegistry;
}
/**
* Generates a Form for the given item, constructed by calling each
* applicable registered handler
* Generates a Form for the given item.
*
* @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
@@ -63,21 +61,31 @@ public abstract class AbstractFormProcessorByHandlers extends AbstractFormProces
*/
public Form generate(Item item, List<String> fields, List<String> forcedFields)
{
if (this.handlerRegistry == null)
{
throw new FormException("Property 'handlerRegistry' has not been set.");
}
// get the typed object representing the item
Object typedItem = getTypedItem(item);
// create an empty Form
Form form = new Form(item);
// execute each applicable handler
for (Handler handler: this.handlerRegistry.getApplicableHandlers(typedItem))
// inform all regsitered filters the form is about to be generated
if (this.filterRegistry != null)
{
form = handler.handleGenerate(typedItem, fields, forcedFields, form);
for (Filter filter: this.filterRegistry.getFilters())
{
filter.beforeGenerate(typedItem, fields, forcedFields, form);
}
}
// perform the actual generation of the form
internalGenerate(typedItem, fields, forcedFields, form);
// inform all regsitered filters the form has been generated
if (this.filterRegistry != null)
{
for (Filter filter: this.filterRegistry.getFilters())
{
filter.afterGenerate(typedItem, fields, forcedFields, form);
}
}
return form;
@@ -93,18 +101,28 @@ public abstract class AbstractFormProcessorByHandlers extends AbstractFormProces
*/
public void persist(Item item, FormData data)
{
if (this.handlerRegistry == null)
{
throw new FormException("Property 'handlerRegistry' has not been set.");
}
// get the typed object representing the item
Object typedItem = getTypedItem(item);
// execute each applicable handler
for (Handler handler: this.handlerRegistry.getApplicableHandlers(typedItem))
// inform all regsitered filters the form is about to be persisted
if (this.filterRegistry != null)
{
handler.handlePersist(typedItem, data);
for (Filter filter: this.filterRegistry.getFilters())
{
filter.beforePersist(typedItem, data);
}
}
// perform the actual persistence of the form
Object persistedObject = internalPersist(typedItem, data);
// inform all regsitered filters the form has been persisted
if (this.filterRegistry != null)
{
for (Filter filter: this.filterRegistry.getFilters())
{
filter.afterPersist(typedItem, data, persistedObject);
}
}
}
@@ -119,4 +137,23 @@ public abstract class AbstractFormProcessorByHandlers extends AbstractFormProces
* @return The typed object
*/
protected abstract Object getTypedItem(Item item);
/**
* Generates the form.
*
* @param item The object 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 being generated
*/
protected abstract void internalGenerate(Object item, List<String> fields, List<String> forcedFields, Form form);
/**
* Persists the form data.
*
* @param item The object to persist the form for
* @param data The data to persist
* @return The object that got created or modified
*/
protected abstract Object internalPersist(Object item, FormData data);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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

View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) 2005-2008 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;
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
* for repository nodes.
*
* @author Gavin Cornwell
*/
public class NodeFormProcessor extends AbstractFormProcessorByHandlers
{
/** Logger */
private static Log logger = LogFactory.getLog(NodeFormProcessor.class);
/** Services */
protected NodeService nodeService;
/**
* Sets the node service
*
* @param nodeService The NodeService instance
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/*
* @see org.alfresco.repo.forms.processor.AbstractFormProcessorByHandlers#getTypedItem(org.alfresco.repo.forms.Item)
*/
@Override
protected Object getTypedItem(Item 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 FormNotFoundException(item,
new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef));
}
else
{
// all Node based handlers can expect to get a NodeRef
return nodeRef;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -22,7 +22,7 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.forms.processor;
package org.alfresco.repo.forms.processor.node;
import java.io.Serializable;
import java.util.ArrayList;
@@ -39,10 +39,13 @@ import org.alfresco.repo.forms.AssociationFieldDefinition;
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.PropertyFieldDefinition;
import org.alfresco.repo.forms.AssociationFieldDefinition.Direction;
import org.alfresco.repo.forms.FormData.FieldData;
import org.alfresco.repo.forms.PropertyFieldDefinition.FieldConstraint;
import org.alfresco.repo.forms.processor.FilteredFormProcessor;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
import org.alfresco.service.cmr.dictionary.Constraint;
@@ -57,6 +60,7 @@ import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.NamespaceService;
@@ -66,17 +70,16 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Handler to handle the generation and persistence of a Form object for a repository node.
* <p>
* This handler will add all properties (including those of any aspects applied) and
* associations of the node to the Form.
* FormProcessor implementation that can generate and persist Form objects
* for repository nodes.
*
* @author Gavin Cornwell
*/
public class NodeHandler extends AbstractHandler
public class NodeFormProcessor extends FilteredFormProcessor
{
private static final Log logger = LogFactory.getLog(NodeHandler.class);
/** Logger */
private static Log logger = LogFactory.getLog(NodeFormProcessor.class);
protected static final String ON = "on";
protected static final String PROP = "prop";
protected static final String ASSOC = "assoc";
@@ -163,11 +166,65 @@ public class NodeHandler extends AbstractHandler
{
this.namespaceService = namespaceService;
}
/*
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#getTypedItem(org.alfresco.repo.forms.Item)
*/
@Override
protected Object getTypedItem(Item 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 FormNotFoundException(item,
new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef));
}
else
{
// all Node based filters can expect to get a NodeRef
return nodeRef;
}
}
/*
* @see org.alfresco.repo.forms.processor.Handler#handleGenerate(java.lang.Object, java.util.List, java.util.List, org.alfresco.repo.forms.Form)
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#internalGenerate(java.lang.Object, java.util.List, java.util.List, org.alfresco.repo.forms.Form)
*/
public Form handleGenerate(Object item, List<String> fields, List<String> forcedFields, Form form)
@Override
protected void internalGenerate(Object item, List<String> fields, List<String> forcedFields, Form form)
{
if (logger.isDebugEnabled())
logger.debug("Generating form for: " + item);
@@ -179,11 +236,9 @@ public class NodeHandler extends AbstractHandler
generateNode(nodeRef, fields, forcedFields, form);
if (logger.isDebugEnabled())
logger.debug("Returning form: " + form);
return form;
logger.debug("Generated form: " + form);
}
/**
* Sets up the Form object for the given NodeRef
*
@@ -766,11 +821,12 @@ public class NodeHandler extends AbstractHandler
return assocValues;
}
/*
* @see org.alfresco.repo.forms.processor.FormProcessorHandler#handlePersist(java.lang.Object, org.alfresco.repo.forms.FormData)
* @see org.alfresco.repo.forms.processor.FilteredFormProcessor#internalPersist(java.lang.Object, org.alfresco.repo.forms.FormData)
*/
public void handlePersist(Object item, FormData data)
@Override
protected Object internalPersist(Object item, FormData data)
{
if (logger.isDebugEnabled())
logger.debug("Persisting form for: " + item);
@@ -780,6 +836,8 @@ public class NodeHandler extends AbstractHandler
// persist the node
persistNode(nodeRef, data);
return item;
}
/**
@@ -1361,4 +1419,4 @@ class RemoveChildAssocCommand extends AbstractAssocCommand
nodeService.removeChild(sourceNodeRef, targetNodeRef);
}
}
}