From 764af23ef71897911d6f20a93269d7f1a1e9b754 Mon Sep 17 00:00:00 2001 From: Ancuta Morarasu Date: Wed, 11 May 2016 11:18:01 +0000 Subject: [PATCH] Merged HEAD (5.2) to 5.2.N (5.2.1) 126429 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2) 121864 gjames: RA-774 Allow the use of "Void" parameter type git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126775 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../framework/core/ResourceInspectorUtil.java | 50 +++++++++++------- .../webscripts/ResourceWebScriptPost.java | 52 ++++++++++++++++--- .../tests/api/mocks/GrassEntityResource.java | 2 +- .../framework/tests/core/InspectorTests.java | 2 +- 4 files changed, 79 insertions(+), 27 deletions(-) diff --git a/source/java/org/alfresco/rest/framework/core/ResourceInspectorUtil.java b/source/java/org/alfresco/rest/framework/core/ResourceInspectorUtil.java index 8d64a463ac..8f580c4465 100755 --- a/source/java/org/alfresco/rest/framework/core/ResourceInspectorUtil.java +++ b/source/java/org/alfresco/rest/framework/core/ResourceInspectorUtil.java @@ -84,24 +84,27 @@ public class ResourceInspectorUtil { //Its an Action 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 + case 4: + int position = paramTypes.length-2; + if (Void.class.equals(paramTypes[position])) + { + return null; + } + else + { + return paramTypes[position]; + } + } + } - if (!String.class.equals(paramTypes[0]) || !Parameters.class.equals(paramTypes[paramTypes.length-1])) - { - throw new IllegalArgumentException("An action method signature must start with a String uniqueId and end with the 'Parameters' object "); - } - if (paramTypes.length == 2) - { - //No parameter required - return null; - } - else if (paramTypes.length == 3) - { - return paramTypes[1]; // Return the middle parameter - } - else - { - throw new IllegalArgumentException("An action method signature should have 3 parameters (uniqueId, typePassedin, Parameters)"); - } + throw new IllegalArgumentException("An action method signature should have 3 parameters (uniqueId, typePassedin, Parameters)," + + " use Void if you are not interested in the second argument."); } /** @@ -144,7 +147,15 @@ public class ResourceInspectorUtil */ public static Object invokeMethod(Method annotatedMethod, Object obj) { - return invokeMethod(annotatedMethod, obj, null); + try + { + return invokeMethod(annotatedMethod, obj, null); + } + catch (Throwable error) + { + logger.error("Invocation failure", error); + return null; + } } /** @@ -153,7 +164,7 @@ public class ResourceInspectorUtil * @param obj Object * @return result of method call */ - public static Object invokeMethod(Method annotatedMethod, Object obj, Object... args) + public static Object invokeMethod(Method annotatedMethod, Object obj, Object... args) throws Throwable { if (annotatedMethod != null) { @@ -172,6 +183,7 @@ public class ResourceInspectorUtil catch (InvocationTargetException error) { logger.warn("InvocationTargetException", error); + throw error.getCause(); } } return null; diff --git a/source/java/org/alfresco/rest/framework/webscripts/ResourceWebScriptPost.java b/source/java/org/alfresco/rest/framework/webscripts/ResourceWebScriptPost.java index d78406df43..346daf5be6 100644 --- a/source/java/org/alfresco/rest/framework/webscripts/ResourceWebScriptPost.java +++ b/source/java/org/alfresco/rest/framework/webscripts/ResourceWebScriptPost.java @@ -29,7 +29,9 @@ 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.ResourceInspector; +import org.alfresco.rest.framework.core.ResourceInspectorUtil; import org.alfresco.rest.framework.core.ResourceLocator; import org.alfresco.rest.framework.core.ResourceMetadata; import org.alfresco.rest.framework.core.ResourceParameter; @@ -67,18 +69,17 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements setParamsExtractor(this); } - @Override public Params extractParams(ResourceMetadata resourceMeta, WebScriptRequest req) { final RecognizedParams params = ResourceWebScriptHelper.getRecognizedParams(req); - + final String entityId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.ENTITY_ID); + switch (resourceMeta.getType()) { case ENTITY: - String entityIdCheck = req.getServiceMatch().getTemplateVars().get(ResourceLocator.ENTITY_ID); - if (StringUtils.isNotBlank(entityIdCheck)) + if (StringUtils.isNotBlank(entityId)) { throw new UnsupportedResourceOperationException("POST is executed against the collection URL"); } @@ -88,7 +89,6 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements return Params.valueOf(null, params, postedObj); } case RELATIONSHIP: - String entityId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.ENTITY_ID); String relationshipId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_ID); if (StringUtils.isNotBlank(relationshipId)) { @@ -99,6 +99,20 @@ 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)) + { + Class objectType = resourceMeta.getObjectType(HttpMethod.POST); + Object postedObj = null; + if (objectType!= null) + { + //Actions don't support a List as json body + postedObj = ResourceWebScriptHelper.extractJsonContent(req, jsonHelper, objectType); + } + return Params.valueOf(entityId, params, postedObj); + } + //Fall through to unsupported. default: throw new UnsupportedResourceOperationException("POST not supported for Actions"); } @@ -160,6 +174,30 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements return ResourceWebScriptHelper.extractJsonContentAsList(req, jsonHelper, objType); } + + /** + * Execute a generic action method + * @param resource + * @param params + * @return the result of the execution. + */ + private Object executeAction(ResourceWithMetadata resource, Params params) throws Throwable + { + ActionResourceMetaData actionResourceMetaData = (ActionResourceMetaData) resource.getMetaData(); + + switch (actionResourceMetaData.getActionMethod().getParameterTypes().length) + { + case 3: + //EntityResource action by id + return ResourceInspectorUtil.invokeMethod(actionResourceMetaData.getActionMethod(),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); + } + + throw new UnsupportedResourceOperationException("The action method has an invalid signature"); + } + /** * Executes the action on the resource * @param resource ResourceWithMetadata @@ -167,7 +205,7 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements * @return anObject the result of the execute */ @SuppressWarnings("unchecked") - private Object executeInternal(ResourceWithMetadata resource, Params params) + private Object executeInternal(ResourceWithMetadata resource, Params params) throws Throwable { final Object resObj = resource.getResource(); switch (resource.getMetaData().getType()) @@ -224,6 +262,8 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements return wrapWithCollectionWithPaging(createdRel); } } + case ACTION: + return executeAction(resource, params); default: throw new UnsupportedResourceOperationException("POST not supported for Actions"); } diff --git a/source/test-java/org/alfresco/rest/framework/tests/api/mocks/GrassEntityResource.java b/source/test-java/org/alfresco/rest/framework/tests/api/mocks/GrassEntityResource.java index b69e52e048..cf032b1ea0 100644 --- a/source/test-java/org/alfresco/rest/framework/tests/api/mocks/GrassEntityResource.java +++ b/source/test-java/org/alfresco/rest/framework/tests/api/mocks/GrassEntityResource.java @@ -45,7 +45,7 @@ public class GrassEntityResource implements EntityResourceAction.ReadById } @Action("cut") - public String cutLawn(String id, Parameters parameters) { + public String cutLawn(String id, Void notused, Parameters parameters) { return "All done"; } diff --git a/source/test-java/org/alfresco/rest/framework/tests/core/InspectorTests.java b/source/test-java/org/alfresco/rest/framework/tests/core/InspectorTests.java index 4b6e0d9277..a3830c6b57 100644 --- a/source/test-java/org/alfresco/rest/framework/tests/core/InspectorTests.java +++ b/source/test-java/org/alfresco/rest/framework/tests/core/InspectorTests.java @@ -445,7 +445,7 @@ public class InspectorTests assertTrue("GrassEntityResource supports POST", resourceMetadata.supports(HttpMethod.POST)); assertFalse("GrassEntityResource does not support GET", resourceMetadata.supports(HttpMethod.GET)); assertNull(resourceMetadata.getObjectType(HttpMethod.POST)); - result = (String) ResourceInspectorUtil.invokeMethod(actionMethod,grassEntityResource, "xyz", Params.valueOf("notUsed", null)); + result = (String) ResourceInspectorUtil.invokeMethod(actionMethod,grassEntityResource, "xyz", null, Params.valueOf("notUsed", null)); assertEquals("All done",result); break; default: