mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)
121907 gjames: RA-774 Renaming action to operation git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@126435 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -21,7 +21,7 @@ package org.alfresco.rest.api.nodes;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.model.Node;
|
||||
import org.alfresco.rest.api.model.NodeTarget;
|
||||
import org.alfresco.rest.framework.Action;
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.alfresco.rest.framework.BinaryProperties;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.WebApiParam;
|
||||
@@ -123,14 +123,14 @@ public class NodesEntityResource implements
|
||||
nodes.deleteNode(nodeId);
|
||||
}
|
||||
|
||||
@Action("copy")
|
||||
@Operation("copy")
|
||||
@WebApiDescription(title = "Copy Node", description="Copy one or more nodes (files or folders) to a new target folder, with option to rename.")
|
||||
public Node copyById(String nodeId, NodeTarget target, Parameters parameters)
|
||||
{
|
||||
return nodes.copyNode(nodeId, target.getTargetParentId(), target.getName(), parameters);
|
||||
}
|
||||
|
||||
@Action("move")
|
||||
@Operation("move")
|
||||
@WebApiDescription(title = "Move Node", description="Moves one or more nodes (files or folders) to a new target folder, with option to rename.")
|
||||
public Node moveById(String nodeId, NodeTarget target, Parameters parameters)
|
||||
{
|
||||
|
@@ -6,13 +6,13 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* An action as on an entity in the Rest API
|
||||
* An Operation as on an entity in the Rest API
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Action
|
||||
public @interface Operation
|
||||
{
|
||||
String value();
|
||||
}
|
@@ -22,34 +22,33 @@ import org.alfresco.rest.framework.Api;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.ResourceAction;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Extends ResourceMetaData to give more information about an Action
|
||||
* Extends ResourceMetaData to give more information about an Operation
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class ActionResourceMetaData extends ResourceMetadata
|
||||
public class OperationResourceMetaData extends ResourceMetadata
|
||||
{
|
||||
private final Method actionMethod;
|
||||
private final Method operationMethod;
|
||||
|
||||
/**
|
||||
* Use this constructor to create the resource metadata
|
||||
* @param uniqueId
|
||||
* @param operations
|
||||
* @param api
|
||||
* @param actionMethod
|
||||
* @param operationMethod
|
||||
*/
|
||||
public ActionResourceMetaData(String uniqueId, List<ResourceOperation> operations, Api api, Method actionMethod)
|
||||
public OperationResourceMetaData(String uniqueId, List<ResourceOperation> operations, Api api, Method operationMethod)
|
||||
{
|
||||
super(uniqueId, RESOURCE_TYPE.ACTION, operations, api, null, null, null);
|
||||
super(uniqueId, RESOURCE_TYPE.OPERATION, operations, api, null, null, null);
|
||||
if (operations.size()!= 1)
|
||||
{
|
||||
throw new IllegalArgumentException("Only 1 action per url is supported for an entity");
|
||||
throw new IllegalArgumentException("Only 1 operation per url is supported for an entity");
|
||||
}
|
||||
this.actionMethod = actionMethod;
|
||||
this.operationMethod = operationMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,22 +57,22 @@ public class ActionResourceMetaData extends ResourceMetadata
|
||||
* @param api
|
||||
* @param apiDeleted
|
||||
*/
|
||||
public ActionResourceMetaData(String uniqueId, Api api, Set<Class<? extends ResourceAction>> apiDeleted)
|
||||
public OperationResourceMetaData(String uniqueId, Api api, Set<Class<? extends ResourceAction>> apiDeleted)
|
||||
{
|
||||
super(uniqueId, RESOURCE_TYPE.ACTION, null, api, apiDeleted, null, null);
|
||||
this.actionMethod = null;
|
||||
super(uniqueId, RESOURCE_TYPE.OPERATION, null, api, apiDeleted, null, null);
|
||||
this.operationMethod = null;
|
||||
}
|
||||
|
||||
public Method getActionMethod()
|
||||
public Method getOperationMethod()
|
||||
{
|
||||
return actionMethod;
|
||||
return operationMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("ActionResourceMetaData [api=");
|
||||
builder.append("OperationResourceMetaData [api=");
|
||||
builder.append(this.getApi());
|
||||
builder.append(", uniqueId=");
|
||||
builder.append(this.getUniqueId());
|
||||
@@ -85,7 +84,7 @@ public class ActionResourceMetaData extends ResourceMetadata
|
||||
builder.append(this.getOperations());
|
||||
builder.append(", apiDeleted=");
|
||||
builder.append(this.getApiDeleted());
|
||||
builder.append("actionMethod=").append(actionMethod);
|
||||
builder.append("operationMethod=").append(operationMethod);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
@@ -29,7 +29,7 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.rest.framework.Action;
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.alfresco.rest.framework.Api;
|
||||
import org.alfresco.rest.framework.BinaryProperties;
|
||||
import org.alfresco.rest.framework.WebApi;
|
||||
@@ -134,7 +134,7 @@ public class ResourceInspector
|
||||
}
|
||||
|
||||
inspectAddressedProperties(api, resource, urlPath, metainfo);
|
||||
inspectActions(api, resource, urlPath, metainfo);
|
||||
inspectOperations(api, resource, urlPath, metainfo);
|
||||
return metainfo;
|
||||
}
|
||||
|
||||
@@ -535,46 +535,46 @@ public class ResourceInspector
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspect a resource to find actions on it.
|
||||
* Inspect a resource to find operations on it.
|
||||
* @param api Api
|
||||
* @param resource Class<?>
|
||||
* @param entityPath String
|
||||
* @param metainfo List<ResourceMetadata>
|
||||
*/
|
||||
public static void inspectActions(Api api, Class<?> resource, final String entityPath, List<ResourceMetadata> metainfo)
|
||||
public static void inspectOperations(Api api, Class<?> resource, final String entityPath, List<ResourceMetadata> metainfo)
|
||||
{
|
||||
Map<String,Pair<ResourceOperation,Method>> operations = findActions(entityPath, resource);
|
||||
Map<String,Pair<ResourceOperation,Method>> operations = findOperations(entityPath, resource);
|
||||
if (operations != null && !operations.isEmpty())
|
||||
{
|
||||
for (Entry<String, Pair<ResourceOperation, Method>> opera : operations.entrySet())
|
||||
{
|
||||
if (isDeleted(opera.getValue().getSecond()))
|
||||
{
|
||||
metainfo.add(new ActionResourceMetaData(opera.getKey(), api, new HashSet(Arrays.asList(opera.getValue().getFirst()))));
|
||||
metainfo.add(new OperationResourceMetaData(opera.getKey(), api, new HashSet(Arrays.asList(opera.getValue().getFirst()))));
|
||||
}
|
||||
else
|
||||
{
|
||||
metainfo.add(new ActionResourceMetaData(opera.getKey(), Arrays.asList(opera.getValue().getFirst()), api, opera.getValue().getSecond()));
|
||||
metainfo.add(new OperationResourceMetaData(opera.getKey(), Arrays.asList(opera.getValue().getFirst()), api, opera.getValue().getSecond()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds actions on an entity
|
||||
* Finds operations on an entity
|
||||
* @param entityPath path to the entity
|
||||
* @param anyClass resource clause
|
||||
* @return The operations
|
||||
*/
|
||||
private static Map<String,Pair<ResourceOperation,Method>> findActions(String entityPath, Class<?> anyClass)
|
||||
private static Map<String,Pair<ResourceOperation,Method>> findOperations(String entityPath, Class<?> anyClass)
|
||||
{
|
||||
Map<String, Pair<ResourceOperation,Method>> embeds = new HashMap<String, Pair<ResourceOperation,Method>>();
|
||||
List<Method> annotatedMethods = ResourceInspectorUtil.findMethodsByAnnotation(anyClass, Action.class);
|
||||
List<Method> annotatedMethods = ResourceInspectorUtil.findMethodsByAnnotation(anyClass, Operation.class);
|
||||
if (annotatedMethods != null && !annotatedMethods.isEmpty())
|
||||
{
|
||||
for (Method annotatedMethod : annotatedMethods)
|
||||
{
|
||||
Annotation annot = AnnotationUtils.findAnnotation(annotatedMethod, Action.class);
|
||||
Annotation annot = AnnotationUtils.findAnnotation(annotatedMethod, Operation.class);
|
||||
if (annot != null)
|
||||
{
|
||||
Map<String, Object> annotAttribs = AnnotationUtils.getAnnotationAttributes(annot);
|
||||
|
@@ -6,8 +6,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.framework.Action;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
@@ -36,13 +35,14 @@ public class ResourceInspectorUtil
|
||||
|
||||
/*
|
||||
* The api is consistent that the object passed in must match the object passed out
|
||||
* however, actions are different, they don't even need a param, and if its supplied
|
||||
* then it doesn't have to match. So we need special logic for actions
|
||||
* however, operations are different, if the param is supplied it doesn't have to match
|
||||
* the return type.
|
||||
* So we need special logic for operations
|
||||
*/
|
||||
Annotation annot = AnnotationUtils.findAnnotation(resolvedMethod, Action.class);
|
||||
Annotation annot = AnnotationUtils.findAnnotation(resolvedMethod, Operation.class);
|
||||
if (annot != null)
|
||||
{
|
||||
return determinActionType(resource, method);
|
||||
return determineOperationType(resource, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -55,16 +55,16 @@ public class ResourceInspectorUtil
|
||||
}
|
||||
}
|
||||
|
||||
protected static Class determinActionType(Class resource, Method method)
|
||||
protected static Class determineOperationType(Class resource, Method method)
|
||||
{
|
||||
//Its an Action annotated method and its a bit special
|
||||
//Its an operation annotated method and its a bit special
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
if (paramTypes!= null)
|
||||
{
|
||||
switch (paramTypes.length)
|
||||
{
|
||||
case 3:
|
||||
//EntityResource action by id, same logic as RelationshipEntityResource action by id
|
||||
//EntityResource operation by id, same logic as RelationshipEntityResource operation by id
|
||||
case 4:
|
||||
int position = paramTypes.length-2;
|
||||
if (Void.class.equals(paramTypes[position]))
|
||||
@@ -78,7 +78,7 @@ public class ResourceInspectorUtil
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("An action method signature should have 3 parameters (uniqueId, typePassedin, Parameters)," +
|
||||
throw new IllegalArgumentException("An operation method signature should have 3 parameters (uniqueId, typePassedin, Parameters)," +
|
||||
" use Void if you are not interested in the second argument.");
|
||||
}
|
||||
|
||||
|
@@ -36,7 +36,7 @@ import org.springframework.http.HttpMethod;
|
||||
*/
|
||||
public class ResourceMetadata
|
||||
{
|
||||
public enum RESOURCE_TYPE {ENTITY, RELATIONSHIP, PROPERTY, ACTION};
|
||||
public enum RESOURCE_TYPE {ENTITY, RELATIONSHIP, PROPERTY, OPERATION};
|
||||
private final String uniqueId;
|
||||
private final RESOURCE_TYPE type;
|
||||
private final List<ResourceOperation> operations;
|
||||
|
@@ -23,7 +23,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.rest.framework.core.ActionResourceMetaData;
|
||||
import org.alfresco.rest.framework.core.OperationResourceMetaData;
|
||||
import org.alfresco.rest.framework.core.ResourceInspector;
|
||||
import org.alfresco.rest.framework.core.ResourceInspectorUtil;
|
||||
import org.alfresco.rest.framework.core.ResourceLocator;
|
||||
@@ -93,15 +93,15 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
Object postedRel = processRequest(resourceMeta, req);
|
||||
return Params.valueOf(entityId, params, postedRel);
|
||||
}
|
||||
case ACTION:
|
||||
final String actionName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_RESOURCE);
|
||||
if (StringUtils.isNotBlank(entityId) && StringUtils.isNotBlank(actionName))
|
||||
case OPERATION:
|
||||
final String operationName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_RESOURCE);
|
||||
if (StringUtils.isNotBlank(entityId) && StringUtils.isNotBlank(operationName))
|
||||
{
|
||||
Class objectType = resourceMeta.getObjectType(HttpMethod.POST);
|
||||
Object postedObj = null;
|
||||
if (objectType!= null)
|
||||
{
|
||||
//Actions don't support a List as json body
|
||||
//Operations don't support a List as json body
|
||||
postedObj = ResourceWebScriptHelper.extractJsonContent(req, jsonHelper, objectType);
|
||||
}
|
||||
return Params.valueOf(entityId, params, postedObj);
|
||||
@@ -170,26 +170,26 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
|
||||
|
||||
/**
|
||||
* Execute a generic action method
|
||||
* Execute a generic operation method
|
||||
* @param resource
|
||||
* @param params
|
||||
* @return the result of the execution.
|
||||
*/
|
||||
private Object executeAction(ResourceWithMetadata resource, Params params) throws Throwable
|
||||
private Object executeOperation(ResourceWithMetadata resource, Params params) throws Throwable
|
||||
{
|
||||
ActionResourceMetaData actionResourceMetaData = (ActionResourceMetaData) resource.getMetaData();
|
||||
OperationResourceMetaData operationResourceMetaData = (OperationResourceMetaData) resource.getMetaData();
|
||||
|
||||
switch (actionResourceMetaData.getActionMethod().getParameterTypes().length)
|
||||
switch (operationResourceMetaData.getOperationMethod().getParameterTypes().length)
|
||||
{
|
||||
case 3:
|
||||
//EntityResource action by id
|
||||
return ResourceInspectorUtil.invokeMethod(actionResourceMetaData.getActionMethod(),resource.getResource(), params.getEntityId(), params.getPassedIn(), params);
|
||||
//EntityResource operation by id
|
||||
return ResourceInspectorUtil.invokeMethod(operationResourceMetaData.getOperationMethod(),resource.getResource(), params.getEntityId(), params.getPassedIn(), params);
|
||||
case 4:
|
||||
//RelationshipEntityResource action by id
|
||||
return ResourceInspectorUtil.invokeMethod(actionResourceMetaData.getActionMethod(),resource.getResource(), params.getEntityId(), params.getRelationshipId(), params.getPassedIn(), params);
|
||||
//RelationshipEntityResource operation by id
|
||||
return ResourceInspectorUtil.invokeMethod(operationResourceMetaData.getOperationMethod(),resource.getResource(), params.getEntityId(), params.getRelationshipId(), params.getPassedIn(), params);
|
||||
}
|
||||
|
||||
throw new UnsupportedResourceOperationException("The action method has an invalid signature");
|
||||
throw new UnsupportedResourceOperationException("The operation method has an invalid signature");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,8 +256,8 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
return wrapWithCollectionWithPaging(createdRel);
|
||||
}
|
||||
}
|
||||
case ACTION:
|
||||
return executeAction(resource, params);
|
||||
case OPERATION:
|
||||
return executeOperation(resource, params);
|
||||
default:
|
||||
throw new UnsupportedResourceOperationException("POST not supported for Actions");
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package org.alfresco.rest.framework.tests.api.mocks;
|
||||
|
||||
import org.alfresco.rest.framework.Action;
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.WebApiParam;
|
||||
import org.alfresco.rest.framework.core.ResourceParameter;
|
||||
@@ -19,12 +19,12 @@ public class GrassEntityResource implements EntityResourceAction.ReadById<Grass>
|
||||
return new Grass(id);
|
||||
}
|
||||
|
||||
@Action("cut")
|
||||
@Operation("cut")
|
||||
public String cutLawn(String id, Void notused, Parameters parameters) {
|
||||
return "All done";
|
||||
}
|
||||
|
||||
@Action("grow")
|
||||
@Operation("grow")
|
||||
@WebApiDescription(title = "Grow the grass")
|
||||
@WebApiParam(name = "Grass", title = "The grass.",required=true, kind = ResourceParameter.KIND.HTTP_BODY_OBJECT)
|
||||
public String growTheLawn(String id, Grass grass, Parameters parameters) {
|
||||
|
@@ -15,10 +15,8 @@ import java.util.Map;
|
||||
|
||||
import org.alfresco.rest.api.model.Comment;
|
||||
import org.alfresco.rest.api.nodes.NodeCommentsRelation;
|
||||
import org.alfresco.rest.framework.Action;
|
||||
import org.alfresco.rest.framework.Api;
|
||||
import org.alfresco.rest.framework.BinaryProperties;
|
||||
import org.alfresco.rest.framework.core.ActionResourceMetaData;
|
||||
import org.alfresco.rest.framework.core.OperationResourceMetaData;
|
||||
import org.alfresco.rest.framework.core.ResourceInspector;
|
||||
import org.alfresco.rest.framework.core.ResourceInspectorUtil;
|
||||
import org.alfresco.rest.framework.core.ResourceMetadata;
|
||||
@@ -391,20 +389,20 @@ public class InspectorTests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInspectActions() throws IllegalAccessException, InstantiationException, Throwable
|
||||
public void testInspectOperations() throws IllegalAccessException, InstantiationException, Throwable
|
||||
{
|
||||
Api api = Api.valueOf("alfrescomock", "private", "1");
|
||||
List<ResourceMetadata> metainfo = new ArrayList<ResourceMetadata>();
|
||||
|
||||
GrassEntityResource grassEntityResource = new GrassEntityResource();
|
||||
ResourceInspector.inspectActions(api, GrassEntityResource.class,"-root-", metainfo);
|
||||
ResourceInspector.inspectOperations(api, GrassEntityResource.class,"-root-", metainfo);
|
||||
assertTrue(metainfo.size()==2);
|
||||
|
||||
for (ResourceMetadata resourceMetadata : metainfo)
|
||||
{
|
||||
assertEquals(ResourceMetadata.RESOURCE_TYPE.ACTION, resourceMetadata.getType());
|
||||
ActionResourceMetaData actionResourceMetaData = (ActionResourceMetaData) resourceMetadata;
|
||||
Method actionMethod = actionResourceMetaData.getActionMethod();
|
||||
assertEquals(ResourceMetadata.RESOURCE_TYPE.OPERATION, resourceMetadata.getType());
|
||||
OperationResourceMetaData operationResourceMetaData = (OperationResourceMetaData) resourceMetadata;
|
||||
Method actionMethod = operationResourceMetaData.getOperationMethod();
|
||||
String result = null;
|
||||
switch (resourceMetadata.getUniqueId())
|
||||
{
|
||||
|
@@ -432,13 +432,13 @@ public class ParamsExtractorTests
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks an action
|
||||
* Mocks an operation
|
||||
* @return ResourceMetadata a Entity
|
||||
*/
|
||||
private static ResourceMetadata mockAction()
|
||||
private static ResourceMetadata mockOperation()
|
||||
{
|
||||
ResourceMetadata resourceMock = mock(ResourceMetadata.class);
|
||||
when(resourceMock.getType()).thenReturn(ResourceMetadata.RESOURCE_TYPE.ACTION);
|
||||
when(resourceMock.getType()).thenReturn(ResourceMetadata.RESOURCE_TYPE.OPERATION);
|
||||
return resourceMock;
|
||||
}
|
||||
|
||||
|
@@ -7,11 +7,9 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@@ -147,7 +145,7 @@ public class ResourceLocatorTests
|
||||
|
||||
collResource = locator.locateResource(api, templateVars, HttpMethod.POST);
|
||||
assertEquals(GrassEntityResource.class, collResource.getResource().getClass());
|
||||
assertEquals(ResourceMetadata.RESOURCE_TYPE.ACTION, collResource.getMetaData().getType());
|
||||
assertEquals(ResourceMetadata.RESOURCE_TYPE.OPERATION, collResource.getMetaData().getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user