mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-08 14:51:49 +00:00
Merged 5.1.N (5.1.2) to 5.2.N (5.2.1)
125605 rmunteanu: Merged 5.1.1 (5.1.1) to 5.1.N (5.1.2) 125498 slanglois: MNT-16155 Update source headers - remove svn:eol-style property on Java and JSP source files git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@125783 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,121 +1,121 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.cmr.security.AccessPermission;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
|
||||
/**
|
||||
* Base class for Template API objects that support permissions.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BasePermissionsNode extends BaseContentNode implements TemplatePermissions
|
||||
{
|
||||
private List<String> permissions = null;
|
||||
private List<String> directPermissions = null;
|
||||
private List<String> fullPermissions = null;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Security API
|
||||
|
||||
/**
|
||||
* @return List of permissions applied to this Node, including inherited.
|
||||
* Strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION for example
|
||||
* ALLOWED;kevinr;Consumer so can be easily tokenized on the ';' character.
|
||||
*/
|
||||
public List<String> getPermissions()
|
||||
{
|
||||
if (this.permissions == null)
|
||||
{
|
||||
this.permissions = retrieveAllSetPermissions(false, false);
|
||||
}
|
||||
return this.permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of permissions applied to this Node (does not include inherited).
|
||||
* Strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION for example
|
||||
* ALLOWED;kevinr;Consumer so can be easily tokenized on the ';' character.
|
||||
*/
|
||||
public List<String> getDirectPermissions()
|
||||
{
|
||||
if (this.directPermissions == null)
|
||||
{
|
||||
this.directPermissions = retrieveAllSetPermissions(true, false);
|
||||
}
|
||||
return this.directPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of permissions applied to this Node, including inherited.
|
||||
* Strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION;[INHERITED|DIRECT] for example
|
||||
* ALLOWED;kevinr;Consumer so can be easily tokenized on the ';' character.
|
||||
*/
|
||||
public List<String> getFullPermissions()
|
||||
{
|
||||
if (this.fullPermissions == null)
|
||||
{
|
||||
this.fullPermissions = retrieveAllSetPermissions(false, true);
|
||||
}
|
||||
return this.fullPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to construct the response object for the various getPermissions() calls.
|
||||
*
|
||||
* @param direct True to only retrieve direct permissions, false to get inherited also
|
||||
* @param full True to retrieve full data string with [INHERITED|DIRECT] element
|
||||
* This exists to maintain backward compatibility with existing permission APIs.
|
||||
*
|
||||
* @return List<String> of permissions.
|
||||
*/
|
||||
private List<String> retrieveAllSetPermissions(boolean direct, boolean full)
|
||||
{
|
||||
String userName = this.services.getAuthenticationService().getCurrentUserName();
|
||||
List<String> permissions = new ArrayList<String>(4);
|
||||
if (hasPermission(PermissionService.READ_PERMISSIONS))
|
||||
{
|
||||
Set<AccessPermission> acls = this.services.getPermissionService().getAllSetPermissions(getNodeRef());
|
||||
for (AccessPermission permission : acls)
|
||||
{
|
||||
if (!direct || permission.isSetDirectly())
|
||||
{
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
buf.append(permission.getAccessStatus())
|
||||
.append(';')
|
||||
.append(permission.getAuthority())
|
||||
.append(';')
|
||||
.append(permission.getPermission());
|
||||
if (full)
|
||||
{
|
||||
buf.append(';').append(permission.isSetDirectly() ? "DIRECT" : "INHERITED");
|
||||
}
|
||||
permissions.add(buf.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this node inherits permissions from its parent node, false otherwise.
|
||||
*/
|
||||
public boolean getInheritsPermissions()
|
||||
{
|
||||
return this.services.getPermissionService().getInheritParentPermissions(getNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param permission Permission name to test
|
||||
*
|
||||
* @return true if the current user is granted the specified permission on the node
|
||||
*/
|
||||
public boolean hasPermission(String permission)
|
||||
{
|
||||
return (this.services.getPermissionService().hasPermission(getNodeRef(), permission) == AccessStatus.ALLOWED);
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.cmr.security.AccessPermission;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
|
||||
/**
|
||||
* Base class for Template API objects that support permissions.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BasePermissionsNode extends BaseContentNode implements TemplatePermissions
|
||||
{
|
||||
private List<String> permissions = null;
|
||||
private List<String> directPermissions = null;
|
||||
private List<String> fullPermissions = null;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Security API
|
||||
|
||||
/**
|
||||
* @return List of permissions applied to this Node, including inherited.
|
||||
* Strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION for example
|
||||
* ALLOWED;kevinr;Consumer so can be easily tokenized on the ';' character.
|
||||
*/
|
||||
public List<String> getPermissions()
|
||||
{
|
||||
if (this.permissions == null)
|
||||
{
|
||||
this.permissions = retrieveAllSetPermissions(false, false);
|
||||
}
|
||||
return this.permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of permissions applied to this Node (does not include inherited).
|
||||
* Strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION for example
|
||||
* ALLOWED;kevinr;Consumer so can be easily tokenized on the ';' character.
|
||||
*/
|
||||
public List<String> getDirectPermissions()
|
||||
{
|
||||
if (this.directPermissions == null)
|
||||
{
|
||||
this.directPermissions = retrieveAllSetPermissions(true, false);
|
||||
}
|
||||
return this.directPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of permissions applied to this Node, including inherited.
|
||||
* Strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION;[INHERITED|DIRECT] for example
|
||||
* ALLOWED;kevinr;Consumer so can be easily tokenized on the ';' character.
|
||||
*/
|
||||
public List<String> getFullPermissions()
|
||||
{
|
||||
if (this.fullPermissions == null)
|
||||
{
|
||||
this.fullPermissions = retrieveAllSetPermissions(false, true);
|
||||
}
|
||||
return this.fullPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to construct the response object for the various getPermissions() calls.
|
||||
*
|
||||
* @param direct True to only retrieve direct permissions, false to get inherited also
|
||||
* @param full True to retrieve full data string with [INHERITED|DIRECT] element
|
||||
* This exists to maintain backward compatibility with existing permission APIs.
|
||||
*
|
||||
* @return List<String> of permissions.
|
||||
*/
|
||||
private List<String> retrieveAllSetPermissions(boolean direct, boolean full)
|
||||
{
|
||||
String userName = this.services.getAuthenticationService().getCurrentUserName();
|
||||
List<String> permissions = new ArrayList<String>(4);
|
||||
if (hasPermission(PermissionService.READ_PERMISSIONS))
|
||||
{
|
||||
Set<AccessPermission> acls = this.services.getPermissionService().getAllSetPermissions(getNodeRef());
|
||||
for (AccessPermission permission : acls)
|
||||
{
|
||||
if (!direct || permission.isSetDirectly())
|
||||
{
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
buf.append(permission.getAccessStatus())
|
||||
.append(';')
|
||||
.append(permission.getAuthority())
|
||||
.append(';')
|
||||
.append(permission.getPermission());
|
||||
if (full)
|
||||
{
|
||||
buf.append(';').append(permission.isSetDirectly() ? "DIRECT" : "INHERITED");
|
||||
}
|
||||
permissions.add(buf.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this node inherits permissions from its parent node, false otherwise.
|
||||
*/
|
||||
public boolean getInheritsPermissions()
|
||||
{
|
||||
return this.services.getPermissionService().getInheritParentPermissions(getNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param permission Permission name to test
|
||||
*
|
||||
* @return true if the current user is granted the specified permission on the node
|
||||
*/
|
||||
public boolean hasPermission(String permission)
|
||||
{
|
||||
return (this.services.getPermissionService().hasPermission(getNodeRef(), permission) == AccessStatus.ALLOWED);
|
||||
}
|
||||
}
|
||||
|
@@ -1,85 +1,85 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
|
||||
/**
|
||||
* Class providing the base Search Query services to execute a search returning a list of TemplateNode objects from a Lucene search string.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseSearchResultsMap extends BaseTemplateMap
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent
|
||||
* The parent TemplateNode to execute searches from
|
||||
* @param services
|
||||
* The ServiceRegistry to use
|
||||
*/
|
||||
public BaseSearchResultsMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(parent, services);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a SearchService query with the given Lucene search string
|
||||
*/
|
||||
protected List<TemplateNode> query(String search)
|
||||
{
|
||||
List<TemplateNode> nodes = null;
|
||||
HashSet<NodeRef> nodeRefs = new HashSet<NodeRef>();
|
||||
|
||||
// check if a full Lucene search string has been supplied or extracted from XML
|
||||
if (search != null && search.length() != 0)
|
||||
{
|
||||
// perform the search against the repo
|
||||
ResultSet results = null;
|
||||
try
|
||||
{
|
||||
results = this.services.getSearchService().query(this.parent.getNodeRef().getStoreRef(),
|
||||
SearchService.LANGUAGE_LUCENE, search);
|
||||
|
||||
if (results.length() != 0)
|
||||
{
|
||||
NodeService nodeService = this.services.getNodeService();
|
||||
|
||||
nodes = new ArrayList<TemplateNode>(results.length());
|
||||
for (ResultSetRow row : results)
|
||||
{
|
||||
NodeRef nodeRef = row.getNodeRef();
|
||||
if (!nodeRefs.contains(nodeRef) && (nodeService.exists(nodeRef)))
|
||||
{
|
||||
nodes.add(new TemplateNode(nodeRef, services, this.parent.getImageResolver()));
|
||||
nodeRefs.add(nodeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to execute search: " + search, err);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (results != null)
|
||||
{
|
||||
results.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes != null ? nodes : (List) Collections.emptyList();
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
|
||||
/**
|
||||
* Class providing the base Search Query services to execute a search returning a list of TemplateNode objects from a Lucene search string.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseSearchResultsMap extends BaseTemplateMap
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent
|
||||
* The parent TemplateNode to execute searches from
|
||||
* @param services
|
||||
* The ServiceRegistry to use
|
||||
*/
|
||||
public BaseSearchResultsMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(parent, services);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a SearchService query with the given Lucene search string
|
||||
*/
|
||||
protected List<TemplateNode> query(String search)
|
||||
{
|
||||
List<TemplateNode> nodes = null;
|
||||
HashSet<NodeRef> nodeRefs = new HashSet<NodeRef>();
|
||||
|
||||
// check if a full Lucene search string has been supplied or extracted from XML
|
||||
if (search != null && search.length() != 0)
|
||||
{
|
||||
// perform the search against the repo
|
||||
ResultSet results = null;
|
||||
try
|
||||
{
|
||||
results = this.services.getSearchService().query(this.parent.getNodeRef().getStoreRef(),
|
||||
SearchService.LANGUAGE_LUCENE, search);
|
||||
|
||||
if (results.length() != 0)
|
||||
{
|
||||
NodeService nodeService = this.services.getNodeService();
|
||||
|
||||
nodes = new ArrayList<TemplateNode>(results.length());
|
||||
for (ResultSetRow row : results)
|
||||
{
|
||||
NodeRef nodeRef = row.getNodeRef();
|
||||
if (!nodeRefs.contains(nodeRef) && (nodeService.exists(nodeRef)))
|
||||
{
|
||||
nodes.add(new TemplateNode(nodeRef, services, this.parent.getImageResolver()));
|
||||
nodeRefs.add(nodeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to execute search: " + search, err);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (results != null)
|
||||
{
|
||||
results.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes != null ? nodes : (List) Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
@@ -1,35 +1,35 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* An abstract Map class that can be used process the parent Node as part of the get()
|
||||
* Map interface implementation.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseTemplateMap extends HashMap implements Cloneable
|
||||
{
|
||||
protected TemplateNode parent;
|
||||
protected ServiceRegistry services = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent The parent TemplateNode to execute searches from
|
||||
* @param services The ServiceRegistry to use
|
||||
*/
|
||||
public BaseTemplateMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(1, 1.0f);
|
||||
this.services = services;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#get(java.lang.Object)
|
||||
*/
|
||||
public abstract Object get(Object key);
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* An abstract Map class that can be used process the parent Node as part of the get()
|
||||
* Map interface implementation.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseTemplateMap extends HashMap implements Cloneable
|
||||
{
|
||||
protected TemplateNode parent;
|
||||
protected ServiceRegistry services = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent The parent TemplateNode to execute searches from
|
||||
* @param services The ServiceRegistry to use
|
||||
*/
|
||||
public BaseTemplateMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(1, 1.0f);
|
||||
this.services = services;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#get(java.lang.Object)
|
||||
*/
|
||||
public abstract Object get(Object key);
|
||||
}
|
||||
|
@@ -1,34 +1,34 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.repo.processor.BaseProcessorExtension;
|
||||
import org.alfresco.service.cmr.repository.TemplateProcessorExtension;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
|
||||
/**
|
||||
* Abstract base class for a template extension implementation
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
@AlfrescoPublicApi
|
||||
public abstract class BaseTemplateProcessorExtension extends BaseProcessorExtension implements TemplateProcessorExtension
|
||||
{
|
||||
/** The TemplateImageResolver for the current template execution thread */
|
||||
private ThreadLocal<TemplateImageResolver> resolver = new ThreadLocal<TemplateImageResolver>();
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.repository.TemplateProcessorExtension#setTemplateImageResolver(org.alfresco.service.cmr.repository.TemplateImageResolver)
|
||||
*/
|
||||
public void setTemplateImageResolver(TemplateImageResolver resolver)
|
||||
{
|
||||
this.resolver.set(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.repository.TemplateProcessorExtension#getTemplateImageResolver()
|
||||
*/
|
||||
public TemplateImageResolver getTemplateImageResolver()
|
||||
{
|
||||
return this.resolver.get();
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.repo.processor.BaseProcessorExtension;
|
||||
import org.alfresco.service.cmr.repository.TemplateProcessorExtension;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
|
||||
/**
|
||||
* Abstract base class for a template extension implementation
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
@AlfrescoPublicApi
|
||||
public abstract class BaseTemplateProcessorExtension extends BaseProcessorExtension implements TemplateProcessorExtension
|
||||
{
|
||||
/** The TemplateImageResolver for the current template execution thread */
|
||||
private ThreadLocal<TemplateImageResolver> resolver = new ThreadLocal<TemplateImageResolver>();
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.repository.TemplateProcessorExtension#setTemplateImageResolver(org.alfresco.service.cmr.repository.TemplateImageResolver)
|
||||
*/
|
||||
public void setTemplateImageResolver(TemplateImageResolver resolver)
|
||||
{
|
||||
this.resolver.set(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.repository.TemplateProcessorExtension#getTemplateImageResolver()
|
||||
*/
|
||||
public TemplateImageResolver getTemplateImageResolver()
|
||||
{
|
||||
return this.resolver.get();
|
||||
}
|
||||
}
|
||||
|
@@ -1,66 +1,66 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.processor.BaseProcessorExtension;
|
||||
import org.alfresco.repo.template.BaseContentNode.TemplateContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateNumberModel;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*
|
||||
* FreeMarker custom method to return the first N characters of a content stream.
|
||||
* <p>
|
||||
* Usage: String cropContent(TemplateContentData content, int length)
|
||||
*/
|
||||
public final class CropContentMethod extends BaseProcessorExtension implements TemplateMethodModelEx
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(CropContentMethod.class);
|
||||
/**
|
||||
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)
|
||||
*/
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
String result = null;
|
||||
|
||||
if (args.size() == 2)
|
||||
{
|
||||
Object arg0 = args.get(0);
|
||||
Object arg1 = args.get(1);
|
||||
|
||||
if (arg0 instanceof BeanModel && arg1 instanceof TemplateNumberModel)
|
||||
{
|
||||
Object wrapped = ((BeanModel)arg0).getWrappedObject();
|
||||
if (wrapped instanceof TemplateContentData)
|
||||
{
|
||||
int bytes = ((TemplateNumberModel)arg1).getAsNumber().intValue();
|
||||
|
||||
try
|
||||
{
|
||||
result = ((TemplateContentData)wrapped).getContentAsText(bytes);
|
||||
}
|
||||
catch (ContentIOException e)
|
||||
{
|
||||
logger.warn("unable to getContentAsText", e);
|
||||
/*
|
||||
* Unable to extract content - return empty text instead.
|
||||
* Probably here through a transformation failure.
|
||||
* This method is called from FreeMarker so throwing the
|
||||
* exception causes problems.
|
||||
*/
|
||||
result = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result != null ? result : "";
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.processor.BaseProcessorExtension;
|
||||
import org.alfresco.repo.template.BaseContentNode.TemplateContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateNumberModel;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*
|
||||
* FreeMarker custom method to return the first N characters of a content stream.
|
||||
* <p>
|
||||
* Usage: String cropContent(TemplateContentData content, int length)
|
||||
*/
|
||||
public final class CropContentMethod extends BaseProcessorExtension implements TemplateMethodModelEx
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(CropContentMethod.class);
|
||||
/**
|
||||
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)
|
||||
*/
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
String result = null;
|
||||
|
||||
if (args.size() == 2)
|
||||
{
|
||||
Object arg0 = args.get(0);
|
||||
Object arg1 = args.get(1);
|
||||
|
||||
if (arg0 instanceof BeanModel && arg1 instanceof TemplateNumberModel)
|
||||
{
|
||||
Object wrapped = ((BeanModel)arg0).getWrappedObject();
|
||||
if (wrapped instanceof TemplateContentData)
|
||||
{
|
||||
int bytes = ((TemplateNumberModel)arg1).getAsNumber().intValue();
|
||||
|
||||
try
|
||||
{
|
||||
result = ((TemplateContentData)wrapped).getContentAsText(bytes);
|
||||
}
|
||||
catch (ContentIOException e)
|
||||
{
|
||||
logger.warn("unable to getContentAsText", e);
|
||||
/*
|
||||
* Unable to extract content - return empty text instead.
|
||||
* Probably here through a transformation failure.
|
||||
* This method is called from FreeMarker so throwing the
|
||||
* exception causes problems.
|
||||
*/
|
||||
result = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result != null ? result : "";
|
||||
}
|
||||
}
|
||||
|
@@ -1,41 +1,41 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import freemarker.template.TemplateDateModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateNumberModel;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class DateIncrementMethod extends BaseTemplateProcessorExtension implements TemplateMethodModelEx
|
||||
{
|
||||
/**
|
||||
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)
|
||||
*/
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
Date result = null;
|
||||
|
||||
if (args.size() == 2)
|
||||
{
|
||||
Object arg0 = args.get(0);
|
||||
Object arg1 = args.get(1);
|
||||
|
||||
if (arg0 instanceof TemplateDateModel && arg1 instanceof TemplateNumberModel)
|
||||
{
|
||||
Date origionalDate = (Date)((TemplateDateModel)arg0).getAsDate();
|
||||
Number number = ((TemplateNumberModel)arg1).getAsNumber();
|
||||
long increment = number.longValue();
|
||||
|
||||
long modified = origionalDate.getTime() + increment;
|
||||
result = new Date(modified);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import freemarker.template.TemplateDateModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateNumberModel;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class DateIncrementMethod extends BaseTemplateProcessorExtension implements TemplateMethodModelEx
|
||||
{
|
||||
/**
|
||||
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)
|
||||
*/
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
Date result = null;
|
||||
|
||||
if (args.size() == 2)
|
||||
{
|
||||
Object arg0 = args.get(0);
|
||||
Object arg1 = args.get(1);
|
||||
|
||||
if (arg0 instanceof TemplateDateModel && arg1 instanceof TemplateNumberModel)
|
||||
{
|
||||
Date origionalDate = (Date)((TemplateDateModel)arg0).getAsDate();
|
||||
Number number = ((TemplateNumberModel)arg1).getAsNumber();
|
||||
long increment = number.longValue();
|
||||
|
||||
long modified = origionalDate.getTime() + increment;
|
||||
result = new Date(modified);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -1,54 +1,54 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateScalarModel;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*
|
||||
* Custom FreeMarker Template language method.
|
||||
* <p>
|
||||
* Method returns whether the current user is granted a particular permission a the TemplateNode.
|
||||
* <p>
|
||||
* Usage: hasPermission(TemplateNode node, String permission) - 1 on true, 0 on false
|
||||
*/
|
||||
public class HasPermissionMethod extends BaseTemplateProcessorExtension implements TemplateMethodModelEx
|
||||
{
|
||||
/**
|
||||
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)
|
||||
*/
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (args.size() == 2)
|
||||
{
|
||||
// arg 0 must be a wrapped TemplateNode object
|
||||
BeanModel arg0 = (BeanModel)args.get(0);
|
||||
|
||||
// arg 1 must be a String permission name
|
||||
String permission;
|
||||
Object arg1 = args.get(1);
|
||||
if (arg1 instanceof TemplateScalarModel)
|
||||
{
|
||||
permission = ((TemplateScalarModel)arg1).getAsString();
|
||||
|
||||
if (arg0.getWrappedObject() instanceof TemplateNode)
|
||||
{
|
||||
// test to see if this node has the permission
|
||||
if ( ((TemplateNode)arg0.getWrappedObject()).hasPermission(permission) )
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Integer.valueOf(result);
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateScalarModel;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*
|
||||
* Custom FreeMarker Template language method.
|
||||
* <p>
|
||||
* Method returns whether the current user is granted a particular permission a the TemplateNode.
|
||||
* <p>
|
||||
* Usage: hasPermission(TemplateNode node, String permission) - 1 on true, 0 on false
|
||||
*/
|
||||
public class HasPermissionMethod extends BaseTemplateProcessorExtension implements TemplateMethodModelEx
|
||||
{
|
||||
/**
|
||||
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)
|
||||
*/
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (args.size() == 2)
|
||||
{
|
||||
// arg 0 must be a wrapped TemplateNode object
|
||||
BeanModel arg0 = (BeanModel)args.get(0);
|
||||
|
||||
// arg 1 must be a String permission name
|
||||
String permission;
|
||||
Object arg1 = args.get(1);
|
||||
if (arg1 instanceof TemplateScalarModel)
|
||||
{
|
||||
permission = ((TemplateScalarModel)arg1).getAsString();
|
||||
|
||||
if (arg0.getWrappedObject() instanceof TemplateNode)
|
||||
{
|
||||
// test to see if this node has the permission
|
||||
if ( ((TemplateNode)arg0.getWrappedObject()).hasPermission(permission) )
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Integer.valueOf(result);
|
||||
}
|
||||
}
|
||||
|
@@ -1,48 +1,48 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.extensions.surf.util.ISO8601DateFormat;
|
||||
|
||||
import freemarker.template.TemplateDateModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateScalarModel;
|
||||
|
||||
/**
|
||||
* @author David Caruana
|
||||
* @author Kevin Roast
|
||||
*
|
||||
* Custom FreeMarker Template language method.
|
||||
* <p>
|
||||
* Render Date to ISO8601 format.<br>
|
||||
* Or parse ISO6801 format string date to a Date object.
|
||||
* <p>
|
||||
* Usage: xmldate(Date date)
|
||||
* xmldate(String date)
|
||||
*/
|
||||
public class ISO8601DateFormatMethod extends BaseTemplateProcessorExtension implements TemplateMethodModelEx
|
||||
{
|
||||
/**
|
||||
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)
|
||||
*/
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
Object result = null;
|
||||
|
||||
if (args.size() == 1)
|
||||
{
|
||||
Object arg0 = args.get(0);
|
||||
if (arg0 instanceof TemplateDateModel)
|
||||
{
|
||||
result = ISO8601DateFormat.format(((TemplateDateModel)arg0).getAsDate());
|
||||
}
|
||||
else if (arg0 instanceof TemplateScalarModel)
|
||||
{
|
||||
result = ISO8601DateFormat.parse(((TemplateScalarModel)arg0).getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
return result != null ? result : "";
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.extensions.surf.util.ISO8601DateFormat;
|
||||
|
||||
import freemarker.template.TemplateDateModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateScalarModel;
|
||||
|
||||
/**
|
||||
* @author David Caruana
|
||||
* @author Kevin Roast
|
||||
*
|
||||
* Custom FreeMarker Template language method.
|
||||
* <p>
|
||||
* Render Date to ISO8601 format.<br>
|
||||
* Or parse ISO6801 format string date to a Date object.
|
||||
* <p>
|
||||
* Usage: xmldate(Date date)
|
||||
* xmldate(String date)
|
||||
*/
|
||||
public class ISO8601DateFormatMethod extends BaseTemplateProcessorExtension implements TemplateMethodModelEx
|
||||
{
|
||||
/**
|
||||
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)
|
||||
*/
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
Object result = null;
|
||||
|
||||
if (args.size() == 1)
|
||||
{
|
||||
Object arg0 = args.get(0);
|
||||
if (arg0 instanceof TemplateDateModel)
|
||||
{
|
||||
result = ISO8601DateFormat.format(((TemplateDateModel)arg0).getAsDate());
|
||||
}
|
||||
else if (arg0 instanceof TemplateScalarModel)
|
||||
{
|
||||
result = ISO8601DateFormat.parse(((TemplateScalarModel)arg0).getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
return result != null ? result : "";
|
||||
}
|
||||
}
|
@@ -1,40 +1,40 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.SAXReader;
|
||||
|
||||
/**
|
||||
* Provides functionality to execute a Lucene search string and return TemplateNode objects.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class LuceneSearchResultsMap extends BaseSearchResultsMap
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent The parent TemplateNode to execute searches from
|
||||
* @param services The ServiceRegistry to use
|
||||
*/
|
||||
public LuceneSearchResultsMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(parent, services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
// execute the search
|
||||
return query(key.toString());
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.SAXReader;
|
||||
|
||||
/**
|
||||
* Provides functionality to execute a Lucene search string and return TemplateNode objects.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class LuceneSearchResultsMap extends BaseSearchResultsMap
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent The parent TemplateNode to execute searches from
|
||||
* @param services The ServiceRegistry to use
|
||||
*/
|
||||
public LuceneSearchResultsMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(parent, services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
// execute the search
|
||||
return query(key.toString());
|
||||
}
|
||||
}
|
||||
|
@@ -1,37 +1,37 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* Provides functionality to execute a Lucene search for a single node by NodeRef.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class NodeSearchResultsMap extends BaseSearchResultsMap
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent The parent TemplateNode to execute searches from
|
||||
* @param services The ServiceRegistry to use
|
||||
*/
|
||||
public NodeSearchResultsMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(parent, services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
TemplateNode result = null;
|
||||
if (key != null)
|
||||
{
|
||||
NodeRef nodeRef = new NodeRef((String)key);
|
||||
result = new TemplateNode(nodeRef, services, this.parent.getImageResolver());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* Provides functionality to execute a Lucene search for a single node by NodeRef.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class NodeSearchResultsMap extends BaseSearchResultsMap
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent The parent TemplateNode to execute searches from
|
||||
* @param services The ServiceRegistry to use
|
||||
*/
|
||||
public NodeSearchResultsMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(parent, services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
TemplateNode result = null;
|
||||
if (key != null)
|
||||
{
|
||||
NodeRef nodeRef = new NodeRef((String)key);
|
||||
result = new TemplateNode(nodeRef, services, this.parent.getImageResolver());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -1,334 +1,334 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authority.AuthorityDAO;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
import org.alfresco.util.ValueDerivingMapFactory;
|
||||
import org.alfresco.util.ValueDerivingMapFactory.ValueDeriver;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* People and users support in FreeMarker templates.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class People extends BaseTemplateProcessorExtension implements InitializingBean
|
||||
{
|
||||
/** Repository Service Registry */
|
||||
private ServiceRegistry services;
|
||||
private AuthorityDAO authorityDAO;
|
||||
private AuthorityService authorityService;
|
||||
private MutableAuthenticationService authenticationService;
|
||||
private PersonService personService;
|
||||
private StoreRef storeRef;
|
||||
private ValueDerivingMapFactory<TemplateNode, String, Boolean> valueDerivingMapFactory;
|
||||
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
Map <String, ValueDeriver<TemplateNode, Boolean>> capabilityTesters = new HashMap<String, ValueDeriver<TemplateNode, Boolean>>(5);
|
||||
capabilityTesters.put("isAdmin", new ValueDeriver<TemplateNode, Boolean>()
|
||||
{
|
||||
public Boolean deriveValue(TemplateNode source)
|
||||
{
|
||||
return isAdmin(source);
|
||||
}
|
||||
});
|
||||
capabilityTesters.put("isGuest", new ValueDeriver<TemplateNode, Boolean>()
|
||||
{
|
||||
public Boolean deriveValue(TemplateNode source)
|
||||
{
|
||||
return isGuest(source);
|
||||
}
|
||||
});
|
||||
capabilityTesters.put("isMutable", new ValueDeriver<TemplateNode, Boolean>()
|
||||
{
|
||||
public Boolean deriveValue(TemplateNode source)
|
||||
{
|
||||
// Check whether the account is mutable according to the authentication service
|
||||
String sourceUser = (String) source.getProperties().get(ContentModel.PROP_USERNAME);
|
||||
if (!authenticationService.isAuthenticationMutable(sourceUser))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Only allow non-admin users to mutate their own accounts
|
||||
String currentUser = authenticationService.getCurrentUserName();
|
||||
if (currentUser.equals(sourceUser) || authorityService.isAdminAuthority(currentUser))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
this.valueDerivingMapFactory = new ValueDerivingMapFactory<TemplateNode, String, Boolean>(capabilityTesters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default store reference
|
||||
*
|
||||
* @param storeRef the default store reference
|
||||
*/
|
||||
public void setStoreUrl(String storeRef)
|
||||
{
|
||||
// ensure this is not set again
|
||||
if (this.storeRef != null)
|
||||
{
|
||||
throw new IllegalStateException("Default store URL can only be set once.");
|
||||
}
|
||||
this.storeRef = new StoreRef(storeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the service registry
|
||||
*
|
||||
* @param serviceRegistry the service registry
|
||||
*/
|
||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
this.services = serviceRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authority DAO
|
||||
*
|
||||
* @param authorityDAO authority dao
|
||||
*/
|
||||
public void setAuthorityDAO(AuthorityDAO authorityDAO)
|
||||
{
|
||||
this.authorityDAO = authorityDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authority service
|
||||
*
|
||||
* @param authorityService The authorityService to set.
|
||||
*/
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the person service
|
||||
*
|
||||
* @param personService The personService to set.
|
||||
*/
|
||||
public void setPersonService(PersonService personService)
|
||||
{
|
||||
this.personService = personService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication service.
|
||||
*
|
||||
* @param authenticationService
|
||||
* the new authentication service
|
||||
*/
|
||||
public void setAuthenticationService(MutableAuthenticationService authenticationService)
|
||||
{
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Person given the username
|
||||
*
|
||||
* @param username the username of the person to get
|
||||
* @return the person node (type cm:person) or null if no such person exists
|
||||
*/
|
||||
public TemplateNode getPerson(String username)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Username", username);
|
||||
TemplateNode person = null;
|
||||
if (personService.personExists(username))
|
||||
{
|
||||
NodeRef personRef = personService.getPerson(username);
|
||||
person = new TemplateNode(personRef, services, getTemplateImageResolver());
|
||||
}
|
||||
return person;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Group given the group name
|
||||
*
|
||||
* @param groupName name of group to get
|
||||
* @return the group node (type usr:authorityContainer) or null if no such group exists
|
||||
*/
|
||||
public TemplateNode getGroup(String groupName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("GroupName", groupName);
|
||||
TemplateNode group = null;
|
||||
NodeRef groupRef = authorityDAO.getAuthorityNodeRefOrNull(groupName);
|
||||
if (groupRef != null)
|
||||
{
|
||||
group = new TemplateNode(groupRef, services, getTemplateImageResolver());
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the members (people) of a group (including all sub-groups)
|
||||
*
|
||||
* @param group the group to retrieve members for
|
||||
*
|
||||
* @return list of nodes representing the group members
|
||||
*/
|
||||
public List<TemplateNode> getMembers(TemplateNode group)
|
||||
{
|
||||
ParameterCheck.mandatory("Group", group);
|
||||
return getContainedAuthorities(group, AuthorityType.USER, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the members (people) of a group
|
||||
*
|
||||
* @param group the group to retrieve members for
|
||||
* @param recurse recurse into sub-groups
|
||||
*
|
||||
* @return list of nodes representing the group members
|
||||
*/
|
||||
public List<TemplateNode> getMembers(TemplateNode group, boolean recurse)
|
||||
{
|
||||
ParameterCheck.mandatory("Group", group);
|
||||
return getContainedAuthorities(group, AuthorityType.USER, recurse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the groups that contain the specified authority
|
||||
*
|
||||
* @param person the user (cm:person) to get the containing groups for
|
||||
*
|
||||
* @return the containing groups as a List of TemplateNode objects, can be null
|
||||
*/
|
||||
public List<TemplateNode> getContainerGroups(TemplateNode person)
|
||||
{
|
||||
ParameterCheck.mandatory("Person", person);
|
||||
List<TemplateNode> parents;
|
||||
Set<String> authorities = this.authorityService.getContainingAuthoritiesInZone(
|
||||
AuthorityType.GROUP,
|
||||
(String)person.getProperties().get(ContentModel.PROP_USERNAME),
|
||||
AuthorityService.ZONE_APP_DEFAULT, null, 1000);
|
||||
parents = new ArrayList<TemplateNode>(authorities.size());
|
||||
for (String authority : authorities)
|
||||
{
|
||||
TemplateNode group = getGroup(authority);
|
||||
if (group != null)
|
||||
{
|
||||
parents.add(group);
|
||||
}
|
||||
}
|
||||
return parents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the specified user is an Administrator authority.
|
||||
*
|
||||
* @param person to test
|
||||
*
|
||||
* @return true if an admin, false otherwise
|
||||
*/
|
||||
public boolean isAdmin(TemplateNode person)
|
||||
{
|
||||
ParameterCheck.mandatory("Person", person);
|
||||
return this.authorityService.isAdminAuthority((String)person.getProperties().get(ContentModel.PROP_USERNAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the specified user is an Guest authority.
|
||||
*
|
||||
* @param person to test
|
||||
*
|
||||
* @return true if a guest user, false otherwise
|
||||
*/
|
||||
public boolean isGuest(TemplateNode person)
|
||||
{
|
||||
ParameterCheck.mandatory("Person", person);
|
||||
return this.authorityService.isGuestAuthority((String)person.getProperties().get(ContentModel.PROP_USERNAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of capabilities (boolean assertions) for the given person.
|
||||
*
|
||||
* @param person the person
|
||||
* @return the capability map
|
||||
*/
|
||||
public Map<String, Boolean> getCapabilities(final TemplateNode person)
|
||||
{
|
||||
ParameterCheck.mandatory("Person", person);
|
||||
return this.valueDerivingMapFactory.getMap(person);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the specified user account is enabled.
|
||||
*
|
||||
* @param person to test
|
||||
*
|
||||
* @return true if account enabled, false if disabled
|
||||
*/
|
||||
public boolean isAccountEnabled(TemplateNode person)
|
||||
{
|
||||
// Only admins have rights to check authentication enablement
|
||||
if (this.authorityService.isAdminAuthority(AuthenticationUtil.getFullyAuthenticatedUser()))
|
||||
{
|
||||
return this.authenticationService.getAuthenticationEnabled((String) person.getProperties().get(
|
||||
ContentModel.PROP_USERNAME));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Contained Authorities
|
||||
*
|
||||
* @param container authority containers
|
||||
* @param type authority type to filter by
|
||||
* @param recurse recurse into sub-containers
|
||||
*
|
||||
* @return contained authorities
|
||||
*/
|
||||
private List<TemplateNode> getContainedAuthorities(TemplateNode container, AuthorityType type, boolean recurse)
|
||||
{
|
||||
List<TemplateNode> members = null;
|
||||
|
||||
if (container.getType().equals(ContentModel.TYPE_AUTHORITY_CONTAINER))
|
||||
{
|
||||
String groupName = (String)container.getProperties().get(ContentModel.PROP_AUTHORITY_NAME);
|
||||
Set<String> authorities = authorityService.getContainedAuthorities(type, groupName, !recurse);
|
||||
members = new ArrayList<TemplateNode>(authorities.size());
|
||||
for (String authority : authorities)
|
||||
{
|
||||
AuthorityType authorityType = AuthorityType.getAuthorityType(authority);
|
||||
if (authorityType.equals(AuthorityType.GROUP))
|
||||
{
|
||||
TemplateNode group = getGroup(authority);
|
||||
if (group != null)
|
||||
{
|
||||
members.add(group);
|
||||
}
|
||||
}
|
||||
else if (authorityType.equals(AuthorityType.USER))
|
||||
{
|
||||
TemplateNode person = getPerson(authority);
|
||||
if (person != null)
|
||||
{
|
||||
members.add(person);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return members != null ? members : Collections.<TemplateNode>emptyList();
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authority.AuthorityDAO;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
import org.alfresco.util.ValueDerivingMapFactory;
|
||||
import org.alfresco.util.ValueDerivingMapFactory.ValueDeriver;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* People and users support in FreeMarker templates.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class People extends BaseTemplateProcessorExtension implements InitializingBean
|
||||
{
|
||||
/** Repository Service Registry */
|
||||
private ServiceRegistry services;
|
||||
private AuthorityDAO authorityDAO;
|
||||
private AuthorityService authorityService;
|
||||
private MutableAuthenticationService authenticationService;
|
||||
private PersonService personService;
|
||||
private StoreRef storeRef;
|
||||
private ValueDerivingMapFactory<TemplateNode, String, Boolean> valueDerivingMapFactory;
|
||||
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
Map <String, ValueDeriver<TemplateNode, Boolean>> capabilityTesters = new HashMap<String, ValueDeriver<TemplateNode, Boolean>>(5);
|
||||
capabilityTesters.put("isAdmin", new ValueDeriver<TemplateNode, Boolean>()
|
||||
{
|
||||
public Boolean deriveValue(TemplateNode source)
|
||||
{
|
||||
return isAdmin(source);
|
||||
}
|
||||
});
|
||||
capabilityTesters.put("isGuest", new ValueDeriver<TemplateNode, Boolean>()
|
||||
{
|
||||
public Boolean deriveValue(TemplateNode source)
|
||||
{
|
||||
return isGuest(source);
|
||||
}
|
||||
});
|
||||
capabilityTesters.put("isMutable", new ValueDeriver<TemplateNode, Boolean>()
|
||||
{
|
||||
public Boolean deriveValue(TemplateNode source)
|
||||
{
|
||||
// Check whether the account is mutable according to the authentication service
|
||||
String sourceUser = (String) source.getProperties().get(ContentModel.PROP_USERNAME);
|
||||
if (!authenticationService.isAuthenticationMutable(sourceUser))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Only allow non-admin users to mutate their own accounts
|
||||
String currentUser = authenticationService.getCurrentUserName();
|
||||
if (currentUser.equals(sourceUser) || authorityService.isAdminAuthority(currentUser))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
this.valueDerivingMapFactory = new ValueDerivingMapFactory<TemplateNode, String, Boolean>(capabilityTesters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default store reference
|
||||
*
|
||||
* @param storeRef the default store reference
|
||||
*/
|
||||
public void setStoreUrl(String storeRef)
|
||||
{
|
||||
// ensure this is not set again
|
||||
if (this.storeRef != null)
|
||||
{
|
||||
throw new IllegalStateException("Default store URL can only be set once.");
|
||||
}
|
||||
this.storeRef = new StoreRef(storeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the service registry
|
||||
*
|
||||
* @param serviceRegistry the service registry
|
||||
*/
|
||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
this.services = serviceRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authority DAO
|
||||
*
|
||||
* @param authorityDAO authority dao
|
||||
*/
|
||||
public void setAuthorityDAO(AuthorityDAO authorityDAO)
|
||||
{
|
||||
this.authorityDAO = authorityDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authority service
|
||||
*
|
||||
* @param authorityService The authorityService to set.
|
||||
*/
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the person service
|
||||
*
|
||||
* @param personService The personService to set.
|
||||
*/
|
||||
public void setPersonService(PersonService personService)
|
||||
{
|
||||
this.personService = personService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication service.
|
||||
*
|
||||
* @param authenticationService
|
||||
* the new authentication service
|
||||
*/
|
||||
public void setAuthenticationService(MutableAuthenticationService authenticationService)
|
||||
{
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Person given the username
|
||||
*
|
||||
* @param username the username of the person to get
|
||||
* @return the person node (type cm:person) or null if no such person exists
|
||||
*/
|
||||
public TemplateNode getPerson(String username)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Username", username);
|
||||
TemplateNode person = null;
|
||||
if (personService.personExists(username))
|
||||
{
|
||||
NodeRef personRef = personService.getPerson(username);
|
||||
person = new TemplateNode(personRef, services, getTemplateImageResolver());
|
||||
}
|
||||
return person;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Group given the group name
|
||||
*
|
||||
* @param groupName name of group to get
|
||||
* @return the group node (type usr:authorityContainer) or null if no such group exists
|
||||
*/
|
||||
public TemplateNode getGroup(String groupName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("GroupName", groupName);
|
||||
TemplateNode group = null;
|
||||
NodeRef groupRef = authorityDAO.getAuthorityNodeRefOrNull(groupName);
|
||||
if (groupRef != null)
|
||||
{
|
||||
group = new TemplateNode(groupRef, services, getTemplateImageResolver());
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the members (people) of a group (including all sub-groups)
|
||||
*
|
||||
* @param group the group to retrieve members for
|
||||
*
|
||||
* @return list of nodes representing the group members
|
||||
*/
|
||||
public List<TemplateNode> getMembers(TemplateNode group)
|
||||
{
|
||||
ParameterCheck.mandatory("Group", group);
|
||||
return getContainedAuthorities(group, AuthorityType.USER, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the members (people) of a group
|
||||
*
|
||||
* @param group the group to retrieve members for
|
||||
* @param recurse recurse into sub-groups
|
||||
*
|
||||
* @return list of nodes representing the group members
|
||||
*/
|
||||
public List<TemplateNode> getMembers(TemplateNode group, boolean recurse)
|
||||
{
|
||||
ParameterCheck.mandatory("Group", group);
|
||||
return getContainedAuthorities(group, AuthorityType.USER, recurse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the groups that contain the specified authority
|
||||
*
|
||||
* @param person the user (cm:person) to get the containing groups for
|
||||
*
|
||||
* @return the containing groups as a List of TemplateNode objects, can be null
|
||||
*/
|
||||
public List<TemplateNode> getContainerGroups(TemplateNode person)
|
||||
{
|
||||
ParameterCheck.mandatory("Person", person);
|
||||
List<TemplateNode> parents;
|
||||
Set<String> authorities = this.authorityService.getContainingAuthoritiesInZone(
|
||||
AuthorityType.GROUP,
|
||||
(String)person.getProperties().get(ContentModel.PROP_USERNAME),
|
||||
AuthorityService.ZONE_APP_DEFAULT, null, 1000);
|
||||
parents = new ArrayList<TemplateNode>(authorities.size());
|
||||
for (String authority : authorities)
|
||||
{
|
||||
TemplateNode group = getGroup(authority);
|
||||
if (group != null)
|
||||
{
|
||||
parents.add(group);
|
||||
}
|
||||
}
|
||||
return parents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the specified user is an Administrator authority.
|
||||
*
|
||||
* @param person to test
|
||||
*
|
||||
* @return true if an admin, false otherwise
|
||||
*/
|
||||
public boolean isAdmin(TemplateNode person)
|
||||
{
|
||||
ParameterCheck.mandatory("Person", person);
|
||||
return this.authorityService.isAdminAuthority((String)person.getProperties().get(ContentModel.PROP_USERNAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the specified user is an Guest authority.
|
||||
*
|
||||
* @param person to test
|
||||
*
|
||||
* @return true if a guest user, false otherwise
|
||||
*/
|
||||
public boolean isGuest(TemplateNode person)
|
||||
{
|
||||
ParameterCheck.mandatory("Person", person);
|
||||
return this.authorityService.isGuestAuthority((String)person.getProperties().get(ContentModel.PROP_USERNAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of capabilities (boolean assertions) for the given person.
|
||||
*
|
||||
* @param person the person
|
||||
* @return the capability map
|
||||
*/
|
||||
public Map<String, Boolean> getCapabilities(final TemplateNode person)
|
||||
{
|
||||
ParameterCheck.mandatory("Person", person);
|
||||
return this.valueDerivingMapFactory.getMap(person);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the specified user account is enabled.
|
||||
*
|
||||
* @param person to test
|
||||
*
|
||||
* @return true if account enabled, false if disabled
|
||||
*/
|
||||
public boolean isAccountEnabled(TemplateNode person)
|
||||
{
|
||||
// Only admins have rights to check authentication enablement
|
||||
if (this.authorityService.isAdminAuthority(AuthenticationUtil.getFullyAuthenticatedUser()))
|
||||
{
|
||||
return this.authenticationService.getAuthenticationEnabled((String) person.getProperties().get(
|
||||
ContentModel.PROP_USERNAME));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Contained Authorities
|
||||
*
|
||||
* @param container authority containers
|
||||
* @param type authority type to filter by
|
||||
* @param recurse recurse into sub-containers
|
||||
*
|
||||
* @return contained authorities
|
||||
*/
|
||||
private List<TemplateNode> getContainedAuthorities(TemplateNode container, AuthorityType type, boolean recurse)
|
||||
{
|
||||
List<TemplateNode> members = null;
|
||||
|
||||
if (container.getType().equals(ContentModel.TYPE_AUTHORITY_CONTAINER))
|
||||
{
|
||||
String groupName = (String)container.getProperties().get(ContentModel.PROP_AUTHORITY_NAME);
|
||||
Set<String> authorities = authorityService.getContainedAuthorities(type, groupName, !recurse);
|
||||
members = new ArrayList<TemplateNode>(authorities.size());
|
||||
for (String authority : authorities)
|
||||
{
|
||||
AuthorityType authorityType = AuthorityType.getAuthorityType(authority);
|
||||
if (authorityType.equals(AuthorityType.GROUP))
|
||||
{
|
||||
TemplateNode group = getGroup(authority);
|
||||
if (group != null)
|
||||
{
|
||||
members.add(group);
|
||||
}
|
||||
}
|
||||
else if (authorityType.equals(AuthorityType.USER))
|
||||
{
|
||||
TemplateNode person = getPerson(authority);
|
||||
if (person != null)
|
||||
{
|
||||
members.add(person);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return members != null ? members : Collections.<TemplateNode>emptyList();
|
||||
}
|
||||
}
|
||||
|
@@ -1,48 +1,48 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Simple class to recursively convert property values to bean objects accessable by Templates.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class PropertyConverter
|
||||
{
|
||||
public Serializable convertProperty(
|
||||
Serializable value, QName name, ServiceRegistry services, TemplateImageResolver resolver)
|
||||
{
|
||||
// perform conversions from Java objects to template compatable instances
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (value instanceof NodeRef)
|
||||
{
|
||||
// NodeRef object properties are converted to new TemplateNode objects
|
||||
// so they can be used as objects within a template
|
||||
value = new TemplateNode(((NodeRef)value), services, resolver);
|
||||
}
|
||||
else if (value instanceof List)
|
||||
{
|
||||
// recursively convert each value in the collection
|
||||
List<Serializable> list = (List<Serializable>)value;
|
||||
List<Serializable> result = new ArrayList<Serializable>(list.size());
|
||||
for (int i=0; i<list.size(); i++)
|
||||
{
|
||||
// add each item to a new list as the repo can return unmodifiable lists
|
||||
result.add(convertProperty(list.get(i), name, services, resolver));
|
||||
}
|
||||
value = (Serializable)result;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Simple class to recursively convert property values to bean objects accessable by Templates.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class PropertyConverter
|
||||
{
|
||||
public Serializable convertProperty(
|
||||
Serializable value, QName name, ServiceRegistry services, TemplateImageResolver resolver)
|
||||
{
|
||||
// perform conversions from Java objects to template compatable instances
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (value instanceof NodeRef)
|
||||
{
|
||||
// NodeRef object properties are converted to new TemplateNode objects
|
||||
// so they can be used as objects within a template
|
||||
value = new TemplateNode(((NodeRef)value), services, resolver);
|
||||
}
|
||||
else if (value instanceof List)
|
||||
{
|
||||
// recursively convert each value in the collection
|
||||
List<Serializable> list = (List<Serializable>)value;
|
||||
List<Serializable> result = new ArrayList<Serializable>(list.size());
|
||||
for (int i=0; i<list.size(); i++)
|
||||
{
|
||||
// add each item to a new list as the repo can return unmodifiable lists
|
||||
result.add(convertProperty(list.get(i), name, services, resolver));
|
||||
}
|
||||
value = (Serializable)result;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
@@ -1,72 +1,72 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.SAXReader;
|
||||
|
||||
/**
|
||||
* Provides functionality to load a saved search and execute it to return TemplateNode objects.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class SavedSearchResultsMap extends BaseSearchResultsMap
|
||||
{
|
||||
private static final String ELEMENT_QUERY = "query";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent The parent TemplateNode to execute searches from
|
||||
* @param services The ServiceRegistry to use
|
||||
*/
|
||||
public SavedSearchResultsMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(parent, services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
String search = null;
|
||||
|
||||
if (key != null && key.toString().length() != 0)
|
||||
{
|
||||
// read the Saved Search XML on the specified node - and get the Lucene search from it
|
||||
try
|
||||
{
|
||||
NodeRef ref = new NodeRef(key.toString());
|
||||
|
||||
ContentReader content = services.getContentService().getReader(ref, ContentModel.PROP_CONTENT);
|
||||
if (content != null && content.exists())
|
||||
{
|
||||
// get the root element
|
||||
SAXReader reader = new SAXReader();
|
||||
Document document = reader.read(new StringReader(content.getContentString()));
|
||||
Element rootElement = document.getRootElement();
|
||||
|
||||
Element queryElement = rootElement.element(ELEMENT_QUERY);
|
||||
if (queryElement != null)
|
||||
{
|
||||
search = queryElement.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to find or load saved Search: " + key, err);
|
||||
}
|
||||
}
|
||||
|
||||
// execute the search
|
||||
return query(search);
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.SAXReader;
|
||||
|
||||
/**
|
||||
* Provides functionality to load a saved search and execute it to return TemplateNode objects.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class SavedSearchResultsMap extends BaseSearchResultsMap
|
||||
{
|
||||
private static final String ELEMENT_QUERY = "query";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent The parent TemplateNode to execute searches from
|
||||
* @param services The ServiceRegistry to use
|
||||
*/
|
||||
public SavedSearchResultsMap(TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
super(parent, services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
String search = null;
|
||||
|
||||
if (key != null && key.toString().length() != 0)
|
||||
{
|
||||
// read the Saved Search XML on the specified node - and get the Lucene search from it
|
||||
try
|
||||
{
|
||||
NodeRef ref = new NodeRef(key.toString());
|
||||
|
||||
ContentReader content = services.getContentService().getReader(ref, ContentModel.PROP_CONTENT);
|
||||
if (content != null && content.exists())
|
||||
{
|
||||
// get the root element
|
||||
SAXReader reader = new SAXReader();
|
||||
Document document = reader.read(new StringReader(content.getContentString()));
|
||||
Element rootElement = document.getRootElement();
|
||||
|
||||
Element queryElement = rootElement.element(ELEMENT_QUERY);
|
||||
if (queryElement != null)
|
||||
{
|
||||
search = queryElement.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to find or load saved Search: " + key, err);
|
||||
}
|
||||
}
|
||||
|
||||
// execute the search
|
||||
return query(search);
|
||||
}
|
||||
}
|
||||
|
@@ -1,65 +1,65 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Object representing an association
|
||||
*/
|
||||
public class TemplateAssociation implements Serializable
|
||||
{
|
||||
/** Serial version UUID*/
|
||||
private static final long serialVersionUID = -2903588739741433082L;
|
||||
|
||||
/** Service registry **/
|
||||
private ServiceRegistry services;
|
||||
|
||||
/** Association reference **/
|
||||
private AssociationRef assocRef;
|
||||
|
||||
/** Image Resolver **/
|
||||
private TemplateImageResolver resolver;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param services
|
||||
* @param assocRef
|
||||
*/
|
||||
public TemplateAssociation(AssociationRef assocRef, ServiceRegistry services, TemplateImageResolver resolver)
|
||||
{
|
||||
this.assocRef = assocRef;
|
||||
this.services = services;
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public AssociationRef getAssociationRef()
|
||||
{
|
||||
return this.assocRef;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return assocRef.getTypeQName().toString();
|
||||
}
|
||||
|
||||
public QName getTypeQName()
|
||||
{
|
||||
return assocRef.getTypeQName();
|
||||
}
|
||||
|
||||
public TemplateNode getSource()
|
||||
{
|
||||
return new TemplateNode(assocRef.getSourceRef(), services, resolver);
|
||||
}
|
||||
|
||||
public TemplateNode getTarget()
|
||||
{
|
||||
return new TemplateNode(assocRef.getTargetRef(), services, resolver);
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Object representing an association
|
||||
*/
|
||||
public class TemplateAssociation implements Serializable
|
||||
{
|
||||
/** Serial version UUID*/
|
||||
private static final long serialVersionUID = -2903588739741433082L;
|
||||
|
||||
/** Service registry **/
|
||||
private ServiceRegistry services;
|
||||
|
||||
/** Association reference **/
|
||||
private AssociationRef assocRef;
|
||||
|
||||
/** Image Resolver **/
|
||||
private TemplateImageResolver resolver;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param services
|
||||
* @param assocRef
|
||||
*/
|
||||
public TemplateAssociation(AssociationRef assocRef, ServiceRegistry services, TemplateImageResolver resolver)
|
||||
{
|
||||
this.assocRef = assocRef;
|
||||
this.services = services;
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public AssociationRef getAssociationRef()
|
||||
{
|
||||
return this.assocRef;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return assocRef.getTypeQName().toString();
|
||||
}
|
||||
|
||||
public QName getTypeQName()
|
||||
{
|
||||
return assocRef.getTypeQName();
|
||||
}
|
||||
|
||||
public TemplateNode getSource()
|
||||
{
|
||||
return new TemplateNode(assocRef.getSourceRef(), services, resolver);
|
||||
}
|
||||
|
||||
public TemplateNode getTarget()
|
||||
{
|
||||
return new TemplateNode(assocRef.getTargetRef(), services, resolver);
|
||||
}
|
||||
}
|
||||
|
@@ -1,43 +1,43 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
/**
|
||||
* Contract for Template API objects that support content on the 'cm:content' default property.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface TemplateContent extends TemplateProperties
|
||||
{
|
||||
/**
|
||||
* @return the content String for this node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public String getContent();
|
||||
|
||||
/**
|
||||
* @return For a content document, this method returns the URL to the content stream for
|
||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||
* <p>
|
||||
* For a container node, this method return the URL to browse to the folder in the web-client
|
||||
*/
|
||||
public String getUrl();
|
||||
|
||||
/**
|
||||
* @return For a content document, this method returns the download URL to the content for
|
||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||
* <p>
|
||||
* For a container node, this method returns an empty string
|
||||
*/
|
||||
public String getDownloadUrl();
|
||||
|
||||
/**
|
||||
* @return The mimetype encoding for content attached to the node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public String getMimetype();
|
||||
|
||||
/**
|
||||
* @return The size in bytes of the content attached to the node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public long getSize();
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
/**
|
||||
* Contract for Template API objects that support content on the 'cm:content' default property.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface TemplateContent extends TemplateProperties
|
||||
{
|
||||
/**
|
||||
* @return the content String for this node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public String getContent();
|
||||
|
||||
/**
|
||||
* @return For a content document, this method returns the URL to the content stream for
|
||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||
* <p>
|
||||
* For a container node, this method return the URL to browse to the folder in the web-client
|
||||
*/
|
||||
public String getUrl();
|
||||
|
||||
/**
|
||||
* @return For a content document, this method returns the download URL to the content for
|
||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||
* <p>
|
||||
* For a container node, this method returns an empty string
|
||||
*/
|
||||
public String getDownloadUrl();
|
||||
|
||||
/**
|
||||
* @return The mimetype encoding for content attached to the node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public String getMimetype();
|
||||
|
||||
/**
|
||||
* @return The size in bytes of the content attached to the node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public long getSize();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,35 +1,35 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Contract supported by Template API objects that represent a repository object via a NodeRef
|
||||
* and associated minimum properties such as as Type and Name.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface TemplateNodeRef extends Serializable
|
||||
{
|
||||
/**
|
||||
* @return The GUID for the node
|
||||
*/
|
||||
public String getId();
|
||||
|
||||
/**
|
||||
* @return Returns the NodeRef this Node object represents
|
||||
*/
|
||||
public NodeRef getNodeRef();
|
||||
|
||||
/**
|
||||
* @return Returns the type.
|
||||
*/
|
||||
public QName getType();
|
||||
|
||||
/**
|
||||
* @return The display name for the node
|
||||
*/
|
||||
public String getName();
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Contract supported by Template API objects that represent a repository object via a NodeRef
|
||||
* and associated minimum properties such as as Type and Name.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface TemplateNodeRef extends Serializable
|
||||
{
|
||||
/**
|
||||
* @return The GUID for the node
|
||||
*/
|
||||
public String getId();
|
||||
|
||||
/**
|
||||
* @return Returns the NodeRef this Node object represents
|
||||
*/
|
||||
public NodeRef getNodeRef();
|
||||
|
||||
/**
|
||||
* @return Returns the type.
|
||||
*/
|
||||
public QName getType();
|
||||
|
||||
/**
|
||||
* @return The display name for the node
|
||||
*/
|
||||
public String getName();
|
||||
}
|
||||
|
@@ -1,30 +1,30 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Contract for Template API objects that support permissions.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface TemplatePermissions extends TemplateNodeRef
|
||||
{
|
||||
/**
|
||||
* @return List of permissions applied to this Node.
|
||||
* Strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION for example
|
||||
* ALLOWED;kevinr;Consumer so can be easily tokenized on the ';' character.
|
||||
*/
|
||||
public List<String> getPermissions();
|
||||
|
||||
/**
|
||||
* @return true if this node inherits permissions from its parent node, false otherwise.
|
||||
*/
|
||||
public boolean getInheritsPermissions();
|
||||
|
||||
/**
|
||||
* @param permission Permission name to test
|
||||
*
|
||||
* @return true if the current user is granted the specified permission on the node
|
||||
*/
|
||||
public boolean hasPermission(String permission);
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Contract for Template API objects that support permissions.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface TemplatePermissions extends TemplateNodeRef
|
||||
{
|
||||
/**
|
||||
* @return List of permissions applied to this Node.
|
||||
* Strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION for example
|
||||
* ALLOWED;kevinr;Consumer so can be easily tokenized on the ';' character.
|
||||
*/
|
||||
public List<String> getPermissions();
|
||||
|
||||
/**
|
||||
* @return true if this node inherits permissions from its parent node, false otherwise.
|
||||
*/
|
||||
public boolean getInheritsPermissions();
|
||||
|
||||
/**
|
||||
* @param permission Permission name to test
|
||||
*
|
||||
* @return true if the current user is granted the specified permission on the node
|
||||
*/
|
||||
public boolean hasPermission(String permission);
|
||||
}
|
||||
|
@@ -1,45 +1,45 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Contract for Template API objects that have properties, aspects and children.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
@AlfrescoPublicApi
|
||||
public interface TemplateProperties extends TemplateNodeRef
|
||||
{
|
||||
/**
|
||||
* @return The properties available on this node.
|
||||
*/
|
||||
public Map<String, Serializable> getProperties();
|
||||
|
||||
/**
|
||||
* @return The list of aspects applied to this node
|
||||
*/
|
||||
public Set<QName> getAspects();
|
||||
|
||||
/**
|
||||
* @param aspect The aspect name to test for
|
||||
*
|
||||
* @return true if the node has the aspect false otherwise
|
||||
*/
|
||||
public boolean hasAspect(String aspect);
|
||||
|
||||
/**
|
||||
* @return The children of this Node as TemplateNode wrappers
|
||||
*/
|
||||
public List<TemplateProperties> getChildren();
|
||||
|
||||
/**
|
||||
* @return the primary parent of this node
|
||||
*/
|
||||
public TemplateProperties getParent();
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Contract for Template API objects that have properties, aspects and children.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
@AlfrescoPublicApi
|
||||
public interface TemplateProperties extends TemplateNodeRef
|
||||
{
|
||||
/**
|
||||
* @return The properties available on this node.
|
||||
*/
|
||||
public Map<String, Serializable> getProperties();
|
||||
|
||||
/**
|
||||
* @return The list of aspects applied to this node
|
||||
*/
|
||||
public Set<QName> getAspects();
|
||||
|
||||
/**
|
||||
* @param aspect The aspect name to test for
|
||||
*
|
||||
* @return true if the node has the aspect false otherwise
|
||||
*/
|
||||
public boolean hasAspect(String aspect);
|
||||
|
||||
/**
|
||||
* @return The children of this Node as TemplateNode wrappers
|
||||
*/
|
||||
public List<TemplateProperties> getChildren();
|
||||
|
||||
/**
|
||||
* @return the primary parent of this node
|
||||
*/
|
||||
public TemplateProperties getParent();
|
||||
}
|
||||
|
@@ -1,265 +1,265 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolverProvider;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNameMap;
|
||||
import org.springframework.extensions.surf.util.URLEncoder;
|
||||
|
||||
/**
|
||||
* Template Node wrapper representing a record in the version history of a node.
|
||||
* Provides access to basic properties and version information for the frozen state record.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class VersionHistoryNode extends BaseContentNode implements NamespacePrefixResolverProvider
|
||||
{
|
||||
private QNameMap<String, Serializable> properties;
|
||||
private boolean propsRetrieved = false;
|
||||
private Version version;
|
||||
private TemplateNode parent;
|
||||
private Set<QName> aspects = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param version Descriptor of the node version information
|
||||
*/
|
||||
public VersionHistoryNode(Version version, TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
if (version == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Version history descriptor is mandatory.");
|
||||
}
|
||||
if (parent == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Parent TemplateNode is mandatory.");
|
||||
}
|
||||
if (services == null)
|
||||
{
|
||||
throw new IllegalArgumentException("The ServiceRegistry must be supplied.");
|
||||
}
|
||||
this.version = version;
|
||||
this.parent = parent;
|
||||
this.services = services;
|
||||
this.properties = new QNameMap<String, Serializable>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The GUID for the frozen state NodeRef
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return this.version.getFrozenStateNodeRef().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the frozen state NodeRef this record represents
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return this.version.getFrozenStateNodeRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the type.
|
||||
*/
|
||||
public QName getType()
|
||||
{
|
||||
return parent.services.getNodeService().getType(this.version.getFrozenStateNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the item name.
|
||||
*
|
||||
* @return the item name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return (String)this.getProperties().get(ContentModel.PROP_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the item title.
|
||||
*
|
||||
* @return the item name
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return (String)this.getProperties().get(ContentModel.PROP_TITLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the created date from the version property data.
|
||||
*
|
||||
* @return the date the version was created
|
||||
*/
|
||||
public Date getCreatedDate()
|
||||
{
|
||||
return this.version.getCreatedDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the creator of the version.
|
||||
*
|
||||
* @return the creator of the version
|
||||
*/
|
||||
public String getCreator()
|
||||
{
|
||||
return this.version.getCreator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the version label from the version property data.
|
||||
*
|
||||
* @return the version label
|
||||
*/
|
||||
public String getVersionLabel()
|
||||
{
|
||||
return this.version.getVersionLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the version type.
|
||||
*
|
||||
* @return true if this is a major version, false otherwise.
|
||||
*/
|
||||
public boolean getIsMajorVersion()
|
||||
{
|
||||
return (this.version.getVersionType() == VersionType.MAJOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the version description.
|
||||
*
|
||||
* @return the version description
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return this.version.getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map containing the version property values.
|
||||
*
|
||||
* @return the map containing the version properties
|
||||
*/
|
||||
public Map<String, Serializable> getProperties()
|
||||
{
|
||||
if (propsRetrieved == false)
|
||||
{
|
||||
Map<QName, Serializable> props = parent.services.getNodeService().getProperties(
|
||||
this.version.getFrozenStateNodeRef());
|
||||
|
||||
for (QName qname : props.keySet())
|
||||
{
|
||||
Serializable propValue = parent.new TemplatePropertyConverter().convertProperty(props.get(qname), qname, parent.services, parent.imageResolver);
|
||||
this.properties.put(qname.toString(), propValue);
|
||||
}
|
||||
|
||||
propsRetrieved = true;
|
||||
}
|
||||
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The list of aspects applied to this node
|
||||
*/
|
||||
@Override
|
||||
public Set<QName> getAspects()
|
||||
{
|
||||
if (this.aspects == null)
|
||||
{
|
||||
this.aspects = parent.services.getNodeService().getAspects(this.version.getFrozenStateNodeRef());
|
||||
}
|
||||
|
||||
return this.aspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aspect The aspect name to test for
|
||||
*
|
||||
* @return true if the node has the aspect false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean hasAspect(String aspect)
|
||||
{
|
||||
if (this.aspects == null)
|
||||
{
|
||||
getAspects();
|
||||
}
|
||||
|
||||
if (aspect.startsWith(parent.NAMESPACE_BEGIN))
|
||||
{
|
||||
return aspects.contains((QName.createQName(aspect)));
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean found = false;
|
||||
for (QName qname : this.aspects)
|
||||
{
|
||||
if (qname.toPrefixString(parent.services.getNamespaceService()).equals(aspect))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.TemplateProperties#getChildren()
|
||||
*/
|
||||
@Override
|
||||
public List<TemplateProperties> getChildren()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.TemplateProperties#getParent()
|
||||
*/
|
||||
public TemplateProperties getParent()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public NamespacePrefixResolver getNamespacePrefixResolver()
|
||||
{
|
||||
return this.services.getNamespaceService();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Content API
|
||||
|
||||
/**
|
||||
* @return Returns the URL to the content stream for the frozen state of the node from
|
||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
@Override
|
||||
public String getUrl()
|
||||
{
|
||||
NodeRef nodeRef = this.version.getFrozenStateNodeRef();
|
||||
return MessageFormat.format(parent.CONTENT_GET_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId(),
|
||||
URLEncoder.encode(getName()) } );
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolverProvider;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNameMap;
|
||||
import org.springframework.extensions.surf.util.URLEncoder;
|
||||
|
||||
/**
|
||||
* Template Node wrapper representing a record in the version history of a node.
|
||||
* Provides access to basic properties and version information for the frozen state record.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class VersionHistoryNode extends BaseContentNode implements NamespacePrefixResolverProvider
|
||||
{
|
||||
private QNameMap<String, Serializable> properties;
|
||||
private boolean propsRetrieved = false;
|
||||
private Version version;
|
||||
private TemplateNode parent;
|
||||
private Set<QName> aspects = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param version Descriptor of the node version information
|
||||
*/
|
||||
public VersionHistoryNode(Version version, TemplateNode parent, ServiceRegistry services)
|
||||
{
|
||||
if (version == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Version history descriptor is mandatory.");
|
||||
}
|
||||
if (parent == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Parent TemplateNode is mandatory.");
|
||||
}
|
||||
if (services == null)
|
||||
{
|
||||
throw new IllegalArgumentException("The ServiceRegistry must be supplied.");
|
||||
}
|
||||
this.version = version;
|
||||
this.parent = parent;
|
||||
this.services = services;
|
||||
this.properties = new QNameMap<String, Serializable>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The GUID for the frozen state NodeRef
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return this.version.getFrozenStateNodeRef().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the frozen state NodeRef this record represents
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return this.version.getFrozenStateNodeRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the type.
|
||||
*/
|
||||
public QName getType()
|
||||
{
|
||||
return parent.services.getNodeService().getType(this.version.getFrozenStateNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the item name.
|
||||
*
|
||||
* @return the item name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return (String)this.getProperties().get(ContentModel.PROP_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the item title.
|
||||
*
|
||||
* @return the item name
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return (String)this.getProperties().get(ContentModel.PROP_TITLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the created date from the version property data.
|
||||
*
|
||||
* @return the date the version was created
|
||||
*/
|
||||
public Date getCreatedDate()
|
||||
{
|
||||
return this.version.getCreatedDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the creator of the version.
|
||||
*
|
||||
* @return the creator of the version
|
||||
*/
|
||||
public String getCreator()
|
||||
{
|
||||
return this.version.getCreator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the version label from the version property data.
|
||||
*
|
||||
* @return the version label
|
||||
*/
|
||||
public String getVersionLabel()
|
||||
{
|
||||
return this.version.getVersionLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the version type.
|
||||
*
|
||||
* @return true if this is a major version, false otherwise.
|
||||
*/
|
||||
public boolean getIsMajorVersion()
|
||||
{
|
||||
return (this.version.getVersionType() == VersionType.MAJOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the version description.
|
||||
*
|
||||
* @return the version description
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return this.version.getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map containing the version property values.
|
||||
*
|
||||
* @return the map containing the version properties
|
||||
*/
|
||||
public Map<String, Serializable> getProperties()
|
||||
{
|
||||
if (propsRetrieved == false)
|
||||
{
|
||||
Map<QName, Serializable> props = parent.services.getNodeService().getProperties(
|
||||
this.version.getFrozenStateNodeRef());
|
||||
|
||||
for (QName qname : props.keySet())
|
||||
{
|
||||
Serializable propValue = parent.new TemplatePropertyConverter().convertProperty(props.get(qname), qname, parent.services, parent.imageResolver);
|
||||
this.properties.put(qname.toString(), propValue);
|
||||
}
|
||||
|
||||
propsRetrieved = true;
|
||||
}
|
||||
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The list of aspects applied to this node
|
||||
*/
|
||||
@Override
|
||||
public Set<QName> getAspects()
|
||||
{
|
||||
if (this.aspects == null)
|
||||
{
|
||||
this.aspects = parent.services.getNodeService().getAspects(this.version.getFrozenStateNodeRef());
|
||||
}
|
||||
|
||||
return this.aspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aspect The aspect name to test for
|
||||
*
|
||||
* @return true if the node has the aspect false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean hasAspect(String aspect)
|
||||
{
|
||||
if (this.aspects == null)
|
||||
{
|
||||
getAspects();
|
||||
}
|
||||
|
||||
if (aspect.startsWith(parent.NAMESPACE_BEGIN))
|
||||
{
|
||||
return aspects.contains((QName.createQName(aspect)));
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean found = false;
|
||||
for (QName qname : this.aspects)
|
||||
{
|
||||
if (qname.toPrefixString(parent.services.getNamespaceService()).equals(aspect))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.TemplateProperties#getChildren()
|
||||
*/
|
||||
@Override
|
||||
public List<TemplateProperties> getChildren()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.template.TemplateProperties#getParent()
|
||||
*/
|
||||
public TemplateProperties getParent()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public NamespacePrefixResolver getNamespacePrefixResolver()
|
||||
{
|
||||
return this.services.getNamespaceService();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Content API
|
||||
|
||||
/**
|
||||
* @return Returns the URL to the content stream for the frozen state of the node from
|
||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
@Override
|
||||
public String getUrl()
|
||||
{
|
||||
NodeRef nodeRef = this.version.getFrozenStateNodeRef();
|
||||
return MessageFormat.format(parent.CONTENT_GET_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId(),
|
||||
URLEncoder.encode(getName()) } );
|
||||
}
|
||||
}
|
||||
|
@@ -1,309 +1,309 @@
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTransition;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolverProvider;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNameMap;
|
||||
|
||||
/**
|
||||
* Workflow and task support in FreeMarker templates.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class Workflow extends BaseTemplateProcessorExtension
|
||||
{
|
||||
private ServiceRegistry services;
|
||||
|
||||
/**
|
||||
* Sets the service registry
|
||||
*
|
||||
* @param services the service registry
|
||||
*/
|
||||
public void setServiceRegistry(ServiceRegistry services)
|
||||
{
|
||||
this.services = services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of objects representing the assigned tasks for the current user
|
||||
*
|
||||
* @return list of WorkflowTaskItem bean objects {@link WorkflowTaskItem}
|
||||
*/
|
||||
public List<WorkflowTaskItem> getAssignedTasks()
|
||||
{
|
||||
// get the "in progress" tasks for the current user
|
||||
List<WorkflowTask> tasks = getWorkflowService().getAssignedTasks(
|
||||
this.services.getAuthenticationService().getCurrentUserName(),
|
||||
WorkflowTaskState.IN_PROGRESS);
|
||||
|
||||
return convertTasks(tasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of objects representing the pooled tasks for the current user
|
||||
*
|
||||
* @return list of WorkflowTaskItem bean objects {@link WorkflowTaskItem}
|
||||
*/
|
||||
public List<WorkflowTaskItem> getPooledTasks()
|
||||
{
|
||||
// get the "pooled" tasks for the current user
|
||||
List<WorkflowTask> tasks = getWorkflowService().getPooledTasks(
|
||||
this.services.getAuthenticationService().getCurrentUserName());
|
||||
|
||||
return convertTasks(tasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of objects representing the completed tasks for the current user
|
||||
*
|
||||
* @return list of WorkflowTaskItem bean objects {@link WorkflowTaskItem}
|
||||
*/
|
||||
public List<WorkflowTaskItem> getCompletedTasks()
|
||||
{
|
||||
// get the "completed" tasks for the current user
|
||||
List<WorkflowTask> tasks = getWorkflowService().getAssignedTasks(
|
||||
this.services.getAuthenticationService().getCurrentUserName(),
|
||||
WorkflowTaskState.COMPLETED);
|
||||
|
||||
return convertTasks(tasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single object representing a task of the given taskId for the current user
|
||||
*
|
||||
* @return WorkflowTaskItem bean object {@link WorkflowTaskItem}
|
||||
*/
|
||||
public WorkflowTaskItem getTaskById(String taskId)
|
||||
{
|
||||
// get the task corresponding to the given taskId
|
||||
WorkflowTask task = getWorkflowService().getTaskById(taskId);
|
||||
|
||||
return new WorkflowTaskItem(this.services, getTemplateImageResolver(), task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list of WorkflowTask items into bean objects accessable from templates
|
||||
*
|
||||
* @param tasks List of WorkflowTask objects to convert
|
||||
*
|
||||
* @return List of WorkflowTaskItem bean wrapper objects
|
||||
*/
|
||||
private List<WorkflowTaskItem> convertTasks(List<WorkflowTask> tasks)
|
||||
{
|
||||
List<WorkflowTaskItem> items = new ArrayList<WorkflowTaskItem>(tasks.size());
|
||||
for (WorkflowTask task : tasks)
|
||||
{
|
||||
items.add(new WorkflowTaskItem(this.services, getTemplateImageResolver(), task));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private WorkflowService getWorkflowService()
|
||||
{
|
||||
return this.services.getWorkflowService();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple bean wrapper around a WorkflowTask item
|
||||
*/
|
||||
public static class WorkflowTaskItem implements NamespacePrefixResolverProvider
|
||||
{
|
||||
private WorkflowTask task;
|
||||
private QNameMap<String, Serializable> properties = null;
|
||||
private ServiceRegistry services;
|
||||
private TemplateImageResolver resolver;
|
||||
|
||||
public WorkflowTaskItem(ServiceRegistry services, TemplateImageResolver resolver, WorkflowTask task)
|
||||
{
|
||||
this.task = task;
|
||||
this.services = services;
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return this.task.title;
|
||||
}
|
||||
|
||||
public String getQnameType()
|
||||
{
|
||||
return this.task.definition.metadata.getName().toString();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.task.description;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return this.task.path.instance.description;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return this.task.id;
|
||||
}
|
||||
|
||||
public boolean getIsCompleted()
|
||||
{
|
||||
return (this.task.state == WorkflowTaskState.COMPLETED);
|
||||
}
|
||||
|
||||
public Date getStartDate()
|
||||
{
|
||||
return this.task.path.instance.startDate;
|
||||
}
|
||||
|
||||
public Map<String, String>[] getTransitions()
|
||||
{
|
||||
Map<String, String>[] tranMaps = null;
|
||||
WorkflowTransition[] transitions = this.task.definition.node.transitions;
|
||||
if (transitions != null)
|
||||
{
|
||||
tranMaps = new HashMap[transitions.length];
|
||||
for (int i=0; i<transitions.length; i++)
|
||||
{
|
||||
tranMaps[i] = new HashMap<String, String>(2, 1.0f);
|
||||
tranMaps[i].put("label", transitions[i].title);
|
||||
tranMaps[i].put("id", transitions[i].id);
|
||||
}
|
||||
}
|
||||
return (tranMaps != null ? tranMaps : new HashMap[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A TemplateNode representing the initiator (person) of the workflow
|
||||
*/
|
||||
public TemplateNode getInitiator()
|
||||
{
|
||||
return new TemplateNode(this.task.path.instance.initiator, this.services, this.resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The workflow package ref
|
||||
*/
|
||||
public NodeRef getPackage()
|
||||
{
|
||||
return (NodeRef)this.task.properties.get(WorkflowModel.ASSOC_PACKAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The workflow package ref as a TemplateNode
|
||||
*/
|
||||
public TemplateNode getPackageTemplateNode()
|
||||
{
|
||||
NodeRef nodeRef = this.getPackage();
|
||||
if (nodeRef != null)
|
||||
{
|
||||
return new TemplateNode(nodeRef, this.services, this.resolver);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the resources from the package attached to this workflow task
|
||||
*/
|
||||
public List<TemplateContent> getPackageResources()
|
||||
{
|
||||
List<TemplateContent> resources = new ArrayList<TemplateContent>();
|
||||
List<NodeRef> contents = this.services.getWorkflowService().getPackageContents(this.task.id);
|
||||
|
||||
NodeService nodeService = this.services.getNodeService();
|
||||
DictionaryService ddService = this.services.getDictionaryService();
|
||||
|
||||
for(NodeRef nodeRef : contents)
|
||||
{
|
||||
QName type = nodeService.getType(nodeRef);
|
||||
|
||||
// make sure the type is defined in the data dictionary
|
||||
if (ddService.getType(type) != null)
|
||||
{
|
||||
// look for content nodes or links to content
|
||||
// NOTE: folders within workflow packages are ignored for now
|
||||
if (ddService.isSubClass(type, ContentModel.TYPE_CONTENT) ||
|
||||
ApplicationModel.TYPE_FILELINK.equals(type))
|
||||
{
|
||||
resources.add(new TemplateNode(nodeRef, this.services, this.resolver));
|
||||
}
|
||||
}
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the 'outcome' label from a completed task
|
||||
*/
|
||||
public String getOutcome()
|
||||
{
|
||||
String outcome = null;
|
||||
if (task.state.equals(WorkflowTaskState.COMPLETED))
|
||||
{
|
||||
// add the outcome label for any completed task
|
||||
String transition = (String)task.properties.get(WorkflowModel.PROP_OUTCOME);
|
||||
if (transition != null)
|
||||
{
|
||||
WorkflowTransition[] transitions = this.task.definition.node.transitions;
|
||||
for (WorkflowTransition trans : transitions)
|
||||
{
|
||||
if (trans.id.equals(transition))
|
||||
{
|
||||
outcome = trans.title;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A map of properties for the workflow task, includes all appropriate bpm model properties.
|
||||
*/
|
||||
public Map<String, Serializable> getProperties()
|
||||
{
|
||||
if (this.properties == null)
|
||||
{
|
||||
// convert properties to a QName accessable Map with TemplateNode objects as required
|
||||
PropertyConverter converter = new PropertyConverter();
|
||||
this.properties = new QNameMap<String, Serializable>(this);
|
||||
for (QName qname : this.task.properties.keySet())
|
||||
{
|
||||
Serializable value = converter.convertProperty(
|
||||
this.task.properties.get(qname), qname, this.services, this.resolver);
|
||||
this.properties.put(qname.toString(), value);
|
||||
}
|
||||
}
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public NamespacePrefixResolver getNamespacePrefixResolver()
|
||||
{
|
||||
return this.services.getNamespaceService();
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTransition;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolverProvider;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNameMap;
|
||||
|
||||
/**
|
||||
* Workflow and task support in FreeMarker templates.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class Workflow extends BaseTemplateProcessorExtension
|
||||
{
|
||||
private ServiceRegistry services;
|
||||
|
||||
/**
|
||||
* Sets the service registry
|
||||
*
|
||||
* @param services the service registry
|
||||
*/
|
||||
public void setServiceRegistry(ServiceRegistry services)
|
||||
{
|
||||
this.services = services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of objects representing the assigned tasks for the current user
|
||||
*
|
||||
* @return list of WorkflowTaskItem bean objects {@link WorkflowTaskItem}
|
||||
*/
|
||||
public List<WorkflowTaskItem> getAssignedTasks()
|
||||
{
|
||||
// get the "in progress" tasks for the current user
|
||||
List<WorkflowTask> tasks = getWorkflowService().getAssignedTasks(
|
||||
this.services.getAuthenticationService().getCurrentUserName(),
|
||||
WorkflowTaskState.IN_PROGRESS);
|
||||
|
||||
return convertTasks(tasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of objects representing the pooled tasks for the current user
|
||||
*
|
||||
* @return list of WorkflowTaskItem bean objects {@link WorkflowTaskItem}
|
||||
*/
|
||||
public List<WorkflowTaskItem> getPooledTasks()
|
||||
{
|
||||
// get the "pooled" tasks for the current user
|
||||
List<WorkflowTask> tasks = getWorkflowService().getPooledTasks(
|
||||
this.services.getAuthenticationService().getCurrentUserName());
|
||||
|
||||
return convertTasks(tasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of objects representing the completed tasks for the current user
|
||||
*
|
||||
* @return list of WorkflowTaskItem bean objects {@link WorkflowTaskItem}
|
||||
*/
|
||||
public List<WorkflowTaskItem> getCompletedTasks()
|
||||
{
|
||||
// get the "completed" tasks for the current user
|
||||
List<WorkflowTask> tasks = getWorkflowService().getAssignedTasks(
|
||||
this.services.getAuthenticationService().getCurrentUserName(),
|
||||
WorkflowTaskState.COMPLETED);
|
||||
|
||||
return convertTasks(tasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single object representing a task of the given taskId for the current user
|
||||
*
|
||||
* @return WorkflowTaskItem bean object {@link WorkflowTaskItem}
|
||||
*/
|
||||
public WorkflowTaskItem getTaskById(String taskId)
|
||||
{
|
||||
// get the task corresponding to the given taskId
|
||||
WorkflowTask task = getWorkflowService().getTaskById(taskId);
|
||||
|
||||
return new WorkflowTaskItem(this.services, getTemplateImageResolver(), task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list of WorkflowTask items into bean objects accessable from templates
|
||||
*
|
||||
* @param tasks List of WorkflowTask objects to convert
|
||||
*
|
||||
* @return List of WorkflowTaskItem bean wrapper objects
|
||||
*/
|
||||
private List<WorkflowTaskItem> convertTasks(List<WorkflowTask> tasks)
|
||||
{
|
||||
List<WorkflowTaskItem> items = new ArrayList<WorkflowTaskItem>(tasks.size());
|
||||
for (WorkflowTask task : tasks)
|
||||
{
|
||||
items.add(new WorkflowTaskItem(this.services, getTemplateImageResolver(), task));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private WorkflowService getWorkflowService()
|
||||
{
|
||||
return this.services.getWorkflowService();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple bean wrapper around a WorkflowTask item
|
||||
*/
|
||||
public static class WorkflowTaskItem implements NamespacePrefixResolverProvider
|
||||
{
|
||||
private WorkflowTask task;
|
||||
private QNameMap<String, Serializable> properties = null;
|
||||
private ServiceRegistry services;
|
||||
private TemplateImageResolver resolver;
|
||||
|
||||
public WorkflowTaskItem(ServiceRegistry services, TemplateImageResolver resolver, WorkflowTask task)
|
||||
{
|
||||
this.task = task;
|
||||
this.services = services;
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return this.task.title;
|
||||
}
|
||||
|
||||
public String getQnameType()
|
||||
{
|
||||
return this.task.definition.metadata.getName().toString();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.task.description;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return this.task.path.instance.description;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return this.task.id;
|
||||
}
|
||||
|
||||
public boolean getIsCompleted()
|
||||
{
|
||||
return (this.task.state == WorkflowTaskState.COMPLETED);
|
||||
}
|
||||
|
||||
public Date getStartDate()
|
||||
{
|
||||
return this.task.path.instance.startDate;
|
||||
}
|
||||
|
||||
public Map<String, String>[] getTransitions()
|
||||
{
|
||||
Map<String, String>[] tranMaps = null;
|
||||
WorkflowTransition[] transitions = this.task.definition.node.transitions;
|
||||
if (transitions != null)
|
||||
{
|
||||
tranMaps = new HashMap[transitions.length];
|
||||
for (int i=0; i<transitions.length; i++)
|
||||
{
|
||||
tranMaps[i] = new HashMap<String, String>(2, 1.0f);
|
||||
tranMaps[i].put("label", transitions[i].title);
|
||||
tranMaps[i].put("id", transitions[i].id);
|
||||
}
|
||||
}
|
||||
return (tranMaps != null ? tranMaps : new HashMap[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A TemplateNode representing the initiator (person) of the workflow
|
||||
*/
|
||||
public TemplateNode getInitiator()
|
||||
{
|
||||
return new TemplateNode(this.task.path.instance.initiator, this.services, this.resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The workflow package ref
|
||||
*/
|
||||
public NodeRef getPackage()
|
||||
{
|
||||
return (NodeRef)this.task.properties.get(WorkflowModel.ASSOC_PACKAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The workflow package ref as a TemplateNode
|
||||
*/
|
||||
public TemplateNode getPackageTemplateNode()
|
||||
{
|
||||
NodeRef nodeRef = this.getPackage();
|
||||
if (nodeRef != null)
|
||||
{
|
||||
return new TemplateNode(nodeRef, this.services, this.resolver);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the resources from the package attached to this workflow task
|
||||
*/
|
||||
public List<TemplateContent> getPackageResources()
|
||||
{
|
||||
List<TemplateContent> resources = new ArrayList<TemplateContent>();
|
||||
List<NodeRef> contents = this.services.getWorkflowService().getPackageContents(this.task.id);
|
||||
|
||||
NodeService nodeService = this.services.getNodeService();
|
||||
DictionaryService ddService = this.services.getDictionaryService();
|
||||
|
||||
for(NodeRef nodeRef : contents)
|
||||
{
|
||||
QName type = nodeService.getType(nodeRef);
|
||||
|
||||
// make sure the type is defined in the data dictionary
|
||||
if (ddService.getType(type) != null)
|
||||
{
|
||||
// look for content nodes or links to content
|
||||
// NOTE: folders within workflow packages are ignored for now
|
||||
if (ddService.isSubClass(type, ContentModel.TYPE_CONTENT) ||
|
||||
ApplicationModel.TYPE_FILELINK.equals(type))
|
||||
{
|
||||
resources.add(new TemplateNode(nodeRef, this.services, this.resolver));
|
||||
}
|
||||
}
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the 'outcome' label from a completed task
|
||||
*/
|
||||
public String getOutcome()
|
||||
{
|
||||
String outcome = null;
|
||||
if (task.state.equals(WorkflowTaskState.COMPLETED))
|
||||
{
|
||||
// add the outcome label for any completed task
|
||||
String transition = (String)task.properties.get(WorkflowModel.PROP_OUTCOME);
|
||||
if (transition != null)
|
||||
{
|
||||
WorkflowTransition[] transitions = this.task.definition.node.transitions;
|
||||
for (WorkflowTransition trans : transitions)
|
||||
{
|
||||
if (trans.id.equals(transition))
|
||||
{
|
||||
outcome = trans.title;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A map of properties for the workflow task, includes all appropriate bpm model properties.
|
||||
*/
|
||||
public Map<String, Serializable> getProperties()
|
||||
{
|
||||
if (this.properties == null)
|
||||
{
|
||||
// convert properties to a QName accessable Map with TemplateNode objects as required
|
||||
PropertyConverter converter = new PropertyConverter();
|
||||
this.properties = new QNameMap<String, Serializable>(this);
|
||||
for (QName qname : this.task.properties.keySet())
|
||||
{
|
||||
Serializable value = converter.convertProperty(
|
||||
this.task.properties.get(qname), qname, this.services, this.resolver);
|
||||
this.properties.put(qname.toString(), value);
|
||||
}
|
||||
}
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public NamespacePrefixResolver getNamespacePrefixResolver()
|
||||
{
|
||||
return this.services.getNamespaceService();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user