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:
Raluca Munteanu
2016-04-26 13:03:25 +00:00
parent 9a889c69ea
commit 386a4aca06
327 changed files with 55062 additions and 55062 deletions

View File

@@ -1,157 +1,157 @@
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.rest.api.Activities;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.impl.activities.ActivitySummaryParser;
import org.alfresco.rest.api.model.Activity;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.json.JSONException;
/**
* Centralises access to activities services and maps between representations.
*
* @author steveglover
*
*/
public class ActivitiesImpl implements Activities
{
private static final String ACTIVITIES_FORMAT = "json";
private People people;
private ActivityService activityService;
private ActivitySummaryParser activitySummaryParser;
private TenantService tenantService;
private Sites sites;
public void setSites(Sites sites)
{
this.sites = sites;
}
public void setPeople(People people)
{
this.people = people;
}
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public void setActivityService(ActivityService activityService)
{
this.activityService = activityService;
}
public void setActivitySummaryParser(ActivitySummaryParser activitySummaryParser)
{
this.activitySummaryParser = activitySummaryParser;
}
public Map<String, Object> getActivitySummary(ActivityFeedEntity entity) throws JSONException
{
Map<String, Object> activitySummary = activitySummaryParser.parse(entity.getActivityType(), entity.getActivitySummary());
return activitySummary;
}
private String getSiteId(String siteNetwork)
{
String siteId = siteNetwork;
int idx = siteNetwork.lastIndexOf(TenantService.SEPARATOR);
if(idx != -1)
{
siteId = siteNetwork.substring(idx + 1);
}
return siteId;
}
public CollectionWithPagingInfo<Activity> getUserActivities(String personId, final Parameters parameters)
{
personId = people.validatePerson(personId);
Paging paging = parameters.getPaging();
String siteId = parameters.getParameter("siteId");
String who = parameters.getParameter("who");
ActivityWho activityWho = null;
if(who != null)
{
try
{
activityWho = ActivityWho.valueOf(who);
}
catch(IllegalArgumentException e)
{
throw new InvalidArgumentException("Parameter who should be one of " + Arrays.toString(ActivityWho.values()));
}
}
if(siteId != null && !siteId.equals(""))
{
SiteInfo siteInfo = sites.validateSite(siteId);
if(siteInfo == null)
{
// site does not exist
throw new EntityNotFoundException(siteId);
}
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
siteId = siteInfo.getShortName();
}
try
{
PagingResults<ActivityFeedEntity> activities = null;
if(activityWho == null)
{
activities = activityService.getPagedUserFeedEntries(personId, siteId, false, false, -1, Util.getPagingRequest(paging));
}
else if(activityWho.equals(ActivityWho.me))
{
activities = activityService.getPagedUserFeedEntries(personId, siteId, false, true, -1, Util.getPagingRequest(paging));
}
else if(activityWho.equals(ActivityWho.others))
{
activities = activityService.getPagedUserFeedEntries(personId, siteId, true, false, -1, Util.getPagingRequest(paging));
}
else
{
throw new InvalidArgumentException("Who argument is invalid.");
}
List<ActivityFeedEntity> feedEntities = activities.getPage();
List<Activity> ret = new ArrayList<Activity>(feedEntities.size());
for(ActivityFeedEntity entity : feedEntities)
{
String feedSiteId = getSiteId(entity.getSiteNetwork());
String networkId = tenantService.getDomain(entity.getSiteNetwork());
Activity activity = new Activity(entity.getId(), networkId, feedSiteId, entity.getFeedUserId(), entity.getPostUserId(),
entity.getPostDate(), entity.getActivityType(), getActivitySummary(entity));
ret.add(activity);
}
return CollectionWithPagingInfo.asPaged(paging, ret, activities.hasMoreItems(), activities.getTotalResultCount().getFirst());
}
catch(JSONException e)
{
throw new AlfrescoRuntimeException("", e);
}
}
}
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.rest.api.Activities;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.impl.activities.ActivitySummaryParser;
import org.alfresco.rest.api.model.Activity;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.json.JSONException;
/**
* Centralises access to activities services and maps between representations.
*
* @author steveglover
*
*/
public class ActivitiesImpl implements Activities
{
private static final String ACTIVITIES_FORMAT = "json";
private People people;
private ActivityService activityService;
private ActivitySummaryParser activitySummaryParser;
private TenantService tenantService;
private Sites sites;
public void setSites(Sites sites)
{
this.sites = sites;
}
public void setPeople(People people)
{
this.people = people;
}
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public void setActivityService(ActivityService activityService)
{
this.activityService = activityService;
}
public void setActivitySummaryParser(ActivitySummaryParser activitySummaryParser)
{
this.activitySummaryParser = activitySummaryParser;
}
public Map<String, Object> getActivitySummary(ActivityFeedEntity entity) throws JSONException
{
Map<String, Object> activitySummary = activitySummaryParser.parse(entity.getActivityType(), entity.getActivitySummary());
return activitySummary;
}
private String getSiteId(String siteNetwork)
{
String siteId = siteNetwork;
int idx = siteNetwork.lastIndexOf(TenantService.SEPARATOR);
if(idx != -1)
{
siteId = siteNetwork.substring(idx + 1);
}
return siteId;
}
public CollectionWithPagingInfo<Activity> getUserActivities(String personId, final Parameters parameters)
{
personId = people.validatePerson(personId);
Paging paging = parameters.getPaging();
String siteId = parameters.getParameter("siteId");
String who = parameters.getParameter("who");
ActivityWho activityWho = null;
if(who != null)
{
try
{
activityWho = ActivityWho.valueOf(who);
}
catch(IllegalArgumentException e)
{
throw new InvalidArgumentException("Parameter who should be one of " + Arrays.toString(ActivityWho.values()));
}
}
if(siteId != null && !siteId.equals(""))
{
SiteInfo siteInfo = sites.validateSite(siteId);
if(siteInfo == null)
{
// site does not exist
throw new EntityNotFoundException(siteId);
}
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
siteId = siteInfo.getShortName();
}
try
{
PagingResults<ActivityFeedEntity> activities = null;
if(activityWho == null)
{
activities = activityService.getPagedUserFeedEntries(personId, siteId, false, false, -1, Util.getPagingRequest(paging));
}
else if(activityWho.equals(ActivityWho.me))
{
activities = activityService.getPagedUserFeedEntries(personId, siteId, false, true, -1, Util.getPagingRequest(paging));
}
else if(activityWho.equals(ActivityWho.others))
{
activities = activityService.getPagedUserFeedEntries(personId, siteId, true, false, -1, Util.getPagingRequest(paging));
}
else
{
throw new InvalidArgumentException("Who argument is invalid.");
}
List<ActivityFeedEntity> feedEntities = activities.getPage();
List<Activity> ret = new ArrayList<Activity>(feedEntities.size());
for(ActivityFeedEntity entity : feedEntities)
{
String feedSiteId = getSiteId(entity.getSiteNetwork());
String networkId = tenantService.getDomain(entity.getSiteNetwork());
Activity activity = new Activity(entity.getId(), networkId, feedSiteId, entity.getFeedUserId(), entity.getPostUserId(),
entity.getPostDate(), entity.getActivityType(), getActivitySummary(entity));
ret.add(activity);
}
return CollectionWithPagingInfo.asPaged(paging, ret, activities.hasMoreItems(), activities.getTotalResultCount().getFirst());
}
catch(JSONException e)
{
throw new AlfrescoRuntimeException("", e);
}
}
}

View File

@@ -1,230 +1,230 @@
package org.alfresco.rest.api.impl;
import java.io.Serializable;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.forum.CommentService;
import org.alfresco.rest.api.Comments;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Comment;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.TypeConstraint;
/**
* Centralises access to comment services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class CommentsImpl implements Comments
{
private Nodes nodes;
private NodeService nodeService;
private CommentService commentService;
private ContentService contentService;
private LockService lockService;
private PermissionService permissionService;
private TypeConstraint typeConstraint;
public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setLockService(LockService lockService)
{
this.lockService = lockService;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setCommentService(CommentService commentService)
{
this.commentService = commentService;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
private Comment toComment(NodeRef nodeRef, NodeRef commentNodeRef)
{
Map<QName, Serializable> nodeProps = nodeService.getProperties(commentNodeRef);
ContentReader reader = contentService.getReader(commentNodeRef, ContentModel.PROP_CONTENT);
if(reader != null)
{
String content = reader.getContentString();
nodeProps.put(Comment.PROP_COMMENT_CONTENT, content);
nodeProps.remove(ContentModel.PROP_CONTENT);
}
boolean canEdit = true;
boolean canDelete = true;
boolean isNodeLocked = false;
boolean isWorkingCopy = false;
if(nodeRef != null)
{
Set<QName> aspects = nodeService.getAspects(nodeRef);
isWorkingCopy = aspects.contains(ContentModel.ASPECT_WORKING_COPY);
if(!isWorkingCopy)
{
if(aspects.contains(ContentModel.ASPECT_LOCKABLE))
{
LockStatus lockStatus = lockService.getLockStatus(nodeRef);
if (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER)
{
isNodeLocked = true;
}
}
}
}
if(isNodeLocked || isWorkingCopy)
{
canEdit = false;
canDelete = false;
}
else
{
canEdit = permissionService.hasPermission(commentNodeRef, PermissionService.WRITE) == AccessStatus.ALLOWED;
canDelete = permissionService.hasPermission(commentNodeRef, PermissionService.DELETE) == AccessStatus.ALLOWED;
}
Comment comment = new Comment(commentNodeRef.getId(), nodeProps, canEdit, canDelete);
return comment;
}
public Comment createComment(String nodeId, Comment comment)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
if(!typeConstraint.matches(nodeRef))
{
throw new UnsupportedResourceOperationException("Cannot comment on this node");
}
try
{
NodeRef commentNode = commentService.createComment(nodeRef, comment.getTitle(), comment.getContent(), false);
return toComment(nodeRef, commentNode);
}
catch(IllegalArgumentException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public Comment updateComment(String nodeId, Comment comment)
{
try
{
NodeRef nodeRef = nodes.validateNode(nodeId);
String commentNodeId = comment.getId();
NodeRef commentNodeRef = nodes.validateNode(commentNodeId);
String title = comment.getTitle();
String content = comment.getContent();
if(content == null)
{
throw new InvalidArgumentException();
}
commentService.updateComment(commentNodeRef, title, content);
return toComment(nodeRef, commentNodeRef);
}
catch(IllegalArgumentException e)
{
throw new ConstraintViolatedException(e.getMessage());
}
}
public CollectionWithPagingInfo<Comment> getComments(String nodeId, Paging paging)
{
final NodeRef nodeRef = nodes.validateNode(nodeId);
/* MNT-10536 : fix */
final Set<QName> contentAndFolders =
new HashSet<QName>(Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT));
if (!nodes.nodeMatches(nodeRef, contentAndFolders, null))
{
throw new InvalidArgumentException("NodeId of folder or content is expected");
}
PagingRequest pagingRequest = Util.getPagingRequest(paging);
final PagingResults<NodeRef> pagingResults = commentService.listComments(nodeRef, pagingRequest);
final List<NodeRef> page = pagingResults.getPage();
List<Comment> comments = new AbstractList<Comment>()
{
@Override
public Comment get(int index)
{
return toComment(nodeRef, page.get(index));
}
@Override
public int size()
{
return page.size();
}
};
return CollectionWithPagingInfo.asPaged(paging, comments, pagingResults.hasMoreItems(), pagingResults.getTotalResultCount().getFirst());
}
@Override
// TODO validate that it is a comment of the node
public void deleteComment(String nodeId, String commentNodeId)
{
try
{
nodes.validateNode(nodeId);
NodeRef commentNodeRef = nodes.validateNode(commentNodeId);
commentService.deleteComment(commentNodeRef);
}
catch(IllegalArgumentException e)
{
throw new ConstraintViolatedException(e.getMessage());
}
}
}
package org.alfresco.rest.api.impl;
import java.io.Serializable;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.forum.CommentService;
import org.alfresco.rest.api.Comments;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Comment;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.TypeConstraint;
/**
* Centralises access to comment services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class CommentsImpl implements Comments
{
private Nodes nodes;
private NodeService nodeService;
private CommentService commentService;
private ContentService contentService;
private LockService lockService;
private PermissionService permissionService;
private TypeConstraint typeConstraint;
public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setLockService(LockService lockService)
{
this.lockService = lockService;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setCommentService(CommentService commentService)
{
this.commentService = commentService;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
private Comment toComment(NodeRef nodeRef, NodeRef commentNodeRef)
{
Map<QName, Serializable> nodeProps = nodeService.getProperties(commentNodeRef);
ContentReader reader = contentService.getReader(commentNodeRef, ContentModel.PROP_CONTENT);
if(reader != null)
{
String content = reader.getContentString();
nodeProps.put(Comment.PROP_COMMENT_CONTENT, content);
nodeProps.remove(ContentModel.PROP_CONTENT);
}
boolean canEdit = true;
boolean canDelete = true;
boolean isNodeLocked = false;
boolean isWorkingCopy = false;
if(nodeRef != null)
{
Set<QName> aspects = nodeService.getAspects(nodeRef);
isWorkingCopy = aspects.contains(ContentModel.ASPECT_WORKING_COPY);
if(!isWorkingCopy)
{
if(aspects.contains(ContentModel.ASPECT_LOCKABLE))
{
LockStatus lockStatus = lockService.getLockStatus(nodeRef);
if (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER)
{
isNodeLocked = true;
}
}
}
}
if(isNodeLocked || isWorkingCopy)
{
canEdit = false;
canDelete = false;
}
else
{
canEdit = permissionService.hasPermission(commentNodeRef, PermissionService.WRITE) == AccessStatus.ALLOWED;
canDelete = permissionService.hasPermission(commentNodeRef, PermissionService.DELETE) == AccessStatus.ALLOWED;
}
Comment comment = new Comment(commentNodeRef.getId(), nodeProps, canEdit, canDelete);
return comment;
}
public Comment createComment(String nodeId, Comment comment)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
if(!typeConstraint.matches(nodeRef))
{
throw new UnsupportedResourceOperationException("Cannot comment on this node");
}
try
{
NodeRef commentNode = commentService.createComment(nodeRef, comment.getTitle(), comment.getContent(), false);
return toComment(nodeRef, commentNode);
}
catch(IllegalArgumentException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public Comment updateComment(String nodeId, Comment comment)
{
try
{
NodeRef nodeRef = nodes.validateNode(nodeId);
String commentNodeId = comment.getId();
NodeRef commentNodeRef = nodes.validateNode(commentNodeId);
String title = comment.getTitle();
String content = comment.getContent();
if(content == null)
{
throw new InvalidArgumentException();
}
commentService.updateComment(commentNodeRef, title, content);
return toComment(nodeRef, commentNodeRef);
}
catch(IllegalArgumentException e)
{
throw new ConstraintViolatedException(e.getMessage());
}
}
public CollectionWithPagingInfo<Comment> getComments(String nodeId, Paging paging)
{
final NodeRef nodeRef = nodes.validateNode(nodeId);
/* MNT-10536 : fix */
final Set<QName> contentAndFolders =
new HashSet<QName>(Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT));
if (!nodes.nodeMatches(nodeRef, contentAndFolders, null))
{
throw new InvalidArgumentException("NodeId of folder or content is expected");
}
PagingRequest pagingRequest = Util.getPagingRequest(paging);
final PagingResults<NodeRef> pagingResults = commentService.listComments(nodeRef, pagingRequest);
final List<NodeRef> page = pagingResults.getPage();
List<Comment> comments = new AbstractList<Comment>()
{
@Override
public Comment get(int index)
{
return toComment(nodeRef, page.get(index));
}
@Override
public int size()
{
return page.size();
}
};
return CollectionWithPagingInfo.asPaged(paging, comments, pagingResults.hasMoreItems(), pagingResults.getTotalResultCount().getFirst());
}
@Override
// TODO validate that it is a comment of the node
public void deleteComment(String nodeId, String commentNodeId)
{
try
{
nodes.validateNode(nodeId);
NodeRef commentNodeRef = nodes.validateNode(commentNodeId);
commentService.deleteComment(commentNodeRef);
}
catch(IllegalArgumentException e)
{
throw new ConstraintViolatedException(e.getMessage());
}
}
}

View File

@@ -1,30 +1,30 @@
package org.alfresco.rest.api.impl;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
/**
* Translates access denied exceptions from the service layer to API not found exception.
*
* @author steveglover
*
*/
public class DefaultExceptionHandler implements ExceptionHandler
{
@Override
public boolean handle(Throwable t)
{
if(t instanceof AccessDeniedException)
{
// Note: security, no message to indicate why
throw new NotFoundException();
}
else if(t instanceof PermissionDeniedException)
{
// Note: security, no message to indicate why
throw new NotFoundException();
}
return false;
}
}
package org.alfresco.rest.api.impl;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
/**
* Translates access denied exceptions from the service layer to API not found exception.
*
* @author steveglover
*
*/
public class DefaultExceptionHandler implements ExceptionHandler
{
@Override
public boolean handle(Throwable t)
{
if(t instanceof AccessDeniedException)
{
// Note: security, no message to indicate why
throw new NotFoundException();
}
else if(t instanceof PermissionDeniedException)
{
// Note: security, no message to indicate why
throw new NotFoundException();
}
return false;
}
}

View File

@@ -1,6 +1,6 @@
package org.alfresco.rest.api.impl;
public interface ExceptionHandler
{
boolean handle(Throwable t);
}
package org.alfresco.rest.api.impl;
public interface ExceptionHandler
{
boolean handle(Throwable t);
}

View File

@@ -1,46 +1,46 @@
package org.alfresco.rest.api.impl;
import java.util.List;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* An interceptor that catches exceptions and handlers them in some way, possibly by re-throwing as a different exception.
*
* @author steveglover
*
*/
public class ExceptionInterceptor implements MethodInterceptor
{
private List<ExceptionHandler> exceptionHandlers;
public void setExceptionHandlers(List<ExceptionHandler> exceptionHandlers)
{
this.exceptionHandlers = exceptionHandlers;
}
public ExceptionInterceptor()
{
super();
}
public Object invoke(MethodInvocation mi) throws Throwable
{
try
{
return mi.proceed();
}
catch(Throwable t)
{
for(ExceptionHandler handler : exceptionHandlers)
{
if(handler.handle(t))
{
break;
}
}
throw t;
}
}
}
package org.alfresco.rest.api.impl;
import java.util.List;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* An interceptor that catches exceptions and handlers them in some way, possibly by re-throwing as a different exception.
*
* @author steveglover
*
*/
public class ExceptionInterceptor implements MethodInterceptor
{
private List<ExceptionHandler> exceptionHandlers;
public void setExceptionHandlers(List<ExceptionHandler> exceptionHandlers)
{
this.exceptionHandlers = exceptionHandlers;
}
public ExceptionInterceptor()
{
super();
}
public Object invoke(MethodInvocation mi) throws Throwable
{
try
{
return mi.proceed();
}
catch(Throwable t)
{
for(ExceptionHandler handler : exceptionHandlers)
{
if(handler.handle(t))
{
break;
}
}
throw t;
}
}
}

View File

@@ -1,91 +1,91 @@
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.opencmis.dictionary.QNameFilter;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Stores a set of excluded types, by full type name. The localName can be a wildcard (*) to indicate that the
* whole namespace should be excluded.
*
* @author steveglover
*
*/
public class ExcludedTypes
{
private List<QName> expectedTypes;
private QNameFilter excludedTypes;
private NodeService nodeService;
public void setExpectedTypes(List<String> expectedTypes)
{
if(expectedTypes != null && expectedTypes.size() > 0)
{
this.expectedTypes = new ArrayList<QName>(expectedTypes.size());
for(String type : expectedTypes)
{
final QName typeDef = QName.createQName(type);
this.expectedTypes.add(typeDef);
}
}
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setExcludedTypes(QNameFilter excludedTypes)
{
this.excludedTypes = excludedTypes;
}
public boolean isExcluded(final NodeRef nodeRef)
{
boolean excluded = false;
QName nodeType = nodeService.getType(nodeRef);
if(expectedTypes != null && !expectedTypes.contains(nodeType))
{
excluded = true;
}
if(!excluded)
{
// need to run as system - caller may not be able to read the node's aspects
// but we need to know what they are in order to determine exclusion.
excluded = TenantUtil.runAsSystemTenant(new TenantRunAsWork<Boolean>()
{
@Override
public Boolean doWork() throws Exception
{
boolean excluded = false;
// the node is a content node. Make sure it doesn't have an aspect in the excluded list.
Set<QName> aspects = new HashSet<QName>(nodeService.getAspects(nodeRef));
for(QName aspect : aspects)
{
if(excludedTypes.isExcluded(aspect))
{
excluded = true;
break;
}
}
return excluded;
}
}, TenantUtil.getCurrentDomain());
}
return excluded;
}
}
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.opencmis.dictionary.QNameFilter;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Stores a set of excluded types, by full type name. The localName can be a wildcard (*) to indicate that the
* whole namespace should be excluded.
*
* @author steveglover
*
*/
public class ExcludedTypes
{
private List<QName> expectedTypes;
private QNameFilter excludedTypes;
private NodeService nodeService;
public void setExpectedTypes(List<String> expectedTypes)
{
if(expectedTypes != null && expectedTypes.size() > 0)
{
this.expectedTypes = new ArrayList<QName>(expectedTypes.size());
for(String type : expectedTypes)
{
final QName typeDef = QName.createQName(type);
this.expectedTypes.add(typeDef);
}
}
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setExcludedTypes(QNameFilter excludedTypes)
{
this.excludedTypes = excludedTypes;
}
public boolean isExcluded(final NodeRef nodeRef)
{
boolean excluded = false;
QName nodeType = nodeService.getType(nodeRef);
if(expectedTypes != null && !expectedTypes.contains(nodeType))
{
excluded = true;
}
if(!excluded)
{
// need to run as system - caller may not be able to read the node's aspects
// but we need to know what they are in order to determine exclusion.
excluded = TenantUtil.runAsSystemTenant(new TenantRunAsWork<Boolean>()
{
@Override
public Boolean doWork() throws Exception
{
boolean excluded = false;
// the node is a content node. Make sure it doesn't have an aspect in the excluded list.
Set<QName> aspects = new HashSet<QName>(nodeService.getAspects(nodeRef));
for(QName aspect : aspects)
{
if(excludedTypes.isExcluded(aspect))
{
excluded = true;
break;
}
}
return excluded;
}
}, TenantUtil.getCurrentDomain());
}
return excluded;
}
}

View File

@@ -1,307 +1,307 @@
package org.alfresco.rest.api.impl;
import java.util.AbstractList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.favourites.PersonFavourite;
import org.alfresco.repo.site.SiteDoesNotExistException;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.rest.api.Favourites;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.model.Document;
import org.alfresco.rest.api.model.DocumentTarget;
import org.alfresco.rest.api.model.Favourite;
import org.alfresco.rest.api.model.Folder;
import org.alfresco.rest.api.model.FolderTarget;
import org.alfresco.rest.api.model.Site;
import org.alfresco.rest.api.model.SiteImpl;
import org.alfresco.rest.api.model.SiteTarget;
import org.alfresco.rest.api.model.Target;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper.WalkerCallbackAdapter;
import org.alfresco.service.cmr.favourites.FavouritesService;
import org.alfresco.service.cmr.favourites.FavouritesService.Type;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Public REST API: Centralises access to favourites functionality and maps between representations repository and api representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class FavouritesImpl implements Favourites
{
private static final Log logger = LogFactory.getLog(FavouritesImpl.class);
private People people;
private Sites sites;
private Nodes nodes;
private FavouritesService favouritesService;
private SiteService siteService;
public void setPeople(People people)
{
this.people = people;
}
public void setSites(Sites sites)
{
this.sites = sites;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setFavouritesService(FavouritesService favouritesService)
{
this.favouritesService = favouritesService;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
private Target getTarget(PersonFavourite personFavourite)
{
Target target = null;
NodeRef nodeRef = personFavourite.getNodeRef();
Type type = personFavourite.getType();
if(type.equals(Type.FILE))
{
Document document = nodes.getDocument(nodeRef);
target = new DocumentTarget(document);
}
else if(type.equals(Type.FOLDER))
{
Folder folder = nodes.getFolder(nodeRef);
target = new FolderTarget(folder);
}
else if(type.equals(Type.SITE))
{
SiteInfo siteInfo = siteService.getSite(nodeRef);
String role = sites.getSiteRole(siteInfo.getShortName());
Site site = new SiteImpl(siteInfo, role);
target = new SiteTarget(site);
}
else
{
throw new AlfrescoRuntimeException("Unexpected favourite target type: " + type);
}
return target;
}
private Favourite getFavourite(PersonFavourite personFavourite)
{
Favourite fav = new Favourite();
fav.setTargetGuid(personFavourite.getNodeRef().getId());
fav.setCreatedAt(personFavourite.getCreatedAt());
Target target = getTarget(personFavourite);
fav.setTarget(target);
return fav;
}
private CollectionWithPagingInfo<Favourite> wrap(Paging paging, PagingResults<PersonFavourite> personFavourites)
{
final List<PersonFavourite> page = personFavourites.getPage();
final List<Favourite> list = new AbstractList<Favourite>()
{
@Override
public Favourite get(int index)
{
PersonFavourite personFavourite = page.get(index);
Favourite fav = getFavourite(personFavourite);
return fav;
}
@Override
public int size()
{
return page.size();
}
};
Pair<Integer, Integer> pair = personFavourites.getTotalResultCount();
Integer total = null;
if(pair.getFirst().equals(pair.getSecond()))
{
total = pair.getFirst();
}
return CollectionWithPagingInfo.asPaged(paging, list, personFavourites.hasMoreItems(), total);
}
@Override
public Favourite addFavourite(String personId, Favourite favourite)
{
Favourite ret = null;
personId = people.validatePerson(personId, true);
Target target = favourite.getTarget();
if(target == null)
{
throw new InvalidArgumentException("target is missing");
}
else if(target instanceof SiteTarget)
{
SiteTarget siteTarget = (SiteTarget)target;
NodeRef guid = siteTarget.getSite().getGuid();
SiteInfo siteInfo = sites.validateSite(guid);
NodeRef siteNodeRef = siteInfo.getNodeRef();
String siteId = siteInfo.getShortName();
try
{
PersonFavourite personFavourite = favouritesService.addFavourite(personId, siteNodeRef);
ret = getFavourite(personFavourite);
}
catch(SiteDoesNotExistException e)
{
throw new RelationshipResourceNotFoundException(personId, siteId);
}
}
else if(target instanceof DocumentTarget)
{
DocumentTarget documentTarget = (DocumentTarget)target;
NodeRef nodeRef = documentTarget.getFile().getGuid();
if(!nodes.nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_CONTENT), null))
{
throw new RelationshipResourceNotFoundException(personId, nodeRef.getId());
}
PersonFavourite personFavourite = favouritesService.addFavourite(personId, nodeRef);
ret = getFavourite(personFavourite);
}
else if(target instanceof FolderTarget)
{
FolderTarget folderTarget = (FolderTarget)target;
NodeRef nodeRef = folderTarget.getFolder().getGuid();
if(!nodes.nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), Collections.singleton(SiteModel.TYPE_SITE)))
{
throw new RelationshipResourceNotFoundException(personId, nodeRef.getId());
}
PersonFavourite personFavourite = favouritesService.addFavourite(personId, nodeRef);
ret = getFavourite(personFavourite);
}
return ret;
}
@Override
public void removeFavourite(String personId, String id)
{
personId = people.validatePerson(personId, true);
NodeRef nodeRef = nodes.validateNode(id);
boolean exists = false;
Type type = favouritesService.getType(nodeRef);
if(type.equals(Type.SITE))
{
SiteInfo siteInfo = siteService.getSite(nodeRef);
if(siteInfo == null)
{
// shouldn't happen because the type implies it's a site
throw new AlfrescoRuntimeException("Unable to find site with nodeRef " + nodeRef);
}
exists = favouritesService.removeFavourite(personId, siteInfo.getNodeRef());
}
else if(type.equals(Type.FILE))
{
exists = favouritesService.removeFavourite(personId, nodeRef);
}
else if(type.equals(Type.FOLDER))
{
exists = favouritesService.removeFavourite(personId, nodeRef);
}
if(!exists)
{
throw new RelationshipResourceNotFoundException(personId, id);
}
}
public Favourite getFavourite(String personId, String favouriteId)
{
NodeRef nodeRef = nodes.validateNode(favouriteId);
personId = people.validatePerson(personId, true);
PersonFavourite personFavourite = favouritesService.getFavourite(personId, nodeRef);
if(personFavourite != null)
{
Favourite favourite = getFavourite(personFavourite);
return favourite;
}
else
{
throw new RelationshipResourceNotFoundException(personId, favouriteId);
}
}
@Override
public CollectionWithPagingInfo<Favourite> getFavourites(String personId, final Parameters parameters)
{
personId = people.validatePerson(personId, true);
Paging paging = parameters.getPaging();
final Set<Type> filteredByClientQuery = new HashSet<Type>();
Set<Type> filterTypes = FavouritesService.Type.ALL_FILTER_TYPES; //Default all
// filterType is of the form 'target.<site|file|folder>'
QueryHelper.walk(parameters.getQuery(), new WalkerCallbackAdapter()
{
@Override
public void or() {
//OR is supported but exists() will be called for each EXISTS so we don't
//need to do anything here. If we don't override it then it will be assumed
//that OR in the grammar is not supported.
}
@Override
public void exists(String filteredByClient, boolean negated) {
if(filteredByClient != null)
{
int idx = filteredByClient.lastIndexOf("/");
if(idx == -1 || idx == filteredByClient.length())
{
throw new InvalidArgumentException();
}
else
{
String filtertype = filteredByClient.substring(idx + 1).toUpperCase();
filteredByClientQuery.add(Type.valueOf(filtertype));
}
}
}
});
if (filteredByClientQuery.size() > 0)
{
filterTypes = filteredByClientQuery;
}
final PagingResults<PersonFavourite> favourites = favouritesService.getPagedFavourites(personId, filterTypes, FavouritesService.DEFAULT_SORT_PROPS,
Util.getPagingRequest(paging));
return wrap(paging, favourites);
}
}
package org.alfresco.rest.api.impl;
import java.util.AbstractList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.favourites.PersonFavourite;
import org.alfresco.repo.site.SiteDoesNotExistException;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.rest.api.Favourites;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.model.Document;
import org.alfresco.rest.api.model.DocumentTarget;
import org.alfresco.rest.api.model.Favourite;
import org.alfresco.rest.api.model.Folder;
import org.alfresco.rest.api.model.FolderTarget;
import org.alfresco.rest.api.model.Site;
import org.alfresco.rest.api.model.SiteImpl;
import org.alfresco.rest.api.model.SiteTarget;
import org.alfresco.rest.api.model.Target;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper.WalkerCallbackAdapter;
import org.alfresco.service.cmr.favourites.FavouritesService;
import org.alfresco.service.cmr.favourites.FavouritesService.Type;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Public REST API: Centralises access to favourites functionality and maps between representations repository and api representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class FavouritesImpl implements Favourites
{
private static final Log logger = LogFactory.getLog(FavouritesImpl.class);
private People people;
private Sites sites;
private Nodes nodes;
private FavouritesService favouritesService;
private SiteService siteService;
public void setPeople(People people)
{
this.people = people;
}
public void setSites(Sites sites)
{
this.sites = sites;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setFavouritesService(FavouritesService favouritesService)
{
this.favouritesService = favouritesService;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
private Target getTarget(PersonFavourite personFavourite)
{
Target target = null;
NodeRef nodeRef = personFavourite.getNodeRef();
Type type = personFavourite.getType();
if(type.equals(Type.FILE))
{
Document document = nodes.getDocument(nodeRef);
target = new DocumentTarget(document);
}
else if(type.equals(Type.FOLDER))
{
Folder folder = nodes.getFolder(nodeRef);
target = new FolderTarget(folder);
}
else if(type.equals(Type.SITE))
{
SiteInfo siteInfo = siteService.getSite(nodeRef);
String role = sites.getSiteRole(siteInfo.getShortName());
Site site = new SiteImpl(siteInfo, role);
target = new SiteTarget(site);
}
else
{
throw new AlfrescoRuntimeException("Unexpected favourite target type: " + type);
}
return target;
}
private Favourite getFavourite(PersonFavourite personFavourite)
{
Favourite fav = new Favourite();
fav.setTargetGuid(personFavourite.getNodeRef().getId());
fav.setCreatedAt(personFavourite.getCreatedAt());
Target target = getTarget(personFavourite);
fav.setTarget(target);
return fav;
}
private CollectionWithPagingInfo<Favourite> wrap(Paging paging, PagingResults<PersonFavourite> personFavourites)
{
final List<PersonFavourite> page = personFavourites.getPage();
final List<Favourite> list = new AbstractList<Favourite>()
{
@Override
public Favourite get(int index)
{
PersonFavourite personFavourite = page.get(index);
Favourite fav = getFavourite(personFavourite);
return fav;
}
@Override
public int size()
{
return page.size();
}
};
Pair<Integer, Integer> pair = personFavourites.getTotalResultCount();
Integer total = null;
if(pair.getFirst().equals(pair.getSecond()))
{
total = pair.getFirst();
}
return CollectionWithPagingInfo.asPaged(paging, list, personFavourites.hasMoreItems(), total);
}
@Override
public Favourite addFavourite(String personId, Favourite favourite)
{
Favourite ret = null;
personId = people.validatePerson(personId, true);
Target target = favourite.getTarget();
if(target == null)
{
throw new InvalidArgumentException("target is missing");
}
else if(target instanceof SiteTarget)
{
SiteTarget siteTarget = (SiteTarget)target;
NodeRef guid = siteTarget.getSite().getGuid();
SiteInfo siteInfo = sites.validateSite(guid);
NodeRef siteNodeRef = siteInfo.getNodeRef();
String siteId = siteInfo.getShortName();
try
{
PersonFavourite personFavourite = favouritesService.addFavourite(personId, siteNodeRef);
ret = getFavourite(personFavourite);
}
catch(SiteDoesNotExistException e)
{
throw new RelationshipResourceNotFoundException(personId, siteId);
}
}
else if(target instanceof DocumentTarget)
{
DocumentTarget documentTarget = (DocumentTarget)target;
NodeRef nodeRef = documentTarget.getFile().getGuid();
if(!nodes.nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_CONTENT), null))
{
throw new RelationshipResourceNotFoundException(personId, nodeRef.getId());
}
PersonFavourite personFavourite = favouritesService.addFavourite(personId, nodeRef);
ret = getFavourite(personFavourite);
}
else if(target instanceof FolderTarget)
{
FolderTarget folderTarget = (FolderTarget)target;
NodeRef nodeRef = folderTarget.getFolder().getGuid();
if(!nodes.nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), Collections.singleton(SiteModel.TYPE_SITE)))
{
throw new RelationshipResourceNotFoundException(personId, nodeRef.getId());
}
PersonFavourite personFavourite = favouritesService.addFavourite(personId, nodeRef);
ret = getFavourite(personFavourite);
}
return ret;
}
@Override
public void removeFavourite(String personId, String id)
{
personId = people.validatePerson(personId, true);
NodeRef nodeRef = nodes.validateNode(id);
boolean exists = false;
Type type = favouritesService.getType(nodeRef);
if(type.equals(Type.SITE))
{
SiteInfo siteInfo = siteService.getSite(nodeRef);
if(siteInfo == null)
{
// shouldn't happen because the type implies it's a site
throw new AlfrescoRuntimeException("Unable to find site with nodeRef " + nodeRef);
}
exists = favouritesService.removeFavourite(personId, siteInfo.getNodeRef());
}
else if(type.equals(Type.FILE))
{
exists = favouritesService.removeFavourite(personId, nodeRef);
}
else if(type.equals(Type.FOLDER))
{
exists = favouritesService.removeFavourite(personId, nodeRef);
}
if(!exists)
{
throw new RelationshipResourceNotFoundException(personId, id);
}
}
public Favourite getFavourite(String personId, String favouriteId)
{
NodeRef nodeRef = nodes.validateNode(favouriteId);
personId = people.validatePerson(personId, true);
PersonFavourite personFavourite = favouritesService.getFavourite(personId, nodeRef);
if(personFavourite != null)
{
Favourite favourite = getFavourite(personFavourite);
return favourite;
}
else
{
throw new RelationshipResourceNotFoundException(personId, favouriteId);
}
}
@Override
public CollectionWithPagingInfo<Favourite> getFavourites(String personId, final Parameters parameters)
{
personId = people.validatePerson(personId, true);
Paging paging = parameters.getPaging();
final Set<Type> filteredByClientQuery = new HashSet<Type>();
Set<Type> filterTypes = FavouritesService.Type.ALL_FILTER_TYPES; //Default all
// filterType is of the form 'target.<site|file|folder>'
QueryHelper.walk(parameters.getQuery(), new WalkerCallbackAdapter()
{
@Override
public void or() {
//OR is supported but exists() will be called for each EXISTS so we don't
//need to do anything here. If we don't override it then it will be assumed
//that OR in the grammar is not supported.
}
@Override
public void exists(String filteredByClient, boolean negated) {
if(filteredByClient != null)
{
int idx = filteredByClient.lastIndexOf("/");
if(idx == -1 || idx == filteredByClient.length())
{
throw new InvalidArgumentException();
}
else
{
String filtertype = filteredByClient.substring(idx + 1).toUpperCase();
filteredByClientQuery.add(Type.valueOf(filtertype));
}
}
}
});
if (filteredByClientQuery.size() > 0)
{
filterTypes = filteredByClientQuery;
}
final PagingResults<PersonFavourite> favourites = favouritesService.getPagedFavourites(personId, filterTypes, FavouritesService.DEFAULT_SORT_PROPS,
Util.getPagingRequest(paging));
return wrap(paging, favourites);
}
}

View File

@@ -1,24 +1,24 @@
package org.alfresco.rest.api.impl;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
/**
* Translates access denied exceptions from the service layer to API permission denied exception.
*
* @author steveglover
*
*/
public class LegacyExceptionHandler implements ExceptionHandler
{
@Override
public boolean handle(Throwable t)
{
if(t instanceof AccessDeniedException)
{
// Note: security, no message to indicate why
throw new PermissionDeniedException();
}
return false;
}
}
package org.alfresco.rest.api.impl;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
/**
* Translates access denied exceptions from the service layer to API permission denied exception.
*
* @author steveglover
*
*/
public class LegacyExceptionHandler implements ExceptionHandler
{
@Override
public boolean handle(Throwable t)
{
if(t instanceof AccessDeniedException)
{
// Note: security, no message to indicate why
throw new PermissionDeniedException();
}
return false;
}
}

View File

@@ -1,87 +1,87 @@
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.rest.api.Networks;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.model.Network;
import org.alfresco.rest.api.model.NetworkImpl;
import org.alfresco.rest.api.model.PersonNetwork;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
/**
* Centralises access to network services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class NetworksImpl implements Networks
{
private People people;
private NetworksService networksService;
public void setPeople(People people)
{
this.people = people;
}
public void setNetworksService(NetworksService networksService)
{
this.networksService = networksService;
}
public Network validateNetwork(String networkId)
{
org.alfresco.repo.tenant.Network network = networksService.getNetwork(networkId);
if(network == null)
{
throw new EntityNotFoundException(networkId);
}
Network restNetwork = new NetworkImpl(network);
return restNetwork;
}
private PersonNetwork getPersonNetwork(org.alfresco.repo.tenant.Network network)
{
Network restNetwork = new NetworkImpl(network);
PersonNetwork personNetwork = new PersonNetwork(network.getIsHomeNetwork(), restNetwork);
return personNetwork;
}
public Network getNetwork(String networkId)
{
Network network = validateNetwork(networkId);
return network;
}
public PersonNetwork getNetwork(String personId, String networkId)
{
// check that personId is the current user
personId = people.validatePerson(personId, true);
Network network = validateNetwork(networkId);
org.alfresco.repo.tenant.Network tenantNetwork = networksService.getNetwork(network.getId());
PersonNetwork personNetwork = getPersonNetwork(tenantNetwork);
return personNetwork;
}
public CollectionWithPagingInfo<PersonNetwork> getNetworks(String personId, Paging paging)
{
// check that personId is the current user
personId = people.validatePerson(personId, true);
PagingResults<org.alfresco.repo.tenant.Network> networks = networksService.getNetworks(Util.getPagingRequest(paging));
List<PersonNetwork> ret = new ArrayList<PersonNetwork>(networks.getPage().size());
for(org.alfresco.repo.tenant.Network network : networks.getPage())
{
PersonNetwork personNetwork = getPersonNetwork(network);
ret.add(personNetwork);
}
return CollectionWithPagingInfo.asPaged(paging, ret, networks.hasMoreItems(), networks.getTotalResultCount().getFirst());
}
}
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.rest.api.Networks;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.model.Network;
import org.alfresco.rest.api.model.NetworkImpl;
import org.alfresco.rest.api.model.PersonNetwork;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
/**
* Centralises access to network services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class NetworksImpl implements Networks
{
private People people;
private NetworksService networksService;
public void setPeople(People people)
{
this.people = people;
}
public void setNetworksService(NetworksService networksService)
{
this.networksService = networksService;
}
public Network validateNetwork(String networkId)
{
org.alfresco.repo.tenant.Network network = networksService.getNetwork(networkId);
if(network == null)
{
throw new EntityNotFoundException(networkId);
}
Network restNetwork = new NetworkImpl(network);
return restNetwork;
}
private PersonNetwork getPersonNetwork(org.alfresco.repo.tenant.Network network)
{
Network restNetwork = new NetworkImpl(network);
PersonNetwork personNetwork = new PersonNetwork(network.getIsHomeNetwork(), restNetwork);
return personNetwork;
}
public Network getNetwork(String networkId)
{
Network network = validateNetwork(networkId);
return network;
}
public PersonNetwork getNetwork(String personId, String networkId)
{
// check that personId is the current user
personId = people.validatePerson(personId, true);
Network network = validateNetwork(networkId);
org.alfresco.repo.tenant.Network tenantNetwork = networksService.getNetwork(network.getId());
PersonNetwork personNetwork = getPersonNetwork(tenantNetwork);
return personNetwork;
}
public CollectionWithPagingInfo<PersonNetwork> getNetworks(String personId, Paging paging)
{
// check that personId is the current user
personId = people.validatePerson(personId, true);
PagingResults<org.alfresco.repo.tenant.Network> networks = networksService.getNetworks(Util.getPagingRequest(paging));
List<PersonNetwork> ret = new ArrayList<PersonNetwork>(networks.getPage().size());
for(org.alfresco.repo.tenant.Network network : networks.getPage())
{
PersonNetwork personNetwork = getPersonNetwork(network);
ret.add(personNetwork);
}
return CollectionWithPagingInfo.asPaged(paging, ret, networks.hasMoreItems(), networks.getTotalResultCount().getFirst());
}
}

View File

@@ -1,134 +1,134 @@
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.alfresco.rest.api.NodeRatings;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.impl.node.ratings.RatingScheme;
import org.alfresco.rest.api.model.NodeRating;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.rating.RatingService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.TypeConstraint;
import org.alfresco.util.registry.NamedObjectRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Centralises access to node ratings services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class NodeRatingsImpl implements NodeRatings
{
private static Log logger = LogFactory.getLog(NodeRatingsImpl.class);
private Nodes nodes;
private RatingService ratingService;
private NamedObjectRegistry<RatingScheme> nodeRatingSchemeRegistry;
private TypeConstraint typeConstraint;
public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setRatingService(RatingService ratingService)
{
this.ratingService = ratingService;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setNodeRatingSchemeRegistry(NamedObjectRegistry<RatingScheme> nodeRatingSchemeRegistry)
{
this.nodeRatingSchemeRegistry = nodeRatingSchemeRegistry;
}
public RatingScheme validateRatingScheme(String ratingSchemeId)
{
RatingScheme ratingScheme = nodeRatingSchemeRegistry.getNamedObject(ratingSchemeId);
if(ratingScheme == null)
{
throw new InvalidArgumentException("Invalid ratingSchemeId " + ratingSchemeId);
}
return ratingScheme;
}
// TODO deal with fractional ratings - InvalidArgumentException
public NodeRating getNodeRating(String nodeId, String ratingSchemeId)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
RatingScheme ratingScheme = validateRatingScheme(ratingSchemeId);
return ratingScheme.getNodeRating(nodeRef);
}
public CollectionWithPagingInfo<NodeRating> getNodeRatings(String nodeId, Paging paging)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
Set<String> schemes = new TreeSet<String>(ratingService.getRatingSchemes().keySet());
Iterator<String> it = schemes.iterator();
int skipCount = paging.getSkipCount();
int maxItems = paging.getMaxItems();
int end = skipCount + maxItems;
if(end < 0)
{
// overflow
end = Integer.MAX_VALUE;
}
int count = Math.min(maxItems, schemes.size() - skipCount);
List<NodeRating> ratings = new ArrayList<NodeRating>(count);
for(int i = 0; i < end && it.hasNext(); i++)
{
String schemeName = it.next();
if(i < skipCount)
{
continue;
}
RatingScheme ratingScheme = validateRatingScheme(schemeName);
NodeRating nodeRating = ratingScheme.getNodeRating(nodeRef);
ratings.add(nodeRating);
}
int totalSize = schemes.size();
boolean hasMoreItems = (skipCount + count < totalSize);
return CollectionWithPagingInfo.asPaged(paging, ratings, hasMoreItems, totalSize);
}
public void addRating(String nodeId, String ratingSchemeId, Object rating)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
RatingScheme ratingScheme = validateRatingScheme(ratingSchemeId);
if(!typeConstraint.matches(nodeRef))
{
throw new UnsupportedResourceOperationException("Cannot rate this node");
}
ratingScheme.applyRating(nodeRef, rating);
}
public void removeRating(String nodeId, String ratingSchemeId)
{
RatingScheme ratingScheme = validateRatingScheme(ratingSchemeId);
NodeRef nodeRef = nodes.validateNode(nodeId);
ratingScheme.removeRating(nodeRef);
}
}
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.alfresco.rest.api.NodeRatings;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.impl.node.ratings.RatingScheme;
import org.alfresco.rest.api.model.NodeRating;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.rating.RatingService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.TypeConstraint;
import org.alfresco.util.registry.NamedObjectRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Centralises access to node ratings services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class NodeRatingsImpl implements NodeRatings
{
private static Log logger = LogFactory.getLog(NodeRatingsImpl.class);
private Nodes nodes;
private RatingService ratingService;
private NamedObjectRegistry<RatingScheme> nodeRatingSchemeRegistry;
private TypeConstraint typeConstraint;
public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setRatingService(RatingService ratingService)
{
this.ratingService = ratingService;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setNodeRatingSchemeRegistry(NamedObjectRegistry<RatingScheme> nodeRatingSchemeRegistry)
{
this.nodeRatingSchemeRegistry = nodeRatingSchemeRegistry;
}
public RatingScheme validateRatingScheme(String ratingSchemeId)
{
RatingScheme ratingScheme = nodeRatingSchemeRegistry.getNamedObject(ratingSchemeId);
if(ratingScheme == null)
{
throw new InvalidArgumentException("Invalid ratingSchemeId " + ratingSchemeId);
}
return ratingScheme;
}
// TODO deal with fractional ratings - InvalidArgumentException
public NodeRating getNodeRating(String nodeId, String ratingSchemeId)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
RatingScheme ratingScheme = validateRatingScheme(ratingSchemeId);
return ratingScheme.getNodeRating(nodeRef);
}
public CollectionWithPagingInfo<NodeRating> getNodeRatings(String nodeId, Paging paging)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
Set<String> schemes = new TreeSet<String>(ratingService.getRatingSchemes().keySet());
Iterator<String> it = schemes.iterator();
int skipCount = paging.getSkipCount();
int maxItems = paging.getMaxItems();
int end = skipCount + maxItems;
if(end < 0)
{
// overflow
end = Integer.MAX_VALUE;
}
int count = Math.min(maxItems, schemes.size() - skipCount);
List<NodeRating> ratings = new ArrayList<NodeRating>(count);
for(int i = 0; i < end && it.hasNext(); i++)
{
String schemeName = it.next();
if(i < skipCount)
{
continue;
}
RatingScheme ratingScheme = validateRatingScheme(schemeName);
NodeRating nodeRating = ratingScheme.getNodeRating(nodeRef);
ratings.add(nodeRating);
}
int totalSize = schemes.size();
boolean hasMoreItems = (skipCount + count < totalSize);
return CollectionWithPagingInfo.asPaged(paging, ratings, hasMoreItems, totalSize);
}
public void addRating(String nodeId, String ratingSchemeId, Object rating)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
RatingScheme ratingScheme = validateRatingScheme(ratingSchemeId);
if(!typeConstraint.matches(nodeRef))
{
throw new UnsupportedResourceOperationException("Cannot rate this node");
}
ratingScheme.applyRating(nodeRef, rating);
}
public void removeRating(String nodeId, String ratingSchemeId)
{
RatingScheme ratingScheme = validateRatingScheme(ratingSchemeId);
NodeRef nodeRef = nodes.validateNode(nodeId);
ratingScheme.removeRating(nodeRef);
}
}

View File

@@ -1,235 +1,235 @@
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.opencmis.CMISConnector;
import org.alfresco.opencmis.CMISNodeInfoImpl;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Document;
import org.alfresco.rest.api.model.Folder;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
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.StoreRef;
import org.alfresco.service.namespace.QName;
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
/**
* Centralises access to node services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class NodesImpl implements Nodes
{
private static enum Type
{
// Note: ordered
DOCUMENT, FOLDER;
};
private NodeService nodeService;
private DictionaryService dictionaryService;
private CMISConnector cmisConnector;
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setCmisConnector(CMISConnector cmisConnector)
{
this.cmisConnector = cmisConnector;
}
/*
*
* Note: assumes workspace://SpacesStore
*/
public NodeRef validateNode(String nodeId)
{
return validateNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
}
public NodeRef validateNode(StoreRef storeRef, String nodeId)
{
String versionLabel = null;
int idx = nodeId.indexOf(";");
if(idx != -1)
{
versionLabel = nodeId.substring(idx + 1);
nodeId = nodeId.substring(0, idx);
if(versionLabel.equals("pwc"))
{
// TODO correct exception?
throw new EntityNotFoundException(nodeId);
}
}
NodeRef nodeRef = new NodeRef(storeRef, nodeId);
return validateNode(nodeRef);
}
public NodeRef validateNode(NodeRef nodeRef)
{
if(!nodeService.exists(nodeRef))
{
throw new EntityNotFoundException(nodeRef.getId());
}
return nodeRef;
}
public boolean nodeMatches(NodeRef nodeRef, Set<QName> expectedTypes, Set<QName> excludedTypes)
{
if(!nodeService.exists(nodeRef))
{
throw new EntityNotFoundException(nodeRef.getId());
}
QName type = nodeService.getType(nodeRef);
Set<QName> allExpectedTypes = new HashSet<QName>();
if(expectedTypes != null)
{
for(QName expectedType : expectedTypes)
{
allExpectedTypes.addAll(dictionaryService.getSubTypes(expectedType, true));
}
}
Set<QName> allExcludedTypes = new HashSet<QName>();
if(excludedTypes != null)
{
for(QName excludedType : excludedTypes)
{
allExcludedTypes.addAll(dictionaryService.getSubTypes(excludedType, true));
}
}
boolean inExpected = allExpectedTypes.contains(type);
boolean excluded = allExcludedTypes.contains(type);
return(inExpected && !excluded);
}
public Node getNode(String nodeId)
{
NodeRef nodeRef = validateNode(nodeId);
return new Node(nodeRef, nodeService.getProperties(nodeRef));
}
public Node getNode(NodeRef nodeRef)
{
return new Node(nodeRef, nodeService.getProperties(nodeRef));
}
private Type getType(NodeRef nodeRef)
{
QName type = nodeService.getType(nodeRef);
boolean isContainer = Boolean.valueOf((dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) == true &&
!dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER)));
return isContainer ? Type.FOLDER : Type.DOCUMENT;
}
// TODO filter CMIS properties
private Properties getCMISProperties(NodeRef nodeRef)
{
CMISNodeInfoImpl nodeInfo = cmisConnector.createNodeInfo(nodeRef);
final Properties properties = cmisConnector.getNodeProperties(nodeInfo, null);
// fake the title property, which CMIS doesn't give us
String title = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE);
final PropertyStringImpl titleProp = new PropertyStringImpl(ContentModel.PROP_TITLE.toString(), title);
Properties wrapProperties = new Properties()
{
@Override
public List<CmisExtensionElement> getExtensions()
{
return properties.getExtensions();
}
@Override
public void setExtensions(List<CmisExtensionElement> extensions)
{
properties.setExtensions(extensions);
}
@Override
public Map<String, PropertyData<?>> getProperties()
{
Map<String, PropertyData<?>> updatedProperties = new HashMap<String, PropertyData<?>>(properties.getProperties());
updatedProperties.put(titleProp.getId(), titleProp);
return updatedProperties;
}
@Override
public List<PropertyData<?>> getPropertyList()
{
List<PropertyData<?>> propertyList = new ArrayList<PropertyData<?>>(properties.getPropertyList());
propertyList.add(titleProp);
return propertyList;
}
};
return wrapProperties;
}
/**
* Returns the public api representation of a document.
*
* Note: properties are modelled after the OpenCMIS node properties
*/
public Document getDocument(NodeRef nodeRef)
{
Type type = getType(nodeRef);
if(type.equals(Type.DOCUMENT))
{
Properties properties = getCMISProperties(nodeRef);
Document doc = new Document(nodeRef, properties);
return doc;
}
else
{
throw new InvalidArgumentException("Node is not a file");
}
}
/**
* Returns the public api representation of a folder.
*
* Note: properties are modelled after the OpenCMIS node properties
*/
public Folder getFolder(NodeRef nodeRef)
{
Type type = getType(nodeRef);
if(type.equals(Type.FOLDER))
{
Properties properties = getCMISProperties(nodeRef);
Folder folder = new Folder(nodeRef, properties);
return folder;
}
else
{
throw new InvalidArgumentException("Node is not a folder");
}
}
}
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.opencmis.CMISConnector;
import org.alfresco.opencmis.CMISNodeInfoImpl;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Document;
import org.alfresco.rest.api.model.Folder;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
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.StoreRef;
import org.alfresco.service.namespace.QName;
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
/**
* Centralises access to node services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class NodesImpl implements Nodes
{
private static enum Type
{
// Note: ordered
DOCUMENT, FOLDER;
};
private NodeService nodeService;
private DictionaryService dictionaryService;
private CMISConnector cmisConnector;
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setCmisConnector(CMISConnector cmisConnector)
{
this.cmisConnector = cmisConnector;
}
/*
*
* Note: assumes workspace://SpacesStore
*/
public NodeRef validateNode(String nodeId)
{
return validateNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
}
public NodeRef validateNode(StoreRef storeRef, String nodeId)
{
String versionLabel = null;
int idx = nodeId.indexOf(";");
if(idx != -1)
{
versionLabel = nodeId.substring(idx + 1);
nodeId = nodeId.substring(0, idx);
if(versionLabel.equals("pwc"))
{
// TODO correct exception?
throw new EntityNotFoundException(nodeId);
}
}
NodeRef nodeRef = new NodeRef(storeRef, nodeId);
return validateNode(nodeRef);
}
public NodeRef validateNode(NodeRef nodeRef)
{
if(!nodeService.exists(nodeRef))
{
throw new EntityNotFoundException(nodeRef.getId());
}
return nodeRef;
}
public boolean nodeMatches(NodeRef nodeRef, Set<QName> expectedTypes, Set<QName> excludedTypes)
{
if(!nodeService.exists(nodeRef))
{
throw new EntityNotFoundException(nodeRef.getId());
}
QName type = nodeService.getType(nodeRef);
Set<QName> allExpectedTypes = new HashSet<QName>();
if(expectedTypes != null)
{
for(QName expectedType : expectedTypes)
{
allExpectedTypes.addAll(dictionaryService.getSubTypes(expectedType, true));
}
}
Set<QName> allExcludedTypes = new HashSet<QName>();
if(excludedTypes != null)
{
for(QName excludedType : excludedTypes)
{
allExcludedTypes.addAll(dictionaryService.getSubTypes(excludedType, true));
}
}
boolean inExpected = allExpectedTypes.contains(type);
boolean excluded = allExcludedTypes.contains(type);
return(inExpected && !excluded);
}
public Node getNode(String nodeId)
{
NodeRef nodeRef = validateNode(nodeId);
return new Node(nodeRef, nodeService.getProperties(nodeRef));
}
public Node getNode(NodeRef nodeRef)
{
return new Node(nodeRef, nodeService.getProperties(nodeRef));
}
private Type getType(NodeRef nodeRef)
{
QName type = nodeService.getType(nodeRef);
boolean isContainer = Boolean.valueOf((dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) == true &&
!dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER)));
return isContainer ? Type.FOLDER : Type.DOCUMENT;
}
// TODO filter CMIS properties
private Properties getCMISProperties(NodeRef nodeRef)
{
CMISNodeInfoImpl nodeInfo = cmisConnector.createNodeInfo(nodeRef);
final Properties properties = cmisConnector.getNodeProperties(nodeInfo, null);
// fake the title property, which CMIS doesn't give us
String title = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE);
final PropertyStringImpl titleProp = new PropertyStringImpl(ContentModel.PROP_TITLE.toString(), title);
Properties wrapProperties = new Properties()
{
@Override
public List<CmisExtensionElement> getExtensions()
{
return properties.getExtensions();
}
@Override
public void setExtensions(List<CmisExtensionElement> extensions)
{
properties.setExtensions(extensions);
}
@Override
public Map<String, PropertyData<?>> getProperties()
{
Map<String, PropertyData<?>> updatedProperties = new HashMap<String, PropertyData<?>>(properties.getProperties());
updatedProperties.put(titleProp.getId(), titleProp);
return updatedProperties;
}
@Override
public List<PropertyData<?>> getPropertyList()
{
List<PropertyData<?>> propertyList = new ArrayList<PropertyData<?>>(properties.getPropertyList());
propertyList.add(titleProp);
return propertyList;
}
};
return wrapProperties;
}
/**
* Returns the public api representation of a document.
*
* Note: properties are modelled after the OpenCMIS node properties
*/
public Document getDocument(NodeRef nodeRef)
{
Type type = getType(nodeRef);
if(type.equals(Type.DOCUMENT))
{
Properties properties = getCMISProperties(nodeRef);
Document doc = new Document(nodeRef, properties);
return doc;
}
else
{
throw new InvalidArgumentException("Node is not a file");
}
}
/**
* Returns the public api representation of a folder.
*
* Note: properties are modelled after the OpenCMIS node properties
*/
public Folder getFolder(NodeRef nodeRef)
{
Type type = getType(nodeRef);
if(type.equals(Type.FOLDER))
{
Properties properties = getCMISProperties(nodeRef);
Folder folder = new Folder(nodeRef, properties);
return folder;
}
else
{
throw new InvalidArgumentException("Node is not a folder");
}
}
}

View File

@@ -1,323 +1,323 @@
package org.alfresco.rest.api.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.model.Company;
import org.alfresco.rest.api.model.Person;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.NoSuchPersonException;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
import org.alfresco.service.cmr.usage.ContentUsageService;
import org.alfresco.service.namespace.QName;
/**
* Centralises access to people services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class PeopleImpl implements People
{
protected Nodes nodes;
protected Sites sites;
protected SiteService siteService;
protected NodeService nodeService;
protected PersonService personService;
protected AuthenticationService authenticationService;
protected ContentUsageService contentUsageService;
protected ContentService contentService;
protected ThumbnailService thumbnailService;
public void setSites(Sites sites)
{
this.sites = sites;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
public void setContentUsageService(ContentUsageService contentUsageService)
{
this.contentUsageService = contentUsageService;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
public void setThumbnailService(ThumbnailService thumbnailService)
{
this.thumbnailService = thumbnailService;
}
public String validatePerson(String personId)
{
return validatePerson(personId, false);
}
public String validatePerson(String personId, boolean validateIsCurrentUser)
{
if(personId.equalsIgnoreCase(DEFAULT_USER))
{
personId = AuthenticationUtil.getFullyAuthenticatedUser();
}
personId = personService.getUserIdentifier(personId);
if(personId == null)
{
// "User " + personId + " does not exist"
throw new EntityNotFoundException("personId is null.");
}
if(validateIsCurrentUser)
{
String currentUserId = AuthenticationUtil.getFullyAuthenticatedUser();
if(!currentUserId.equalsIgnoreCase(personId))
{
throw new EntityNotFoundException(personId);
}
}
return personId;
}
protected void processPersonProperties(String userName, final Map<QName, Serializable> nodeProps)
{
if(!contentUsageService.getEnabled())
{
// quota used will always be 0 in this case so remove from the person properties
nodeProps.remove(ContentModel.PROP_SIZE_QUOTA);
nodeProps.remove(ContentModel.PROP_SIZE_CURRENT);
}
final ContentData personDescription = (ContentData)nodeProps.get(ContentModel.PROP_PERSONDESC);
if(personDescription != null)
{
nodeProps.remove(ContentModel.PROP_PERSONDESC);
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
ContentReader reader = contentService.getRawReader(personDescription.getContentUrl());
if(reader != null && reader.exists())
{
String description = reader.getContentString();
nodeProps.put(Person.PROP_PERSON_DESCRIPTION, description);
}
return null;
}
});
}
}
public boolean hasAvatar(NodeRef personNodeRef)
{
if(personNodeRef != null)
{
List<AssociationRef> avatorAssocs = nodeService.getTargetAssocs(personNodeRef, ContentModel.ASSOC_AVATAR);
return(avatorAssocs.size() > 0);
}
else
{
return false;
}
}
public NodeRef getAvatar(String personId)
{
NodeRef avatar = null;
personId = validatePerson(personId);
NodeRef personNode = personService.getPerson(personId);
if(personNode != null)
{
List<AssociationRef> avatorAssocs = nodeService.getTargetAssocs(personNode, ContentModel.ASSOC_AVATAR);
if(avatorAssocs.size() > 0)
{
AssociationRef ref = avatorAssocs.get(0);
NodeRef thumbnailNodeRef = thumbnailService.getThumbnailByName(ref.getTargetRef(), ContentModel.PROP_CONTENT, "avatar");
if(thumbnailNodeRef != null)
{
avatar = thumbnailNodeRef;
}
else
{
throw new EntityNotFoundException("avatar");
}
}
else
{
throw new EntityNotFoundException("avatar");
}
}
else
{
throw new EntityNotFoundException(personId);
}
return avatar;
}
/**
*
* @throws NoSuchPersonException if personId does not exist
*/
public Person getPerson(String personId)
{
Person person = null;
personId = validatePerson(personId);
NodeRef personNode = personService.getPerson(personId, false);
if (personNode != null)
{
Map<QName, Serializable> nodeProps = nodeService.getProperties(personNode);
processPersonProperties(personId, nodeProps);
// TODO this needs to be run as admin but should we do this here?
final String pId = personId;
Boolean enabled = AuthenticationUtil.runAsSystem(new RunAsWork<Boolean>()
{
public Boolean doWork() throws Exception
{
return authenticationService.getAuthenticationEnabled(pId);
}
});
person = new Person(personNode, nodeProps, enabled);
// get avatar information
if(hasAvatar(personNode))
{
try
{
NodeRef avatar = getAvatar(personId);
person.setAvatarId(avatar);
}
catch(EntityNotFoundException e)
{
// shouldn't happen, but ok
}
}
}
else
{
throw new EntityNotFoundException(personId);
}
return person;
}
/**
private void addToMap(Map<QName, Serializable> properties, QName name, Serializable value)
{
// if(name != null && value != null)
// {
properties.put(name, value);
// }
}
public Person updatePerson(String personId, final Person person)
{
personId = validatePerson(personId);
final Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
// addToMap(properties, ContentModel.PROP_USERNAME, person.getUserName());
addToMap(properties, ContentModel.PROP_FIRSTNAME, person.getFirstName());
addToMap(properties, ContentModel.PROP_LASTNAME, person.getLastName());
addToMap(properties, ContentModel.PROP_JOBTITLE, person.getJobTitle());
addToMap(properties, ContentModel.PROP_LOCATION, person.getLocation());
addToMap(properties, ContentModel.PROP_TELEPHONE, person.getTelephone());
addToMap(properties, ContentModel.PROP_MOBILE, person.getMobile());
addToMap(properties, ContentModel.PROP_EMAIL, person.getEmail());
Company company = person.getCompany();
if(company != null)
{
addToMap(properties, ContentModel.PROP_ORGANIZATION, company.getOrganization());
addToMap(properties, ContentModel.PROP_COMPANYADDRESS1, company.getAddress1());
addToMap(properties, ContentModel.PROP_COMPANYADDRESS2, company.getAddress2());
addToMap(properties, ContentModel.PROP_COMPANYADDRESS3, company.getAddress3());
addToMap(properties, ContentModel.PROP_COMPANYPOSTCODE, company.getPostcode());
addToMap(properties, ContentModel.PROP_COMPANYTELEPHONE, company.getTelephone());
addToMap(properties, ContentModel.PROP_COMPANYFAX, company.getFax());
addToMap(properties, ContentModel.PROP_COMPANYEMAIL, company.getEmail());
}
else
{
addToMap(properties, ContentModel.PROP_ORGANIZATION, null);
addToMap(properties, ContentModel.PROP_COMPANYADDRESS1, null);
addToMap(properties, ContentModel.PROP_COMPANYADDRESS2, null);
addToMap(properties, ContentModel.PROP_COMPANYADDRESS3, null);
addToMap(properties, ContentModel.PROP_COMPANYPOSTCODE, null);
addToMap(properties, ContentModel.PROP_COMPANYTELEPHONE, null);
addToMap(properties, ContentModel.PROP_COMPANYFAX, null);
addToMap(properties, ContentModel.PROP_COMPANYEMAIL, null);
}
addToMap(properties, ContentModel.PROP_SKYPE, person.getSkypeId());
addToMap(properties, ContentModel.PROP_INSTANTMSG, person.getInstantMessageId());
addToMap(properties, ContentModel.PROP_USER_STATUS, person.getUserStatus());
addToMap(properties, ContentModel.PROP_USER_STATUS_TIME, person.getStatusUpdatedAt());
addToMap(properties, ContentModel.PROP_GOOGLEUSERNAME, person.getGoogleId());
addToMap(properties, ContentModel.PROP_SIZE_QUOTA, person.getQuota());
addToMap(properties, ContentModel.PROP_SIZE_CURRENT, person.getQuotaUsed());
addToMap(properties, ContentModel.PROP_DESCRIPTION, person.getDescription());
final String pId = personId;
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
personService.setPersonProperties(pId, properties, false);
return null;
}
});
return getPerson(personId);
}
*/
}
package org.alfresco.rest.api.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.model.Company;
import org.alfresco.rest.api.model.Person;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.NoSuchPersonException;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
import org.alfresco.service.cmr.usage.ContentUsageService;
import org.alfresco.service.namespace.QName;
/**
* Centralises access to people services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class PeopleImpl implements People
{
protected Nodes nodes;
protected Sites sites;
protected SiteService siteService;
protected NodeService nodeService;
protected PersonService personService;
protected AuthenticationService authenticationService;
protected ContentUsageService contentUsageService;
protected ContentService contentService;
protected ThumbnailService thumbnailService;
public void setSites(Sites sites)
{
this.sites = sites;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
public void setContentUsageService(ContentUsageService contentUsageService)
{
this.contentUsageService = contentUsageService;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
public void setThumbnailService(ThumbnailService thumbnailService)
{
this.thumbnailService = thumbnailService;
}
public String validatePerson(String personId)
{
return validatePerson(personId, false);
}
public String validatePerson(String personId, boolean validateIsCurrentUser)
{
if(personId.equalsIgnoreCase(DEFAULT_USER))
{
personId = AuthenticationUtil.getFullyAuthenticatedUser();
}
personId = personService.getUserIdentifier(personId);
if(personId == null)
{
// "User " + personId + " does not exist"
throw new EntityNotFoundException("personId is null.");
}
if(validateIsCurrentUser)
{
String currentUserId = AuthenticationUtil.getFullyAuthenticatedUser();
if(!currentUserId.equalsIgnoreCase(personId))
{
throw new EntityNotFoundException(personId);
}
}
return personId;
}
protected void processPersonProperties(String userName, final Map<QName, Serializable> nodeProps)
{
if(!contentUsageService.getEnabled())
{
// quota used will always be 0 in this case so remove from the person properties
nodeProps.remove(ContentModel.PROP_SIZE_QUOTA);
nodeProps.remove(ContentModel.PROP_SIZE_CURRENT);
}
final ContentData personDescription = (ContentData)nodeProps.get(ContentModel.PROP_PERSONDESC);
if(personDescription != null)
{
nodeProps.remove(ContentModel.PROP_PERSONDESC);
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
ContentReader reader = contentService.getRawReader(personDescription.getContentUrl());
if(reader != null && reader.exists())
{
String description = reader.getContentString();
nodeProps.put(Person.PROP_PERSON_DESCRIPTION, description);
}
return null;
}
});
}
}
public boolean hasAvatar(NodeRef personNodeRef)
{
if(personNodeRef != null)
{
List<AssociationRef> avatorAssocs = nodeService.getTargetAssocs(personNodeRef, ContentModel.ASSOC_AVATAR);
return(avatorAssocs.size() > 0);
}
else
{
return false;
}
}
public NodeRef getAvatar(String personId)
{
NodeRef avatar = null;
personId = validatePerson(personId);
NodeRef personNode = personService.getPerson(personId);
if(personNode != null)
{
List<AssociationRef> avatorAssocs = nodeService.getTargetAssocs(personNode, ContentModel.ASSOC_AVATAR);
if(avatorAssocs.size() > 0)
{
AssociationRef ref = avatorAssocs.get(0);
NodeRef thumbnailNodeRef = thumbnailService.getThumbnailByName(ref.getTargetRef(), ContentModel.PROP_CONTENT, "avatar");
if(thumbnailNodeRef != null)
{
avatar = thumbnailNodeRef;
}
else
{
throw new EntityNotFoundException("avatar");
}
}
else
{
throw new EntityNotFoundException("avatar");
}
}
else
{
throw new EntityNotFoundException(personId);
}
return avatar;
}
/**
*
* @throws NoSuchPersonException if personId does not exist
*/
public Person getPerson(String personId)
{
Person person = null;
personId = validatePerson(personId);
NodeRef personNode = personService.getPerson(personId, false);
if (personNode != null)
{
Map<QName, Serializable> nodeProps = nodeService.getProperties(personNode);
processPersonProperties(personId, nodeProps);
// TODO this needs to be run as admin but should we do this here?
final String pId = personId;
Boolean enabled = AuthenticationUtil.runAsSystem(new RunAsWork<Boolean>()
{
public Boolean doWork() throws Exception
{
return authenticationService.getAuthenticationEnabled(pId);
}
});
person = new Person(personNode, nodeProps, enabled);
// get avatar information
if(hasAvatar(personNode))
{
try
{
NodeRef avatar = getAvatar(personId);
person.setAvatarId(avatar);
}
catch(EntityNotFoundException e)
{
// shouldn't happen, but ok
}
}
}
else
{
throw new EntityNotFoundException(personId);
}
return person;
}
/**
private void addToMap(Map<QName, Serializable> properties, QName name, Serializable value)
{
// if(name != null && value != null)
// {
properties.put(name, value);
// }
}
public Person updatePerson(String personId, final Person person)
{
personId = validatePerson(personId);
final Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
// addToMap(properties, ContentModel.PROP_USERNAME, person.getUserName());
addToMap(properties, ContentModel.PROP_FIRSTNAME, person.getFirstName());
addToMap(properties, ContentModel.PROP_LASTNAME, person.getLastName());
addToMap(properties, ContentModel.PROP_JOBTITLE, person.getJobTitle());
addToMap(properties, ContentModel.PROP_LOCATION, person.getLocation());
addToMap(properties, ContentModel.PROP_TELEPHONE, person.getTelephone());
addToMap(properties, ContentModel.PROP_MOBILE, person.getMobile());
addToMap(properties, ContentModel.PROP_EMAIL, person.getEmail());
Company company = person.getCompany();
if(company != null)
{
addToMap(properties, ContentModel.PROP_ORGANIZATION, company.getOrganization());
addToMap(properties, ContentModel.PROP_COMPANYADDRESS1, company.getAddress1());
addToMap(properties, ContentModel.PROP_COMPANYADDRESS2, company.getAddress2());
addToMap(properties, ContentModel.PROP_COMPANYADDRESS3, company.getAddress3());
addToMap(properties, ContentModel.PROP_COMPANYPOSTCODE, company.getPostcode());
addToMap(properties, ContentModel.PROP_COMPANYTELEPHONE, company.getTelephone());
addToMap(properties, ContentModel.PROP_COMPANYFAX, company.getFax());
addToMap(properties, ContentModel.PROP_COMPANYEMAIL, company.getEmail());
}
else
{
addToMap(properties, ContentModel.PROP_ORGANIZATION, null);
addToMap(properties, ContentModel.PROP_COMPANYADDRESS1, null);
addToMap(properties, ContentModel.PROP_COMPANYADDRESS2, null);
addToMap(properties, ContentModel.PROP_COMPANYADDRESS3, null);
addToMap(properties, ContentModel.PROP_COMPANYPOSTCODE, null);
addToMap(properties, ContentModel.PROP_COMPANYTELEPHONE, null);
addToMap(properties, ContentModel.PROP_COMPANYFAX, null);
addToMap(properties, ContentModel.PROP_COMPANYEMAIL, null);
}
addToMap(properties, ContentModel.PROP_SKYPE, person.getSkypeId());
addToMap(properties, ContentModel.PROP_INSTANTMSG, person.getInstantMessageId());
addToMap(properties, ContentModel.PROP_USER_STATUS, person.getUserStatus());
addToMap(properties, ContentModel.PROP_USER_STATUS_TIME, person.getStatusUpdatedAt());
addToMap(properties, ContentModel.PROP_GOOGLEUSERNAME, person.getGoogleId());
addToMap(properties, ContentModel.PROP_SIZE_QUOTA, person.getQuota());
addToMap(properties, ContentModel.PROP_SIZE_CURRENT, person.getQuotaUsed());
addToMap(properties, ContentModel.PROP_DESCRIPTION, person.getDescription());
final String pId = personId;
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
personService.setPersonProperties(pId, properties, false);
return null;
}
});
return getPerson(personId);
}
*/
}

View File

@@ -1,66 +1,66 @@
package org.alfresco.rest.api.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.query.PagingResults;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Preferences;
import org.alfresco.rest.api.model.Preference;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.preference.PreferenceService;
import org.alfresco.util.Pair;
/**
* Centralises access to preference services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class PreferencesImpl implements Preferences
{
private People people;
private PreferenceService preferenceService;
public void setPeople(People people)
{
this.people = people;
}
public void setPreferenceService(PreferenceService preferenceService)
{
this.preferenceService = preferenceService;
}
public Preference getPreference(String personId, String preferenceName)
{
personId = people.validatePerson(personId);
Serializable preferenceValue = preferenceService.getPreference(personId, preferenceName);
if(preferenceValue != null)
{
return new Preference(preferenceName, preferenceValue);
}
else
{
throw new RelationshipResourceNotFoundException(personId, preferenceName);
}
}
public CollectionWithPagingInfo<Preference> getPreferences(String personId, Paging paging)
{
personId = people.validatePerson(personId);
PagingResults<Pair<String, Serializable>> preferences = preferenceService.getPagedPreferences(personId, null, Util.getPagingRequest(paging));
List<Preference> ret = new ArrayList<Preference>(preferences.getPage().size());
for(Pair<String, Serializable> prefEntity : preferences.getPage())
{
Preference pref = new Preference(prefEntity.getFirst(), prefEntity.getSecond());
ret.add(pref);
}
return CollectionWithPagingInfo.asPaged(paging, ret, preferences.hasMoreItems(), preferences.getTotalResultCount().getFirst());
}
}
package org.alfresco.rest.api.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.query.PagingResults;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Preferences;
import org.alfresco.rest.api.model.Preference;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.preference.PreferenceService;
import org.alfresco.util.Pair;
/**
* Centralises access to preference services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class PreferencesImpl implements Preferences
{
private People people;
private PreferenceService preferenceService;
public void setPeople(People people)
{
this.people = people;
}
public void setPreferenceService(PreferenceService preferenceService)
{
this.preferenceService = preferenceService;
}
public Preference getPreference(String personId, String preferenceName)
{
personId = people.validatePerson(personId);
Serializable preferenceValue = preferenceService.getPreference(personId, preferenceName);
if(preferenceValue != null)
{
return new Preference(preferenceName, preferenceValue);
}
else
{
throw new RelationshipResourceNotFoundException(personId, preferenceName);
}
}
public CollectionWithPagingInfo<Preference> getPreferences(String personId, Paging paging)
{
personId = people.validatePerson(personId);
PagingResults<Pair<String, Serializable>> preferences = preferenceService.getPagedPreferences(personId, null, Util.getPagingRequest(paging));
List<Preference> ret = new ArrayList<Preference>(preferences.getPage().size());
for(Pair<String, Serializable> prefEntity : preferences.getPage())
{
Preference pref = new Preference(prefEntity.getFirst(), prefEntity.getSecond());
ret.add(pref);
}
return CollectionWithPagingInfo.asPaged(paging, ret, preferences.hasMoreItems(), preferences.getTotalResultCount().getFirst());
}
}

View File

@@ -1,18 +1,18 @@
package org.alfresco.rest.api.impl;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.service.cmr.invitation.InvitationExceptionForbidden;
public class SiteMembershipRequestsExceptionHandler extends DefaultExceptionHandler
{
@Override
public boolean handle(Throwable t)
{
if(t instanceof InvitationExceptionForbidden)
{
// Note: security, no message to indicate why
throw new NotFoundException();
}
return super.handle(t);
}
}
package org.alfresco.rest.api.impl;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.service.cmr.invitation.InvitationExceptionForbidden;
public class SiteMembershipRequestsExceptionHandler extends DefaultExceptionHandler
{
@Override
public boolean handle(Throwable t)
{
if(t instanceof InvitationExceptionForbidden)
{
// Note: security, no message to indicate why
throw new NotFoundException();
}
return super.handle(t);
}
}

View File

@@ -1,445 +1,445 @@
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.invitation.InvitationSearchCriteriaImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.SiteMembershipRequests;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.model.SiteMembershipRequest;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.invitation.Invitation;
import org.alfresco.service.cmr.invitation.Invitation.ResourceType;
import org.alfresco.service.cmr.invitation.InvitationExceptionNotFound;
import org.alfresco.service.cmr.invitation.InvitationSearchCriteria.InvitationType;
import org.alfresco.service.cmr.invitation.InvitationService;
import org.alfresco.service.cmr.invitation.ModeratedInvitation;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Public REST API: centralises access to site membership requests and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class SiteMembershipRequestsImpl implements SiteMembershipRequests
{
private static final Log logger = LogFactory.getLog(SiteMembershipRequestsImpl.class);
// Default role to assign to the site membership request
public final static String DEFAULT_ROLE = SiteModel.SITE_CONSUMER;
private People people;
private Sites sites;
private SiteService siteService;
private NodeService nodeService;
private InvitationService invitationService;
private NetworksService networksService;
public void setNetworksService(NetworksService networksService)
{
this.networksService = networksService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPeople(People people)
{
this.people = people;
}
public void setSites(Sites sites)
{
this.sites = sites;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
public void setInvitationService(InvitationService invitationService)
{
this.invitationService = invitationService;
}
private Invitation getSiteInvitation(String inviteeId, String siteId)
{
// Is there an outstanding site invite request for the invitee?
InvitationSearchCriteriaImpl criteria = new InvitationSearchCriteriaImpl();
criteria.setInvitationType(InvitationType.MODERATED);
criteria.setInvitee(inviteeId);
criteria.setResourceName(siteId);
criteria.setResourceType(ResourceType.WEB_SITE);
List<Invitation> invitations = invitationService.searchInvitation(criteria);
if(invitations.size() > 1)
{
// TODO exception
throw new AlfrescoRuntimeException("There should be only one outstanding site invitation");
}
return (invitations.size() == 0 ? null : invitations.get(0));
}
private List<Invitation> getSiteInvitations(String inviteeId)
{
InvitationSearchCriteriaImpl criteria = new InvitationSearchCriteriaImpl();
criteria.setInvitationType(InvitationType.MODERATED);
criteria.setInvitee(inviteeId);
criteria.setResourceType(ResourceType.WEB_SITE);
List<Invitation> invitations = invitationService.searchInvitation(criteria);
return invitations;
}
private SiteMembershipRequest inviteToModeratedSite(final String message, final String inviteeId, final String siteId,
final String inviteeRole)
{
ModeratedInvitation invitation = invitationService.inviteModerated(message, inviteeId, ResourceType.WEB_SITE, siteId, inviteeRole);
SiteMembershipRequest ret = new SiteMembershipRequest();
ret.setId(siteId);
ret.setMessage(message);
ret.setCreatedAt(invitation.getCreatedAt());
return ret;
}
private SiteMembershipRequest inviteToSite(String siteId, String inviteeId, String inviteeRole, String message)
{
siteService.setMembership(siteId, inviteeId, inviteeRole);
SiteMembershipRequest ret = new SiteMembershipRequest();
ret.setId(siteId);
ret.setMessage(message);
Date createdAt = new Date();
ret.setCreatedAt(createdAt);
return ret;
}
private SiteMembershipRequest inviteToPublicSite(final SiteInfo siteInfo, final String message, final String inviteeId,
final String inviteeRole)
{
SiteMembershipRequest siteMembershipRequest = null;
final String siteId = siteInfo.getShortName();
NodeRef siteNodeRef = siteInfo.getNodeRef();
String siteCreator = (String)nodeService.getProperty(siteNodeRef, ContentModel.PROP_CREATOR);
final String siteNetwork = networksService.getUserDefaultNetwork(siteCreator);
if(StringUtils.isNotEmpty(siteNetwork))
{
// MT
siteMembershipRequest = TenantUtil.runAsUserTenant(new TenantRunAsWork<SiteMembershipRequest>()
{
@Override
public SiteMembershipRequest doWork() throws Exception
{
return inviteToSite(siteId, inviteeId, inviteeRole, message);
}
}, siteCreator, siteNetwork);
}
else
{
siteMembershipRequest = AuthenticationUtil.runAs(new RunAsWork<SiteMembershipRequest>()
{
@Override
public SiteMembershipRequest doWork() throws Exception
{
return inviteToSite(siteId, inviteeId, inviteeRole, message);
}
}, siteCreator);
}
return siteMembershipRequest;
}
@Override
public SiteMembershipRequest createSiteMembershipRequest(String inviteeId, final SiteMembershipRequest siteInvite)
{
SiteMembershipRequest request = null;
inviteeId = people.validatePerson(inviteeId, true);
// Note that the order of error checking is important. The server first needs to check for the status 404
// conditions before checking for status 400 conditions. Otherwise the server is open to a probing attack.
String siteId = siteInvite.getId();
final SiteInfo siteInfo = sites.validateSite(siteId);
if(siteInfo == null)
{
// site does not exist
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
siteId = siteInfo.getShortName();
final SiteVisibility siteVisibility = siteInfo.getVisibility();
if(siteVisibility.equals(SiteVisibility.PRIVATE))
{
// note: security, no indication that this is a private site
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
// Is the invitee already a member of the site?
boolean isMember = siteService.isMember(siteId, inviteeId);
if(isMember)
{
// yes
throw new InvalidArgumentException(inviteeId + " is already a member of site " + siteId);
}
// Is there an outstanding site invite request for the (invitee, site)?
Invitation invitation = getSiteInvitation(inviteeId, siteId);
if(invitation != null)
{
// yes
throw new InvalidArgumentException(inviteeId + " is already invited to site " + siteId);
}
final String inviteeRole = DEFAULT_ROLE;
String message = siteInvite.getMessage();
if(message == null)
{
// the invitation service ignores null messages so convert to an empty message.
message = "";
}
if(siteVisibility.equals(SiteVisibility.MODERATED))
{
request = inviteToModeratedSite(message, inviteeId, siteId, inviteeRole);
}
else if(siteVisibility.equals(SiteVisibility.PUBLIC))
{
request = inviteToPublicSite(siteInfo, message, inviteeId, inviteeRole);
}
else
{
// note: security, no indication that this is a private site
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
return request;
}
@Override
public SiteMembershipRequest updateSiteMembershipRequest(String inviteeId, final SiteMembershipRequest siteInvite)
{
SiteMembershipRequest updatedSiteInvite = null;
inviteeId = people.validatePerson(inviteeId, true);
String siteId = siteInvite.getId();
SiteInfo siteInfo = sites.validateSite(siteId);
if(siteInfo == null)
{
// site does not exist
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
siteId = siteInfo.getShortName();
String message = siteInvite.getMessage();
if(message == null)
{
// the invitation service ignores null messages so convert to an empty message.
message = "";
}
try
{
ModeratedInvitation updatedInvitation = invitationService.updateModeratedInvitation(inviteeId, siteId, message);
if(updatedInvitation == null)
{
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
updatedSiteInvite = getSiteMembershipRequest(updatedInvitation);
}
catch(InvitationExceptionNotFound e)
{
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
if(updatedSiteInvite == null)
{
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
return updatedSiteInvite;
}
@Override
public void cancelSiteMembershipRequest(String inviteeId, String siteId)
{
inviteeId = people.validatePerson(inviteeId);
SiteInfo siteInfo = sites.validateSite(siteId);
if(siteInfo == null)
{
// site does not exist
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
siteId = siteInfo.getShortName();
Invitation invitation = getSiteInvitation(inviteeId, siteId);
if(invitation == null)
{
// no such invitation
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
invitationService.cancel(invitation.getInviteId());
}
public SiteMembershipRequest getSiteMembershipRequest(String inviteeId, final String siteId)
{
inviteeId = people.validatePerson(inviteeId);
SiteInfo siteInfo = AuthenticationUtil.runAsSystem(new RunAsWork<SiteInfo>()
{
@Override
public SiteInfo doWork() throws Exception
{
SiteInfo siteInfo = sites.validateSite(siteId);
return siteInfo;
}
});
if(siteInfo.getVisibility().equals(SiteVisibility.MODERATED))
{
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
String normalizedSiteId = siteInfo.getShortName();
Invitation invitation = getSiteInvitation(inviteeId, normalizedSiteId);
if(invitation == null)
{
// no such invitation
throw new RelationshipResourceNotFoundException(inviteeId, normalizedSiteId);
}
if(invitation instanceof ModeratedInvitation)
{
ModeratedInvitation moderatedInvitation = (ModeratedInvitation)invitation;
SiteMembershipRequest siteInvite = getSiteMembershipRequest(moderatedInvitation);
return siteInvite;
}
else
{
throw new InvalidArgumentException("Expected moderated invitation");
}
}
else
{
// non-moderated sites cannot appear in a site membership request, so throw an exception
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
}
private SiteMembershipRequest getSiteMembershipRequest(ModeratedInvitation moderatedInvitation)
{
SiteMembershipRequest siteMembershipRequest = null;
ResourceType resourceType = moderatedInvitation.getResourceType();
if(resourceType.equals(ResourceType.WEB_SITE))
{
final String siteId = moderatedInvitation.getResourceName();
SiteInfo siteInfo = AuthenticationUtil.runAsSystem(new RunAsWork<SiteInfo>()
{
@Override
public SiteInfo doWork() throws Exception
{
SiteInfo siteInfo = sites.validateSite(siteId);
return siteInfo;
}
});
if(siteInfo.getVisibility().equals(SiteVisibility.MODERATED))
{
// return a site membership request only if this is a moderated site
siteMembershipRequest = new SiteMembershipRequest();
String title = siteInfo.getTitle();
siteMembershipRequest.setTitle(title);
siteMembershipRequest.setId(siteId);
siteMembershipRequest.setMessage(moderatedInvitation.getInviteeComments());
siteMembershipRequest.setCreatedAt(moderatedInvitation.getCreatedAt());
siteMembershipRequest.setModifiedAt(moderatedInvitation.getModifiedAt());
}
}
else
{
logger.warn("Unexpected resource type " + resourceType + " for site membership request");
}
return siteMembershipRequest;
}
@Override
public CollectionWithPagingInfo<SiteMembershipRequest> getPagedSiteMembershipRequests(String personId, Paging paging)
{
personId = people.validatePerson(personId, true);
int skipCount = paging.getSkipCount();
int maxItems = paging.getMaxItems();
int max = skipCount + maxItems + 1; // to detect hasMoreItems
List<Invitation> invitations = getSiteInvitations(personId);
List<SiteMembershipRequest> siteMembershipRequests = new ArrayList<SiteMembershipRequest>(invitations.size());
for(Invitation invitation : invitations)
{
if(invitation instanceof ModeratedInvitation)
{
ModeratedInvitation moderatedInvitation = (ModeratedInvitation)invitation;
SiteMembershipRequest siteMembershipRequest = getSiteMembershipRequest(moderatedInvitation);
if(siteMembershipRequest != null)
{
// note: siteMembershipRequest may be null if the site is now no longer a moderated site
// or if the invitation is malformed and does not refer to a site.
siteMembershipRequests.add(siteMembershipRequest);
}
}
else
{
// just ignore, shouldn't happen because getSiteInvitations filters by ModeratedInvitation
}
}
// unfortunately, need to sort in memory because there's no way to get site membership requests sorted by title from
// the workflow apis
Collections.sort(siteMembershipRequests);
int totalItems = siteMembershipRequests.size();
if(skipCount >= totalItems)
{
List<SiteMembershipRequest> empty = Collections.emptyList();
return CollectionWithPagingInfo.asPaged(paging, empty, false, totalItems);
}
else
{
int end = Math.min(max - 1, totalItems);
boolean hasMoreItems = totalItems > end;
siteMembershipRequests = siteMembershipRequests.subList(skipCount, end);
return CollectionWithPagingInfo.asPaged(paging, siteMembershipRequests, hasMoreItems, totalItems);
}
}
}
package org.alfresco.rest.api.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.invitation.InvitationSearchCriteriaImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.rest.api.People;
import org.alfresco.rest.api.SiteMembershipRequests;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.model.SiteMembershipRequest;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.invitation.Invitation;
import org.alfresco.service.cmr.invitation.Invitation.ResourceType;
import org.alfresco.service.cmr.invitation.InvitationExceptionNotFound;
import org.alfresco.service.cmr.invitation.InvitationSearchCriteria.InvitationType;
import org.alfresco.service.cmr.invitation.InvitationService;
import org.alfresco.service.cmr.invitation.ModeratedInvitation;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Public REST API: centralises access to site membership requests and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class SiteMembershipRequestsImpl implements SiteMembershipRequests
{
private static final Log logger = LogFactory.getLog(SiteMembershipRequestsImpl.class);
// Default role to assign to the site membership request
public final static String DEFAULT_ROLE = SiteModel.SITE_CONSUMER;
private People people;
private Sites sites;
private SiteService siteService;
private NodeService nodeService;
private InvitationService invitationService;
private NetworksService networksService;
public void setNetworksService(NetworksService networksService)
{
this.networksService = networksService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPeople(People people)
{
this.people = people;
}
public void setSites(Sites sites)
{
this.sites = sites;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
public void setInvitationService(InvitationService invitationService)
{
this.invitationService = invitationService;
}
private Invitation getSiteInvitation(String inviteeId, String siteId)
{
// Is there an outstanding site invite request for the invitee?
InvitationSearchCriteriaImpl criteria = new InvitationSearchCriteriaImpl();
criteria.setInvitationType(InvitationType.MODERATED);
criteria.setInvitee(inviteeId);
criteria.setResourceName(siteId);
criteria.setResourceType(ResourceType.WEB_SITE);
List<Invitation> invitations = invitationService.searchInvitation(criteria);
if(invitations.size() > 1)
{
// TODO exception
throw new AlfrescoRuntimeException("There should be only one outstanding site invitation");
}
return (invitations.size() == 0 ? null : invitations.get(0));
}
private List<Invitation> getSiteInvitations(String inviteeId)
{
InvitationSearchCriteriaImpl criteria = new InvitationSearchCriteriaImpl();
criteria.setInvitationType(InvitationType.MODERATED);
criteria.setInvitee(inviteeId);
criteria.setResourceType(ResourceType.WEB_SITE);
List<Invitation> invitations = invitationService.searchInvitation(criteria);
return invitations;
}
private SiteMembershipRequest inviteToModeratedSite(final String message, final String inviteeId, final String siteId,
final String inviteeRole)
{
ModeratedInvitation invitation = invitationService.inviteModerated(message, inviteeId, ResourceType.WEB_SITE, siteId, inviteeRole);
SiteMembershipRequest ret = new SiteMembershipRequest();
ret.setId(siteId);
ret.setMessage(message);
ret.setCreatedAt(invitation.getCreatedAt());
return ret;
}
private SiteMembershipRequest inviteToSite(String siteId, String inviteeId, String inviteeRole, String message)
{
siteService.setMembership(siteId, inviteeId, inviteeRole);
SiteMembershipRequest ret = new SiteMembershipRequest();
ret.setId(siteId);
ret.setMessage(message);
Date createdAt = new Date();
ret.setCreatedAt(createdAt);
return ret;
}
private SiteMembershipRequest inviteToPublicSite(final SiteInfo siteInfo, final String message, final String inviteeId,
final String inviteeRole)
{
SiteMembershipRequest siteMembershipRequest = null;
final String siteId = siteInfo.getShortName();
NodeRef siteNodeRef = siteInfo.getNodeRef();
String siteCreator = (String)nodeService.getProperty(siteNodeRef, ContentModel.PROP_CREATOR);
final String siteNetwork = networksService.getUserDefaultNetwork(siteCreator);
if(StringUtils.isNotEmpty(siteNetwork))
{
// MT
siteMembershipRequest = TenantUtil.runAsUserTenant(new TenantRunAsWork<SiteMembershipRequest>()
{
@Override
public SiteMembershipRequest doWork() throws Exception
{
return inviteToSite(siteId, inviteeId, inviteeRole, message);
}
}, siteCreator, siteNetwork);
}
else
{
siteMembershipRequest = AuthenticationUtil.runAs(new RunAsWork<SiteMembershipRequest>()
{
@Override
public SiteMembershipRequest doWork() throws Exception
{
return inviteToSite(siteId, inviteeId, inviteeRole, message);
}
}, siteCreator);
}
return siteMembershipRequest;
}
@Override
public SiteMembershipRequest createSiteMembershipRequest(String inviteeId, final SiteMembershipRequest siteInvite)
{
SiteMembershipRequest request = null;
inviteeId = people.validatePerson(inviteeId, true);
// Note that the order of error checking is important. The server first needs to check for the status 404
// conditions before checking for status 400 conditions. Otherwise the server is open to a probing attack.
String siteId = siteInvite.getId();
final SiteInfo siteInfo = sites.validateSite(siteId);
if(siteInfo == null)
{
// site does not exist
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
siteId = siteInfo.getShortName();
final SiteVisibility siteVisibility = siteInfo.getVisibility();
if(siteVisibility.equals(SiteVisibility.PRIVATE))
{
// note: security, no indication that this is a private site
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
// Is the invitee already a member of the site?
boolean isMember = siteService.isMember(siteId, inviteeId);
if(isMember)
{
// yes
throw new InvalidArgumentException(inviteeId + " is already a member of site " + siteId);
}
// Is there an outstanding site invite request for the (invitee, site)?
Invitation invitation = getSiteInvitation(inviteeId, siteId);
if(invitation != null)
{
// yes
throw new InvalidArgumentException(inviteeId + " is already invited to site " + siteId);
}
final String inviteeRole = DEFAULT_ROLE;
String message = siteInvite.getMessage();
if(message == null)
{
// the invitation service ignores null messages so convert to an empty message.
message = "";
}
if(siteVisibility.equals(SiteVisibility.MODERATED))
{
request = inviteToModeratedSite(message, inviteeId, siteId, inviteeRole);
}
else if(siteVisibility.equals(SiteVisibility.PUBLIC))
{
request = inviteToPublicSite(siteInfo, message, inviteeId, inviteeRole);
}
else
{
// note: security, no indication that this is a private site
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
return request;
}
@Override
public SiteMembershipRequest updateSiteMembershipRequest(String inviteeId, final SiteMembershipRequest siteInvite)
{
SiteMembershipRequest updatedSiteInvite = null;
inviteeId = people.validatePerson(inviteeId, true);
String siteId = siteInvite.getId();
SiteInfo siteInfo = sites.validateSite(siteId);
if(siteInfo == null)
{
// site does not exist
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
siteId = siteInfo.getShortName();
String message = siteInvite.getMessage();
if(message == null)
{
// the invitation service ignores null messages so convert to an empty message.
message = "";
}
try
{
ModeratedInvitation updatedInvitation = invitationService.updateModeratedInvitation(inviteeId, siteId, message);
if(updatedInvitation == null)
{
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
updatedSiteInvite = getSiteMembershipRequest(updatedInvitation);
}
catch(InvitationExceptionNotFound e)
{
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
if(updatedSiteInvite == null)
{
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
return updatedSiteInvite;
}
@Override
public void cancelSiteMembershipRequest(String inviteeId, String siteId)
{
inviteeId = people.validatePerson(inviteeId);
SiteInfo siteInfo = sites.validateSite(siteId);
if(siteInfo == null)
{
// site does not exist
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
siteId = siteInfo.getShortName();
Invitation invitation = getSiteInvitation(inviteeId, siteId);
if(invitation == null)
{
// no such invitation
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
invitationService.cancel(invitation.getInviteId());
}
public SiteMembershipRequest getSiteMembershipRequest(String inviteeId, final String siteId)
{
inviteeId = people.validatePerson(inviteeId);
SiteInfo siteInfo = AuthenticationUtil.runAsSystem(new RunAsWork<SiteInfo>()
{
@Override
public SiteInfo doWork() throws Exception
{
SiteInfo siteInfo = sites.validateSite(siteId);
return siteInfo;
}
});
if(siteInfo.getVisibility().equals(SiteVisibility.MODERATED))
{
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
String normalizedSiteId = siteInfo.getShortName();
Invitation invitation = getSiteInvitation(inviteeId, normalizedSiteId);
if(invitation == null)
{
// no such invitation
throw new RelationshipResourceNotFoundException(inviteeId, normalizedSiteId);
}
if(invitation instanceof ModeratedInvitation)
{
ModeratedInvitation moderatedInvitation = (ModeratedInvitation)invitation;
SiteMembershipRequest siteInvite = getSiteMembershipRequest(moderatedInvitation);
return siteInvite;
}
else
{
throw new InvalidArgumentException("Expected moderated invitation");
}
}
else
{
// non-moderated sites cannot appear in a site membership request, so throw an exception
throw new RelationshipResourceNotFoundException(inviteeId, siteId);
}
}
private SiteMembershipRequest getSiteMembershipRequest(ModeratedInvitation moderatedInvitation)
{
SiteMembershipRequest siteMembershipRequest = null;
ResourceType resourceType = moderatedInvitation.getResourceType();
if(resourceType.equals(ResourceType.WEB_SITE))
{
final String siteId = moderatedInvitation.getResourceName();
SiteInfo siteInfo = AuthenticationUtil.runAsSystem(new RunAsWork<SiteInfo>()
{
@Override
public SiteInfo doWork() throws Exception
{
SiteInfo siteInfo = sites.validateSite(siteId);
return siteInfo;
}
});
if(siteInfo.getVisibility().equals(SiteVisibility.MODERATED))
{
// return a site membership request only if this is a moderated site
siteMembershipRequest = new SiteMembershipRequest();
String title = siteInfo.getTitle();
siteMembershipRequest.setTitle(title);
siteMembershipRequest.setId(siteId);
siteMembershipRequest.setMessage(moderatedInvitation.getInviteeComments());
siteMembershipRequest.setCreatedAt(moderatedInvitation.getCreatedAt());
siteMembershipRequest.setModifiedAt(moderatedInvitation.getModifiedAt());
}
}
else
{
logger.warn("Unexpected resource type " + resourceType + " for site membership request");
}
return siteMembershipRequest;
}
@Override
public CollectionWithPagingInfo<SiteMembershipRequest> getPagedSiteMembershipRequests(String personId, Paging paging)
{
personId = people.validatePerson(personId, true);
int skipCount = paging.getSkipCount();
int maxItems = paging.getMaxItems();
int max = skipCount + maxItems + 1; // to detect hasMoreItems
List<Invitation> invitations = getSiteInvitations(personId);
List<SiteMembershipRequest> siteMembershipRequests = new ArrayList<SiteMembershipRequest>(invitations.size());
for(Invitation invitation : invitations)
{
if(invitation instanceof ModeratedInvitation)
{
ModeratedInvitation moderatedInvitation = (ModeratedInvitation)invitation;
SiteMembershipRequest siteMembershipRequest = getSiteMembershipRequest(moderatedInvitation);
if(siteMembershipRequest != null)
{
// note: siteMembershipRequest may be null if the site is now no longer a moderated site
// or if the invitation is malformed and does not refer to a site.
siteMembershipRequests.add(siteMembershipRequest);
}
}
else
{
// just ignore, shouldn't happen because getSiteInvitations filters by ModeratedInvitation
}
}
// unfortunately, need to sort in memory because there's no way to get site membership requests sorted by title from
// the workflow apis
Collections.sort(siteMembershipRequests);
int totalItems = siteMembershipRequests.size();
if(skipCount >= totalItems)
{
List<SiteMembershipRequest> empty = Collections.emptyList();
return CollectionWithPagingInfo.asPaged(paging, empty, false, totalItems);
}
else
{
int end = Math.min(max - 1, totalItems);
boolean hasMoreItems = totalItems > end;
siteMembershipRequests = siteMembershipRequests.subList(skipCount, end);
return CollectionWithPagingInfo.asPaged(paging, siteMembershipRequests, hasMoreItems, totalItems);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,188 +1,188 @@
package org.alfresco.rest.api.impl;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.tagging.NonExistentTagException;
import org.alfresco.repo.tagging.TagExistsException;
import org.alfresco.repo.tagging.TaggingException;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.Tags;
import org.alfresco.rest.api.model.Tag;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.util.Pair;
import org.alfresco.util.TypeConstraint;
/**
* Centralises access to tag services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class TagsImpl implements Tags
{
private Nodes nodes;
private TaggingService taggingService;
private TypeConstraint typeConstraint;
public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setTaggingService(TaggingService taggingService)
{
this.taggingService = taggingService;
}
public List<Tag> addTags(String nodeId, final List<Tag> tags)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
if(!typeConstraint.matches(nodeRef))
{
throw new UnsupportedResourceOperationException("Cannot tag this node");
}
List<String> tagValues = new AbstractList<String>()
{
@Override
public String get(int arg0)
{
String tag = tags.get(arg0).getTag();
return tag;
}
@Override
public int size()
{
return tags.size();
}
};
try
{
List<Pair<String, NodeRef>> tagNodeRefs = taggingService.addTags(nodeRef, tagValues);
List<Tag> ret = new ArrayList<Tag>(tags.size());
for(Pair<String, NodeRef> pair : tagNodeRefs)
{
ret.add(new Tag(pair.getSecond(), pair.getFirst()));
}
return ret;
}
catch(IllegalArgumentException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public void deleteTag(String nodeId, String tagId)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
getTag(tagId);
NodeRef existingTagNodeRef = validateTag(tagId);
String tagValue = taggingService.getTagName(existingTagNodeRef);
taggingService.removeTag(nodeRef, tagValue);
}
public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Paging paging)
{
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(storeRef, Util.getPagingRequest(paging));
Integer totalItems = results.getTotalResultCount().getFirst();
List<Pair<NodeRef, String>> page = results.getPage();
List<Tag> tags = new ArrayList<Tag>(page.size());
for(Pair<NodeRef, String> pair : page)
{
tags.add(new Tag(pair.getFirst(), pair.getSecond()));
}
return CollectionWithPagingInfo.asPaged(paging, tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue()));
}
public NodeRef validateTag(String tagId)
{
NodeRef tagNodeRef = nodes.validateNode(tagId);
if(tagNodeRef == null)
{
throw new EntityNotFoundException(tagId);
}
return tagNodeRef;
}
public NodeRef validateTag(StoreRef storeRef, String tagId)
{
NodeRef tagNodeRef = nodes.validateNode(storeRef, tagId);
if(tagNodeRef == null)
{
throw new EntityNotFoundException(tagId);
}
return tagNodeRef;
}
public Tag changeTag(StoreRef storeRef, String tagId, Tag tag)
{
try
{
NodeRef existingTagNodeRef = validateTag(storeRef, tagId);
String existingTagName = taggingService.getTagName(existingTagNodeRef);
String newTagName = tag.getTag();
NodeRef newTagNodeRef = taggingService.changeTag(storeRef, existingTagName, newTagName);
return new Tag(newTagNodeRef, newTagName);
}
catch(NonExistentTagException e)
{
throw new NotFoundException(e.getMessage());
}
catch(TagExistsException e)
{
throw new ConstraintViolatedException(e.getMessage());
}
catch(TaggingException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public Tag getTag(String tagId)
{
return getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, tagId);
}
public Tag getTag(StoreRef storeRef, String tagId)
{
NodeRef tagNodeRef = validateTag(storeRef, tagId);
String tagValue = taggingService.getTagName(tagNodeRef);
return new Tag(tagNodeRef, tagValue);
}
public CollectionWithPagingInfo<Tag> getTags(String nodeId, Parameters params)
{
NodeRef nodeRef = validateTag(nodeId);
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging()));
Integer totalItems = results.getTotalResultCount().getFirst();
List<Pair<NodeRef, String>> page = results.getPage();
List<Tag> tags = new ArrayList<Tag>(page.size());
for(Pair<NodeRef, String> pair : page)
{
tags.add(new Tag(pair.getFirst(), pair.getSecond()));
}
return CollectionWithPagingInfo.asPaged(params.getPaging(), tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue()));
}
}
package org.alfresco.rest.api.impl;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.tagging.NonExistentTagException;
import org.alfresco.repo.tagging.TagExistsException;
import org.alfresco.repo.tagging.TaggingException;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.Tags;
import org.alfresco.rest.api.model.Tag;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.util.Pair;
import org.alfresco.util.TypeConstraint;
/**
* Centralises access to tag services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class TagsImpl implements Tags
{
private Nodes nodes;
private TaggingService taggingService;
private TypeConstraint typeConstraint;
public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setTaggingService(TaggingService taggingService)
{
this.taggingService = taggingService;
}
public List<Tag> addTags(String nodeId, final List<Tag> tags)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
if(!typeConstraint.matches(nodeRef))
{
throw new UnsupportedResourceOperationException("Cannot tag this node");
}
List<String> tagValues = new AbstractList<String>()
{
@Override
public String get(int arg0)
{
String tag = tags.get(arg0).getTag();
return tag;
}
@Override
public int size()
{
return tags.size();
}
};
try
{
List<Pair<String, NodeRef>> tagNodeRefs = taggingService.addTags(nodeRef, tagValues);
List<Tag> ret = new ArrayList<Tag>(tags.size());
for(Pair<String, NodeRef> pair : tagNodeRefs)
{
ret.add(new Tag(pair.getSecond(), pair.getFirst()));
}
return ret;
}
catch(IllegalArgumentException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public void deleteTag(String nodeId, String tagId)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
getTag(tagId);
NodeRef existingTagNodeRef = validateTag(tagId);
String tagValue = taggingService.getTagName(existingTagNodeRef);
taggingService.removeTag(nodeRef, tagValue);
}
public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Paging paging)
{
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(storeRef, Util.getPagingRequest(paging));
Integer totalItems = results.getTotalResultCount().getFirst();
List<Pair<NodeRef, String>> page = results.getPage();
List<Tag> tags = new ArrayList<Tag>(page.size());
for(Pair<NodeRef, String> pair : page)
{
tags.add(new Tag(pair.getFirst(), pair.getSecond()));
}
return CollectionWithPagingInfo.asPaged(paging, tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue()));
}
public NodeRef validateTag(String tagId)
{
NodeRef tagNodeRef = nodes.validateNode(tagId);
if(tagNodeRef == null)
{
throw new EntityNotFoundException(tagId);
}
return tagNodeRef;
}
public NodeRef validateTag(StoreRef storeRef, String tagId)
{
NodeRef tagNodeRef = nodes.validateNode(storeRef, tagId);
if(tagNodeRef == null)
{
throw new EntityNotFoundException(tagId);
}
return tagNodeRef;
}
public Tag changeTag(StoreRef storeRef, String tagId, Tag tag)
{
try
{
NodeRef existingTagNodeRef = validateTag(storeRef, tagId);
String existingTagName = taggingService.getTagName(existingTagNodeRef);
String newTagName = tag.getTag();
NodeRef newTagNodeRef = taggingService.changeTag(storeRef, existingTagName, newTagName);
return new Tag(newTagNodeRef, newTagName);
}
catch(NonExistentTagException e)
{
throw new NotFoundException(e.getMessage());
}
catch(TagExistsException e)
{
throw new ConstraintViolatedException(e.getMessage());
}
catch(TaggingException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public Tag getTag(String tagId)
{
return getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, tagId);
}
public Tag getTag(StoreRef storeRef, String tagId)
{
NodeRef tagNodeRef = validateTag(storeRef, tagId);
String tagValue = taggingService.getTagName(tagNodeRef);
return new Tag(tagNodeRef, tagValue);
}
public CollectionWithPagingInfo<Tag> getTags(String nodeId, Parameters params)
{
NodeRef nodeRef = validateTag(nodeId);
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging()));
Integer totalItems = results.getTotalResultCount().getFirst();
List<Pair<NodeRef, String>> page = results.getPage();
List<Tag> tags = new ArrayList<Tag>(page.size());
for(Pair<NodeRef, String> pair : page)
{
tags.add(new Tag(pair.getFirst(), pair.getSecond()));
}
return CollectionWithPagingInfo.asPaged(params.getPaging(), tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue()));
}
}

View File

@@ -1,15 +1,15 @@
package org.alfresco.rest.api.impl;
import org.alfresco.query.CannedQueryPageDetails;
import org.alfresco.query.PagingRequest;
import org.alfresco.rest.framework.resource.parameters.Paging;
public class Util
{
public static PagingRequest getPagingRequest(Paging paging)
{
PagingRequest pagingRequest = new PagingRequest(paging.getSkipCount(), paging.getMaxItems());
pagingRequest.setRequestTotalCountMax(CannedQueryPageDetails.DEFAULT_PAGE_SIZE);
return pagingRequest;
}
}
package org.alfresco.rest.api.impl;
import org.alfresco.query.CannedQueryPageDetails;
import org.alfresco.query.PagingRequest;
import org.alfresco.rest.framework.resource.parameters.Paging;
public class Util
{
public static PagingRequest getPagingRequest(Paging paging)
{
PagingRequest pagingRequest = new PagingRequest(paging.getSkipCount(), paging.getMaxItems());
pagingRequest.setRequestTotalCountMax(CannedQueryPageDetails.DEFAULT_PAGE_SIZE);
return pagingRequest;
}
}

View File

@@ -1,119 +1,119 @@
package org.alfresco.rest.api.impl.activities;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
public abstract class AbstractActivitySummaryProcessor extends AbstractLifecycleBean implements ActivitySummaryProcessor
{
protected static Log logger = LogFactory.getLog(ActivitySummaryProcessor.class);
protected ActivitySummaryProcessorRegistry registry;
private List<String> eventTypes;
public void setEventTypes(List<String> eventTypes)
{
this.eventTypes = eventTypes;
}
public void setRegistry(ActivitySummaryProcessorRegistry registry)
{
this.registry = registry;
}
public void setCustomRenditions(List<String> eventTypes)
{
this.eventTypes = eventTypes;
}
/*
* (non-Javadoc)
* @see org.springframework.extensions.surf.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent)
*/
protected void onBootstrap(ApplicationEvent event)
{
register();
}
protected void onShutdown(ApplicationEvent event)
{
}
@Override
public Map<String, Object> process(Map<String, Object> entries)
{
List<Change> changes = new LinkedList<Change>();
Map<String, Object> ret = new HashMap<String, Object>(entries.size());
for(Map.Entry<String, Object> entry : entries.entrySet())
{
String key = entry.getKey();
Object value = entry.getValue();
Change change = processEntry(key, value);
if(change != null)
{
changes.add(change);
}
}
for(Change change : changes)
{
if(change != null)
{
change.process(entries);
}
}
return ret;
}
protected abstract Change processEntry(String key, Object value);
protected void register()
{
for(String eventType : eventTypes)
{
registry.register(eventType, this);
}
}
public static class ChangeKey implements Change
{
private String oldKey;
private String newKey;
public ChangeKey(String oldKey, String newKey) {
super();
this.oldKey = oldKey;
this.newKey = newKey;
}
public void process(Map<String, Object> entries)
{
Object value = entries.remove(oldKey);
entries.put(newKey, value);
}
}
public static class RemoveKey implements Change
{
private String key;
public RemoveKey(String key) {
super();
this.key = key;
}
public void process(Map<String, Object> entries)
{
entries.remove(key);
}
}
}
package org.alfresco.rest.api.impl.activities;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
public abstract class AbstractActivitySummaryProcessor extends AbstractLifecycleBean implements ActivitySummaryProcessor
{
protected static Log logger = LogFactory.getLog(ActivitySummaryProcessor.class);
protected ActivitySummaryProcessorRegistry registry;
private List<String> eventTypes;
public void setEventTypes(List<String> eventTypes)
{
this.eventTypes = eventTypes;
}
public void setRegistry(ActivitySummaryProcessorRegistry registry)
{
this.registry = registry;
}
public void setCustomRenditions(List<String> eventTypes)
{
this.eventTypes = eventTypes;
}
/*
* (non-Javadoc)
* @see org.springframework.extensions.surf.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent)
*/
protected void onBootstrap(ApplicationEvent event)
{
register();
}
protected void onShutdown(ApplicationEvent event)
{
}
@Override
public Map<String, Object> process(Map<String, Object> entries)
{
List<Change> changes = new LinkedList<Change>();
Map<String, Object> ret = new HashMap<String, Object>(entries.size());
for(Map.Entry<String, Object> entry : entries.entrySet())
{
String key = entry.getKey();
Object value = entry.getValue();
Change change = processEntry(key, value);
if(change != null)
{
changes.add(change);
}
}
for(Change change : changes)
{
if(change != null)
{
change.process(entries);
}
}
return ret;
}
protected abstract Change processEntry(String key, Object value);
protected void register()
{
for(String eventType : eventTypes)
{
registry.register(eventType, this);
}
}
public static class ChangeKey implements Change
{
private String oldKey;
private String newKey;
public ChangeKey(String oldKey, String newKey) {
super();
this.oldKey = oldKey;
this.newKey = newKey;
}
public void process(Map<String, Object> entries)
{
Object value = entries.remove(oldKey);
entries.put(newKey, value);
}
}
public static class RemoveKey implements Change
{
private String key;
public RemoveKey(String key) {
super();
this.key = key;
}
public void process(Map<String, Object> entries)
{
entries.remove(key);
}
}
}

View File

@@ -1,168 +1,168 @@
package org.alfresco.rest.api.impl.activities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.registry.NamedObjectRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.springframework.extensions.surf.util.ISO8601DateFormat;
/*
* Adapted from JSONtoFmModel
*/
public class ActivitySummaryParser implements ActivitySummaryProcessorRegistry
{
private final Log logger = LogFactory.getLog(ActivitySummaryParser.class);
// note: current format is dependent on ISO8601DateFormat.parser, eg. YYYY-MM-DDThh:mm:ss.sssTZD
private static String REGEXP_ISO8061 = "^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(.([0-9]){3})?(Z|[\\+\\-]([0-9]{2}):([0-9]{2}))$";
private static Pattern matcherISO8601 = Pattern.compile(REGEXP_ISO8061);
private static final Pattern nodeRefPattern = Pattern.compile("^[a-zA-Z]+://.+/.+");
private NamedObjectRegistry<ActivitySummaryProcessor> processors;
private boolean autoConvertISO8601 = true;
public ActivitySummaryParser()
{
}
public void setProcessors(NamedObjectRegistry<ActivitySummaryProcessor> processors)
{
this.processors = processors;
}
public void register(String activityType, ActivitySummaryProcessor processor)
{
ActivitySummaryProcessor existingProcessor = processors.getNamedObject(activityType);
if(existingProcessor != null)
{
logger.warn("Activity summary processor " + existingProcessor + " is being overridden by " + processor + " for activity type " + activityType);
}
processors.register(activityType, processor);
}
private void processActivitySummary(String activityType, Map<String, Object> entries)
{
ActivitySummaryProcessor processor = processors.getNamedObject(activityType);
if(processor == null)
{
processor = new BaseActivitySummaryProcessor();
}
processor.process(entries);
}
public Map<String, Object> parse(String activityType, String activitySummary) throws JSONException
{
JSONObject json = (JSONObject)JSONValue.parse(activitySummary);
Map<String, Object> map = convertJSONObjectToMap(json);
processActivitySummary(activityType, map);
return map;
}
/**
* Determine if passed string conforms to the pattern of a node reference
*
* @param nodeRef the node reference as a string
* @return true => it matches the pattern of a node reference
*/
private boolean isNodeRef(String nodeRef)
{
Matcher matcher = nodeRefPattern.matcher(nodeRef);
return matcher.matches();
}
Map<String, Object> convertJSONObjectToMap(JSONObject jo) throws JSONException
{
Map<String, Object> model = new HashMap<String, Object>();
for(Object key : jo.keySet())
{
Object value = jo.get(key);
if (value instanceof JSONObject)
{
model.put((String)key, convertJSONObjectToMap((JSONObject)value));
}
else if (value instanceof JSONArray)
{
model.put((String)key, convertJSONArrayToList((JSONArray)value));
}
else if (value == null)
{
model.put((String)key, null);
}
else
{
if ((value instanceof String) && autoConvertISO8601 && (matcherISO8601.matcher((String)value).matches()))
{
value = ISO8601DateFormat.parse((String)value);
}
if ((value instanceof String) && isNodeRef((String)value))
{
try
{
value = new NodeRef((String)value);
}
catch(AlfrescoRuntimeException e)
{
// cannot convert to a nodeRef, just keep as a string
logger.warn("Cannot convert activity summary NodeRef string " + value + " to a NodeRef");
}
}
model.put((String)key, value);
}
}
return model;
}
List<Object> convertJSONArrayToList(JSONArray ja) throws JSONException
{
List<Object> model = new ArrayList<Object>();
for (int i = 0; i < ja.size(); i++)
{
Object o = ja.get(i);
if (o instanceof JSONArray)
{
model.add(convertJSONArrayToList((JSONArray)o));
}
else if (o instanceof JSONObject)
{
model.add(convertJSONObjectToMap((JSONObject)o));
}
else if (o == null)
{
model.add(null);
}
else
{
if ((o instanceof String) && autoConvertISO8601 && (matcherISO8601.matcher((String)o).matches()))
{
o = ISO8601DateFormat.parse((String)o);
}
model.add(o);
}
}
return model;
}
}
package org.alfresco.rest.api.impl.activities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.registry.NamedObjectRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.springframework.extensions.surf.util.ISO8601DateFormat;
/*
* Adapted from JSONtoFmModel
*/
public class ActivitySummaryParser implements ActivitySummaryProcessorRegistry
{
private final Log logger = LogFactory.getLog(ActivitySummaryParser.class);
// note: current format is dependent on ISO8601DateFormat.parser, eg. YYYY-MM-DDThh:mm:ss.sssTZD
private static String REGEXP_ISO8061 = "^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(.([0-9]){3})?(Z|[\\+\\-]([0-9]{2}):([0-9]{2}))$";
private static Pattern matcherISO8601 = Pattern.compile(REGEXP_ISO8061);
private static final Pattern nodeRefPattern = Pattern.compile("^[a-zA-Z]+://.+/.+");
private NamedObjectRegistry<ActivitySummaryProcessor> processors;
private boolean autoConvertISO8601 = true;
public ActivitySummaryParser()
{
}
public void setProcessors(NamedObjectRegistry<ActivitySummaryProcessor> processors)
{
this.processors = processors;
}
public void register(String activityType, ActivitySummaryProcessor processor)
{
ActivitySummaryProcessor existingProcessor = processors.getNamedObject(activityType);
if(existingProcessor != null)
{
logger.warn("Activity summary processor " + existingProcessor + " is being overridden by " + processor + " for activity type " + activityType);
}
processors.register(activityType, processor);
}
private void processActivitySummary(String activityType, Map<String, Object> entries)
{
ActivitySummaryProcessor processor = processors.getNamedObject(activityType);
if(processor == null)
{
processor = new BaseActivitySummaryProcessor();
}
processor.process(entries);
}
public Map<String, Object> parse(String activityType, String activitySummary) throws JSONException
{
JSONObject json = (JSONObject)JSONValue.parse(activitySummary);
Map<String, Object> map = convertJSONObjectToMap(json);
processActivitySummary(activityType, map);
return map;
}
/**
* Determine if passed string conforms to the pattern of a node reference
*
* @param nodeRef the node reference as a string
* @return true => it matches the pattern of a node reference
*/
private boolean isNodeRef(String nodeRef)
{
Matcher matcher = nodeRefPattern.matcher(nodeRef);
return matcher.matches();
}
Map<String, Object> convertJSONObjectToMap(JSONObject jo) throws JSONException
{
Map<String, Object> model = new HashMap<String, Object>();
for(Object key : jo.keySet())
{
Object value = jo.get(key);
if (value instanceof JSONObject)
{
model.put((String)key, convertJSONObjectToMap((JSONObject)value));
}
else if (value instanceof JSONArray)
{
model.put((String)key, convertJSONArrayToList((JSONArray)value));
}
else if (value == null)
{
model.put((String)key, null);
}
else
{
if ((value instanceof String) && autoConvertISO8601 && (matcherISO8601.matcher((String)value).matches()))
{
value = ISO8601DateFormat.parse((String)value);
}
if ((value instanceof String) && isNodeRef((String)value))
{
try
{
value = new NodeRef((String)value);
}
catch(AlfrescoRuntimeException e)
{
// cannot convert to a nodeRef, just keep as a string
logger.warn("Cannot convert activity summary NodeRef string " + value + " to a NodeRef");
}
}
model.put((String)key, value);
}
}
return model;
}
List<Object> convertJSONArrayToList(JSONArray ja) throws JSONException
{
List<Object> model = new ArrayList<Object>();
for (int i = 0; i < ja.size(); i++)
{
Object o = ja.get(i);
if (o instanceof JSONArray)
{
model.add(convertJSONArrayToList((JSONArray)o));
}
else if (o instanceof JSONObject)
{
model.add(convertJSONObjectToMap((JSONObject)o));
}
else if (o == null)
{
model.add(null);
}
else
{
if ((o instanceof String) && autoConvertISO8601 && (matcherISO8601.matcher((String)o).matches()))
{
o = ISO8601DateFormat.parse((String)o);
}
model.add(o);
}
}
return model;
}
}

View File

@@ -1,13 +1,13 @@
package org.alfresco.rest.api.impl.activities;
import java.util.Map;
public interface ActivitySummaryProcessor
{
public interface Change
{
void process(Map<String, Object> entries);
}
public Map<String, Object> process(Map<String, Object> entries);
}
package org.alfresco.rest.api.impl.activities;
import java.util.Map;
public interface ActivitySummaryProcessor
{
public interface Change
{
void process(Map<String, Object> entries);
}
public Map<String, Object> process(Map<String, Object> entries);
}

View File

@@ -1,12 +1,12 @@
package org.alfresco.rest.api.impl.activities;
/**
* A registry for activity summary parsers/post processors.
*
* @author steveglover
*
*/
public interface ActivitySummaryProcessorRegistry
{
public void register(String activityType, ActivitySummaryProcessor processor);
}
package org.alfresco.rest.api.impl.activities;
/**
* A registry for activity summary parsers/post processors.
*
* @author steveglover
*
*/
public interface ActivitySummaryProcessorRegistry
{
public void register(String activityType, ActivitySummaryProcessor processor);
}

View File

@@ -1,96 +1,96 @@
package org.alfresco.rest.api.impl.activities;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.alfresco.rest.api.impl.activities.AbstractActivitySummaryProcessor.RemoveKey;
import org.alfresco.service.cmr.repository.NodeRef;
public class BaseActivitySummaryProcessor extends AbstractActivitySummaryProcessor
{
@Override
protected Change processEntry(String key, Object value)
{
Change change = null;
if(key.equals("page"))
{
change = new ChangePageValue(key);
}
if(key.equals("tenantDomain"))
{
change = new RemoveKey(key);
}
if(key.equals("nodeRef"))
{
change = new ChangeKey(key, "objectId");
}
if(key.equals("parentNodeRef"))
{
change = new ChangeKey(key, "parentObjectId");
}
// remove null or empty properties
if(value == null || value.equals(""))
{
change = new RemoveKey(key);
}
return change;
}
public static class ChangePageValue implements Change
{
private String key;
private static final String regex = Pattern.quote("document-details?nodeRef=") + "(.*)";
private static final Pattern pattern = Pattern.compile(regex);
public ChangePageValue(String key) {
super();
this.key = key;
}
/*
* Extract and output the node id from input that looks like this: document-details?nodeRef=workspace%3A%2F%2FSpacesStore%2Fd4c1a75e-a17e-4033-94f4-988cca39a357 (non-Javadoc)
*
* @see org.alfresco.rest.api.impl.activities.ActivitySummaryProcessor.Change#process(java.util.Map)
*/
public void process(Map<String, Object> entries)
{
String value = (String)entries.remove(key);
try
{
value = URLDecoder.decode(value, "UTF-8");
Matcher matcher = pattern.matcher(value);
if(matcher.matches())
{
String nodeRefStr = matcher.group(1);
boolean isNodeRef = NodeRef.isNodeRef(nodeRefStr);
if(isNodeRef)
{
NodeRef nodeRef = new NodeRef(nodeRefStr);
entries.put("objectId", nodeRef.getId());
}
else
{
logger.warn("Activity page url contains an invalid NodeRef " + value);
}
}
else
{
logger.warn("Failed to match activity page url for objectId extraction " + value);
}
}
catch (UnsupportedEncodingException e)
{
logger.warn("Unable to decode activity page url " + value);
}
}
}
}
package org.alfresco.rest.api.impl.activities;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.alfresco.rest.api.impl.activities.AbstractActivitySummaryProcessor.RemoveKey;
import org.alfresco.service.cmr.repository.NodeRef;
public class BaseActivitySummaryProcessor extends AbstractActivitySummaryProcessor
{
@Override
protected Change processEntry(String key, Object value)
{
Change change = null;
if(key.equals("page"))
{
change = new ChangePageValue(key);
}
if(key.equals("tenantDomain"))
{
change = new RemoveKey(key);
}
if(key.equals("nodeRef"))
{
change = new ChangeKey(key, "objectId");
}
if(key.equals("parentNodeRef"))
{
change = new ChangeKey(key, "parentObjectId");
}
// remove null or empty properties
if(value == null || value.equals(""))
{
change = new RemoveKey(key);
}
return change;
}
public static class ChangePageValue implements Change
{
private String key;
private static final String regex = Pattern.quote("document-details?nodeRef=") + "(.*)";
private static final Pattern pattern = Pattern.compile(regex);
public ChangePageValue(String key) {
super();
this.key = key;
}
/*
* Extract and output the node id from input that looks like this: document-details?nodeRef=workspace%3A%2F%2FSpacesStore%2Fd4c1a75e-a17e-4033-94f4-988cca39a357 (non-Javadoc)
*
* @see org.alfresco.rest.api.impl.activities.ActivitySummaryProcessor.Change#process(java.util.Map)
*/
public void process(Map<String, Object> entries)
{
String value = (String)entries.remove(key);
try
{
value = URLDecoder.decode(value, "UTF-8");
Matcher matcher = pattern.matcher(value);
if(matcher.matches())
{
String nodeRefStr = matcher.group(1);
boolean isNodeRef = NodeRef.isNodeRef(nodeRefStr);
if(isNodeRef)
{
NodeRef nodeRef = new NodeRef(nodeRefStr);
entries.put("objectId", nodeRef.getId());
}
else
{
logger.warn("Activity page url contains an invalid NodeRef " + value);
}
}
else
{
logger.warn("Failed to match activity page url for objectId extraction " + value);
}
}
catch (UnsupportedEncodingException e)
{
logger.warn("Unable to decode activity page url " + value);
}
}
}
}

View File

@@ -1,7 +1,7 @@
package org.alfresco.rest.api.impl.activities;
public class CommentsActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
}
package org.alfresco.rest.api.impl.activities;
public class CommentsActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
}

View File

@@ -1,17 +1,17 @@
package org.alfresco.rest.api.impl.activities;
public class DiscussionsActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
@Override
protected Change processEntry(String key, Object value)
{
Change change = null;
if(key.equals("params"))
{
change = new RemoveKey(key);
}
return change;
}
}
package org.alfresco.rest.api.impl.activities;
public class DiscussionsActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
@Override
protected Change processEntry(String key, Object value)
{
Change change = null;
if(key.equals("params"))
{
change = new RemoveKey(key);
}
return change;
}
}

View File

@@ -1,6 +1,6 @@
package org.alfresco.rest.api.impl.activities;
public class DocumentLibraryActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
}
package org.alfresco.rest.api.impl.activities;
public class DocumentLibraryActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
}

View File

@@ -1,18 +1,18 @@
package org.alfresco.rest.api.impl.activities;
public class SiteActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
@Override
protected Change processEntry(String key, Object value)
{
Change change = super.processEntry(key, value);
if(key.equals("memberUserName"))
{
change = new ChangeKey(key, "memberPersonId");
}
return change;
}
}
package org.alfresco.rest.api.impl.activities;
public class SiteActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
@Override
protected Change processEntry(String key, Object value)
{
Change change = super.processEntry(key, value);
if(key.equals("memberUserName"))
{
change = new ChangeKey(key, "memberPersonId");
}
return change;
}
}

View File

@@ -1,26 +1,26 @@
package org.alfresco.rest.api.impl.activities;
public class SubscriptionsActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
//{"lastName":"Glover","userFirstName":"David","followerLastName":"Glover","userUserName":"david.bowie@alfresco.com","followerFirstName":"Steve",
// "userLastName":"Bowie","followerUserName":"steven.glover@alfresco.com","firstName":"Steve","tenantDomain":"alfresco.com"}
@Override
protected Change processEntry(String key, Object value)
{
Change change = super.processEntry(key, value);
if(key.equals("userUserName"))
{
change = new ChangeKey(key, "userPersonId");
}
if(key.equals("followerUserName"))
{
change = new ChangeKey(key, "followerPersonId");
}
return change;
}
}
package org.alfresco.rest.api.impl.activities;
public class SubscriptionsActivitySummaryProcessor extends BaseActivitySummaryProcessor
{
//{"lastName":"Glover","userFirstName":"David","followerLastName":"Glover","userUserName":"david.bowie@alfresco.com","followerFirstName":"Steve",
// "userLastName":"Bowie","followerUserName":"steven.glover@alfresco.com","firstName":"Steve","tenantDomain":"alfresco.com"}
@Override
protected Change processEntry(String key, Object value)
{
Change change = super.processEntry(key, value);
if(key.equals("userUserName"))
{
change = new ChangeKey(key, "userPersonId");
}
if(key.equals("followerUserName"))
{
change = new ChangeKey(key, "followerPersonId");
}
return change;
}
}

View File

@@ -1,210 +1,210 @@
package org.alfresco.rest.api.impl.node.ratings;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.rest.api.model.DocumentRatingSummary;
import org.alfresco.rest.api.model.NodeRating;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.rating.Rating;
import org.alfresco.service.cmr.rating.RatingService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.util.registry.NamedObjectRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.InitializingBean;
/**
* Manages the mapping between the rest api's representation of a node rating and the repository's
* representation of a node rating.
*
* @author steveglover
*
*/
public abstract class AbstractRatingScheme implements RatingScheme, InitializingBean
{
private static Log logger = LogFactory.getLog(RatingScheme.class);
protected String ratingSchemeName; // for interaction with the RatingService
protected String ratingSchemeId; // exposed through the api
protected RatingService ratingService;
protected NodeService nodeService;
protected DictionaryService dictionaryService;
protected ActivityService activityService;
protected SiteService siteService;
protected NamedObjectRegistry<RatingScheme> nodeRatingSchemeRegistry;
public AbstractRatingScheme(String ratingSchemeId, String ratingSchemeName)
{
super();
this.ratingSchemeName = ratingSchemeName;
this.ratingSchemeId = ratingSchemeId;
}
public String getRatingSchemeId()
{
return ratingSchemeId;
}
public String getRatingServiceName()
{
return ratingSchemeName;
}
public void setNodeRatingSchemeRegistry(NamedObjectRegistry<RatingScheme> nodeRatingSchemeRegistry)
{
this.nodeRatingSchemeRegistry = nodeRatingSchemeRegistry;
}
public void setActivityService(ActivityService activityService)
{
this.activityService = activityService;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setRatingService(RatingService ratingService)
{
this.ratingService = ratingService;
}
protected org.alfresco.service.cmr.rating.RatingScheme getRepoRatingScheme()
{
return ratingService.getRatingScheme(ratingSchemeName);
}
protected abstract DocumentRatingSummary getDocumentRatingSummary(NodeRef nodeRef);
protected abstract Object getApiRating(Float rating);
@Override
public void afterPropertiesSet() throws Exception
{
nodeRatingSchemeRegistry.register(ratingSchemeId, this);
nodeRatingSchemeRegistry.register(ratingSchemeName, this);
}
public void validateRating(Float rating)
{
org.alfresco.service.cmr.rating.RatingScheme ratingScheme = getRepoRatingScheme();
Float minRating = ratingScheme.getMinRating();
Float maxRating = ratingScheme.getMaxRating();
if(rating < minRating || rating > maxRating)
{
throw new InvalidArgumentException("Rating is out of bounds.");
}
}
public NodeRating getNodeRating(NodeRef nodeRef)
{
Rating ratingByCurrentUser = ratingService.getRatingByCurrentUser(nodeRef, ratingSchemeName);
Float rating = null;
Date appliedAt = null;
if(ratingByCurrentUser != null)
{
rating = ratingByCurrentUser.getScore();
appliedAt = ratingByCurrentUser.getAppliedAt();
}
Object myRating = null;
if(rating != null)
{
validateRating(rating);
myRating = getApiRating(rating);
}
DocumentRatingSummary documentRatingSummary = getDocumentRatingSummary(nodeRef);
NodeRating nodeRating = new NodeRating(ratingSchemeId, myRating, appliedAt, documentRatingSummary);
return nodeRating;
}
private String getSiteId(final NodeRef nodeRef)
{
// may not be able to read site data so run as system
String siteId = AuthenticationUtil.runAsSystem(new RunAsWork<String>()
{
@Override
public String doWork() throws Exception
{
String siteId = null;
SiteInfo siteInfo = siteService.getSite(nodeRef);
if(siteInfo != null)
{
siteId = siteInfo.getShortName();
}
return siteId;
}
});
return siteId;
}
@SuppressWarnings("unchecked")
private JSONObject getActivityData(final NodeRef nodeRef, String siteId)
{
JSONObject activityData = null;
if(siteId != null)
{
// may not be able to read these nodes, but we need to for the activity processing so run as system
activityData = AuthenticationUtil.runAsSystem(new RunAsWork<JSONObject>()
{
@Override
public JSONObject doWork() throws Exception
{
JSONObject activityData = new JSONObject();
activityData.put("title", nodeService.getProperty(nodeRef, ContentModel.PROP_NAME));
try
{
StringBuilder sb = new StringBuilder("document-details?nodeRef=");
sb.append(URLEncoder.encode(nodeRef.toString(), "UTF-8"));
activityData.put("page", sb.toString());
}
catch (UnsupportedEncodingException e)
{
logger.warn("Unable to urlencode page for create nodeRating activity");
}
return activityData;
}
});
}
return activityData;
}
protected void postActivity(final NodeRef nodeRef, final String activityType)
{
String siteId = getSiteId(nodeRef);
JSONObject activityData = getActivityData(nodeRef, siteId);
if(activityData != null)
{
activityService.postActivity(activityType, siteId, "nodeRatings", activityData.toString());
}
}
}
package org.alfresco.rest.api.impl.node.ratings;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.rest.api.model.DocumentRatingSummary;
import org.alfresco.rest.api.model.NodeRating;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.rating.Rating;
import org.alfresco.service.cmr.rating.RatingService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.util.registry.NamedObjectRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.InitializingBean;
/**
* Manages the mapping between the rest api's representation of a node rating and the repository's
* representation of a node rating.
*
* @author steveglover
*
*/
public abstract class AbstractRatingScheme implements RatingScheme, InitializingBean
{
private static Log logger = LogFactory.getLog(RatingScheme.class);
protected String ratingSchemeName; // for interaction with the RatingService
protected String ratingSchemeId; // exposed through the api
protected RatingService ratingService;
protected NodeService nodeService;
protected DictionaryService dictionaryService;
protected ActivityService activityService;
protected SiteService siteService;
protected NamedObjectRegistry<RatingScheme> nodeRatingSchemeRegistry;
public AbstractRatingScheme(String ratingSchemeId, String ratingSchemeName)
{
super();
this.ratingSchemeName = ratingSchemeName;
this.ratingSchemeId = ratingSchemeId;
}
public String getRatingSchemeId()
{
return ratingSchemeId;
}
public String getRatingServiceName()
{
return ratingSchemeName;
}
public void setNodeRatingSchemeRegistry(NamedObjectRegistry<RatingScheme> nodeRatingSchemeRegistry)
{
this.nodeRatingSchemeRegistry = nodeRatingSchemeRegistry;
}
public void setActivityService(ActivityService activityService)
{
this.activityService = activityService;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setRatingService(RatingService ratingService)
{
this.ratingService = ratingService;
}
protected org.alfresco.service.cmr.rating.RatingScheme getRepoRatingScheme()
{
return ratingService.getRatingScheme(ratingSchemeName);
}
protected abstract DocumentRatingSummary getDocumentRatingSummary(NodeRef nodeRef);
protected abstract Object getApiRating(Float rating);
@Override
public void afterPropertiesSet() throws Exception
{
nodeRatingSchemeRegistry.register(ratingSchemeId, this);
nodeRatingSchemeRegistry.register(ratingSchemeName, this);
}
public void validateRating(Float rating)
{
org.alfresco.service.cmr.rating.RatingScheme ratingScheme = getRepoRatingScheme();
Float minRating = ratingScheme.getMinRating();
Float maxRating = ratingScheme.getMaxRating();
if(rating < minRating || rating > maxRating)
{
throw new InvalidArgumentException("Rating is out of bounds.");
}
}
public NodeRating getNodeRating(NodeRef nodeRef)
{
Rating ratingByCurrentUser = ratingService.getRatingByCurrentUser(nodeRef, ratingSchemeName);
Float rating = null;
Date appliedAt = null;
if(ratingByCurrentUser != null)
{
rating = ratingByCurrentUser.getScore();
appliedAt = ratingByCurrentUser.getAppliedAt();
}
Object myRating = null;
if(rating != null)
{
validateRating(rating);
myRating = getApiRating(rating);
}
DocumentRatingSummary documentRatingSummary = getDocumentRatingSummary(nodeRef);
NodeRating nodeRating = new NodeRating(ratingSchemeId, myRating, appliedAt, documentRatingSummary);
return nodeRating;
}
private String getSiteId(final NodeRef nodeRef)
{
// may not be able to read site data so run as system
String siteId = AuthenticationUtil.runAsSystem(new RunAsWork<String>()
{
@Override
public String doWork() throws Exception
{
String siteId = null;
SiteInfo siteInfo = siteService.getSite(nodeRef);
if(siteInfo != null)
{
siteId = siteInfo.getShortName();
}
return siteId;
}
});
return siteId;
}
@SuppressWarnings("unchecked")
private JSONObject getActivityData(final NodeRef nodeRef, String siteId)
{
JSONObject activityData = null;
if(siteId != null)
{
// may not be able to read these nodes, but we need to for the activity processing so run as system
activityData = AuthenticationUtil.runAsSystem(new RunAsWork<JSONObject>()
{
@Override
public JSONObject doWork() throws Exception
{
JSONObject activityData = new JSONObject();
activityData.put("title", nodeService.getProperty(nodeRef, ContentModel.PROP_NAME));
try
{
StringBuilder sb = new StringBuilder("document-details?nodeRef=");
sb.append(URLEncoder.encode(nodeRef.toString(), "UTF-8"));
activityData.put("page", sb.toString());
}
catch (UnsupportedEncodingException e)
{
logger.warn("Unable to urlencode page for create nodeRating activity");
}
return activityData;
}
});
}
return activityData;
}
protected void postActivity(final NodeRef nodeRef, final String activityType)
{
String siteId = getSiteId(nodeRef);
JSONObject activityData = getActivityData(nodeRef, siteId);
if(activityData != null)
{
activityService.postActivity(activityType, siteId, "nodeRatings", activityData.toString());
}
}
}

View File

@@ -1,79 +1,79 @@
package org.alfresco.rest.api.impl.node.ratings;
import org.alfresco.rest.api.model.DocumentRatingSummary;
import org.alfresco.rest.api.model.FiveStarRatingSummary;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.cmr.rating.RatingServiceException;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* The rest apis representation of the 'fiveStar' rating scheme.
*
* @author steveglover
*
*/
public class FiveStarRatingScheme extends AbstractRatingScheme
{
public FiveStarRatingScheme()
{
super("fiveStar", "fiveStarRatingScheme");
}
public Float getRatingServiceRating(Object rating)
{
Float ratingToApply = null;
if(rating instanceof Integer)
{
ratingToApply = ((Integer)rating).floatValue();
}
else
{
throw new InvalidArgumentException("Rating should be non-null and an integer for 'fiveStar' rating scheme.");
}
validateRating(ratingToApply);
return ratingToApply;
}
public Object getApiRating(Float rating)
{
Object apiRating = Integer.valueOf(rating.intValue());
return apiRating;
}
public DocumentRatingSummary getDocumentRatingSummary(NodeRef nodeRef)
{
return new FiveStarRatingSummary(ratingService.getRatingsCount(nodeRef, ratingSchemeName),
ratingService.getTotalRating(nodeRef, ratingSchemeName),
ratingService.getAverageRating(nodeRef, ratingSchemeName));
}
@Override
public void applyRating(NodeRef nodeRef, Object rating)
{
try
{
Float ratingServiceRating = getRatingServiceRating(rating);
ratingService.applyRating(nodeRef, ratingServiceRating, getRatingServiceName());
}
catch(RatingServiceException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
@Override
public void removeRating(NodeRef nodeRef)
{
try
{
ratingService.removeRatingByCurrentUser(nodeRef, getRatingServiceName());
}
catch(RatingServiceException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
}
package org.alfresco.rest.api.impl.node.ratings;
import org.alfresco.rest.api.model.DocumentRatingSummary;
import org.alfresco.rest.api.model.FiveStarRatingSummary;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.cmr.rating.RatingServiceException;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* The rest apis representation of the 'fiveStar' rating scheme.
*
* @author steveglover
*
*/
public class FiveStarRatingScheme extends AbstractRatingScheme
{
public FiveStarRatingScheme()
{
super("fiveStar", "fiveStarRatingScheme");
}
public Float getRatingServiceRating(Object rating)
{
Float ratingToApply = null;
if(rating instanceof Integer)
{
ratingToApply = ((Integer)rating).floatValue();
}
else
{
throw new InvalidArgumentException("Rating should be non-null and an integer for 'fiveStar' rating scheme.");
}
validateRating(ratingToApply);
return ratingToApply;
}
public Object getApiRating(Float rating)
{
Object apiRating = Integer.valueOf(rating.intValue());
return apiRating;
}
public DocumentRatingSummary getDocumentRatingSummary(NodeRef nodeRef)
{
return new FiveStarRatingSummary(ratingService.getRatingsCount(nodeRef, ratingSchemeName),
ratingService.getTotalRating(nodeRef, ratingSchemeName),
ratingService.getAverageRating(nodeRef, ratingSchemeName));
}
@Override
public void applyRating(NodeRef nodeRef, Object rating)
{
try
{
Float ratingServiceRating = getRatingServiceRating(rating);
ratingService.applyRating(nodeRef, ratingServiceRating, getRatingServiceName());
}
catch(RatingServiceException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
@Override
public void removeRating(NodeRef nodeRef)
{
try
{
ratingService.removeRatingByCurrentUser(nodeRef, getRatingServiceName());
}
catch(RatingServiceException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
}

View File

@@ -1,100 +1,100 @@
package org.alfresco.rest.api.impl.node.ratings;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.activities.ActivityType;
import org.alfresco.rest.api.model.DocumentRatingSummary;
import org.alfresco.rest.api.model.LikesRatingSummary;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.cmr.rating.RatingServiceException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* The rest api representation of the 'likes' rating scheme.
*
* @author steveglover
*
*/
public class LikesRatingScheme extends AbstractRatingScheme
{
public LikesRatingScheme()
{
super("likes", "likesRatingScheme");
}
public Float getRatingServiceRating(Object rating)
{
Float ratingToApply = null;
if(rating instanceof Boolean)
{
boolean liked = ((Boolean)rating).booleanValue();
ratingToApply = Float.valueOf((liked ? 1.0f : 0.0f));
}
else
{
throw new InvalidArgumentException("Rating should be non-null and a boolean for 'likes' rating scheme.");
}
return ratingToApply;
}
@Override
public void applyRating(NodeRef nodeRef, Object rating)
{
try
{
Float ratingServiceRating = getRatingServiceRating(rating);
ratingService.applyRating(nodeRef, ratingServiceRating, getRatingServiceName());
QName nodeType = nodeService.getType(nodeRef);
boolean isContainer = dictionaryService.isSubClass(nodeType, ContentModel.TYPE_FOLDER) &&
!dictionaryService.isSubClass(nodeType, ContentModel.TYPE_SYSTEM_FOLDER);
postActivity(nodeRef, isContainer ? ActivityType.FOLDER_LIKED : ActivityType.FILE_LIKED);
}
catch(RatingServiceException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
@Override
public void removeRating(NodeRef nodeRef)
{
try
{
ratingService.removeRatingByCurrentUser(nodeRef, getRatingServiceName());
}
catch(RatingServiceException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
@Override
protected Object getApiRating(Float rating)
{
Object apiRating = null;
if(rating == 1.0f)
{
apiRating = true;
}
else if(rating == 0.0f)
{
apiRating = false;
}
else
{
throw new InvalidArgumentException("Rating is invalid.");
}
return apiRating;
}
@Override
protected DocumentRatingSummary getDocumentRatingSummary(NodeRef nodeRef)
{
return new LikesRatingSummary(ratingService.getRatingsCount(nodeRef, ratingSchemeName));
}
}
package org.alfresco.rest.api.impl.node.ratings;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.activities.ActivityType;
import org.alfresco.rest.api.model.DocumentRatingSummary;
import org.alfresco.rest.api.model.LikesRatingSummary;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.cmr.rating.RatingServiceException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* The rest api representation of the 'likes' rating scheme.
*
* @author steveglover
*
*/
public class LikesRatingScheme extends AbstractRatingScheme
{
public LikesRatingScheme()
{
super("likes", "likesRatingScheme");
}
public Float getRatingServiceRating(Object rating)
{
Float ratingToApply = null;
if(rating instanceof Boolean)
{
boolean liked = ((Boolean)rating).booleanValue();
ratingToApply = Float.valueOf((liked ? 1.0f : 0.0f));
}
else
{
throw new InvalidArgumentException("Rating should be non-null and a boolean for 'likes' rating scheme.");
}
return ratingToApply;
}
@Override
public void applyRating(NodeRef nodeRef, Object rating)
{
try
{
Float ratingServiceRating = getRatingServiceRating(rating);
ratingService.applyRating(nodeRef, ratingServiceRating, getRatingServiceName());
QName nodeType = nodeService.getType(nodeRef);
boolean isContainer = dictionaryService.isSubClass(nodeType, ContentModel.TYPE_FOLDER) &&
!dictionaryService.isSubClass(nodeType, ContentModel.TYPE_SYSTEM_FOLDER);
postActivity(nodeRef, isContainer ? ActivityType.FOLDER_LIKED : ActivityType.FILE_LIKED);
}
catch(RatingServiceException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
@Override
public void removeRating(NodeRef nodeRef)
{
try
{
ratingService.removeRatingByCurrentUser(nodeRef, getRatingServiceName());
}
catch(RatingServiceException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
@Override
protected Object getApiRating(Float rating)
{
Object apiRating = null;
if(rating == 1.0f)
{
apiRating = true;
}
else if(rating == 0.0f)
{
apiRating = false;
}
else
{
throw new InvalidArgumentException("Rating is invalid.");
}
return apiRating;
}
@Override
protected DocumentRatingSummary getDocumentRatingSummary(NodeRef nodeRef)
{
return new LikesRatingSummary(ratingService.getRatingsCount(nodeRef, ratingSchemeName));
}
}

View File

@@ -1,11 +1,11 @@
package org.alfresco.rest.api.impl.node.ratings;
import org.alfresco.rest.api.model.NodeRating;
import org.alfresco.service.cmr.repository.NodeRef;
public interface RatingScheme
{
public void applyRating(NodeRef nodeRef, Object rating);
public void removeRating(NodeRef nodeRef);
public NodeRating getNodeRating(NodeRef nodeRef);
}
package org.alfresco.rest.api.impl.node.ratings;
import org.alfresco.rest.api.model.NodeRating;
import org.alfresco.service.cmr.repository.NodeRef;
public interface RatingScheme
{
public void applyRating(NodeRef nodeRef, Object rating);
public void removeRating(NodeRef nodeRef);
public NodeRating getNodeRating(NodeRef nodeRef);
}