Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)

122241 gjames: RA-833: Added a RelationshipResourceBinaryAction


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@126462 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jamal Kaabi-Mofrad
2016-05-10 11:03:52 +00:00
parent 05757c9773
commit 7d99e1aa4a
11 changed files with 226 additions and 37 deletions

View File

@@ -49,6 +49,7 @@ import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAct
import org.alfresco.rest.framework.resource.actions.interfaces.MultiPartResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.MultiPartRelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
import org.alfresco.rest.framework.resource.actions.interfaces.ResourceAction;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.Pair;
@@ -161,6 +162,10 @@ public class ResourceInspector
findOperation(BinaryResourceAction.Delete.class, HttpMethod.DELETE, helperForAddressProps);
findOperation(BinaryResourceAction.Update.class, HttpMethod.PUT, helperForAddressProps);
findOperation(RelationshipResourceBinaryAction.Read.class, HttpMethod.GET, helperForAddressProps);
findOperation(RelationshipResourceBinaryAction.Delete.class, HttpMethod.DELETE, helperForAddressProps);
findOperation(RelationshipResourceBinaryAction.Update.class, HttpMethod.PUT, helperForAddressProps);
boolean noAuth = resource.isAnnotationPresent(WebApiNoAuth.class);
if (noAuth)
{

View File

@@ -0,0 +1,74 @@
package org.alfresco.rest.framework.resource.actions.interfaces;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.content.FileBinaryResource;
import org.alfresco.rest.framework.resource.content.NodeBinaryResource;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import java.io.InputStream;
/**
* Permissible actions for binary resources of an @RelationshipResource
*
* Supports full CRUD (Read, Update, Delete)
*
* @author Gethin James
*/
public interface RelationshipResourceBinaryAction
{
/**
* HTTP GET - Retrieve a binary resource
*/
public static interface Read extends ResourceAction
{
/**
* Retrieves a binary property by returning a BinaryResource object. The specific property is specified in the {@link Parameters} object.
* See {@link Parameters#hasBinaryProperty(String)} or {@link Parameters#getBinaryProperty()}
* @param entityId unique id
* @param entityResourceId Entity resource context for this relationship
* @param parameters {@link Parameters}
* @return BinaryResource - Either {@link FileBinaryResource} or {@link NodeBinaryResource}
* @throws EntityNotFoundException
*/
public BinaryResource readProperty(String entityId, String entityResourceId, Parameters parameters) throws EntityNotFoundException;
}
/**
* HTTP DELETE - Deletes a binary resource
*/
public static interface Delete extends ResourceAction
{
/**
* Deletes a binary property. The specific property is specified in the {@link Parameters} object.
* See {@link Parameters#hasBinaryProperty(String)} or {@link Parameters#getBinaryProperty()}
* @param entityId unique id
* @param entityResourceId Entity resource context for this relationship
* @param parameters {@link Parameters}
*/
public void deleteProperty(String entityId, String entityResourceId, Parameters parameters);
}
/**
* HTTP PUT - Updates a binary resource if it exists, error if not
*/
public static interface Update<E> extends ResourceAction
{
/**
* Updates a binary property. The specific property is specified in the {@link Parameters} object.
* See {@link Parameters#hasBinaryProperty(String)} or {@link Parameters#getBinaryProperty()}
* @param entityId unique id
* @param entityResourceId Entity resource context for this relationship
* @param stream An inputstream
* @param contentInfo Basic information about the content stream
* @param params {@link Parameters}
*/
public E updateProperty(String entityId, String entityResourceId, BasicContentInfo contentInfo, InputStream stream, Parameters params);
}
}

View File

@@ -18,7 +18,7 @@ import org.springframework.extensions.webscripts.Status;
public interface Parameters
{
/**
* Gets a single request parameter passed in by the user.
* Gets a single request query parameter passed in by the user.
* Currently doesn't support multiple values.
* @param parameterName String
* @return String The Parameter value

View File

@@ -69,6 +69,11 @@ public class Params implements Parameters
return new Params(entityId, null, passedIn, null, null, recognizedParams, null);
}
public static Params valueOf(String entityId, String relationshipId, RecognizedParams recognizedParams, Object passedIn)
{
return new Params(entityId, relationshipId, passedIn, null, null, recognizedParams, null);
}
public static Params valueOf(String entityId, String relationshipId, Object passedIn, InputStream stream, String addressedProperty, RecognizedParams recognizedParams, BasicContentInfo contentInfo)
{
return new Params(entityId, relationshipId, passedIn, stream, addressedProperty, recognizedParams, contentInfo);

View File

@@ -9,6 +9,7 @@ import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationE
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
import org.alfresco.rest.framework.resource.parameters.Params;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.webscripts.Status;
@@ -61,10 +62,19 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
}
case PROPERTY:
final String resourceName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_RESOURCE);
final String propertyName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.PROPERTY);
if (StringUtils.isNotBlank(entityId) && StringUtils.isNotBlank(resourceName))
{
if (StringUtils.isNotBlank(propertyName))
{
return Params.valueOf(entityId, relationshipId, null, null, propertyName, null, null);
}
else
{
return Params.valueOf(entityId, null, null, null, resourceName, null, null);
}
}
//Fall through to unsupported.
default:
throw new UnsupportedResourceOperationException("DELETE not supported for Actions");
@@ -100,6 +110,8 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
//Don't pass anything to the callback - its just successful
return null;
case PROPERTY:
if (BinaryResourceAction.Delete.class.isAssignableFrom(resource.getResource().getClass()))
{
if (resource.getMetaData().isDeleted(BinaryResourceAction.Delete.class))
{
throw new DeletedResourceException("(DELETE) "+resource.getMetaData().getUniqueId());
@@ -108,6 +120,18 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
binDeleter.deleteProperty(params.getEntityId(), params);
//Don't pass anything to the callback - its just successful
return null;
}
if (RelationshipResourceBinaryAction.Delete.class.isAssignableFrom(resource.getResource().getClass()))
{
if (resource.getMetaData().isDeleted(RelationshipResourceBinaryAction.Delete.class))
{
throw new DeletedResourceException("(DELETE) "+resource.getMetaData().getUniqueId());
}
RelationshipResourceBinaryAction.Delete binDeleter = (RelationshipResourceBinaryAction.Delete) resource.getResource();
binDeleter.deleteProperty(params.getEntityId(), params.getRelationshipId(), params);
//Don't pass anything to the callback - its just successful
return null;
}
default:
throw new UnsupportedResourceOperationException("DELETE not supported for Actions");
}

View File

@@ -30,6 +30,7 @@ import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAct
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction.Read;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction.ReadById;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.content.ContentInfo;
import org.alfresco.rest.framework.resource.content.NodeBinaryResource;
@@ -87,10 +88,19 @@ public class ResourceWebScriptGet extends AbstractResourceWebScript implements P
}
case PROPERTY:
final String resourceName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_RESOURCE);
final String propertyName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.PROPERTY);
if (StringUtils.isNotBlank(entityId) && StringUtils.isNotBlank(resourceName))
{
if (StringUtils.isNotBlank(propertyName))
{
return Params.valueOf(entityId, relationshipId, null, null, propertyName, params, null);
}
else
{
return Params.valueOf(entityId, null, null, null, resourceName, params, null);
}
}
//Fall through to unsupported.
default:
throw new UnsupportedResourceOperationException("GET not supported for Actions");
@@ -187,11 +197,16 @@ public class ResourceWebScriptGet extends AbstractResourceWebScript implements P
BinaryResource prop = getter.readProperty(params.getEntityId(), params);
return prop;
}
else
if (RelationshipResourceBinaryAction.Read.class.isAssignableFrom(resource.getResource().getClass()))
{
throw new UnsupportedResourceOperationException();
if (resource.getMetaData().isDeleted(RelationshipResourceBinaryAction.Read.class))
{
throw new DeletedResourceException("(GET) "+resource.getMetaData().getUniqueId());
}
RelationshipResourceBinaryAction.Read getter = (RelationshipResourceBinaryAction.Read) resource.getResource();
BinaryResource prop = getter.readProperty(params.getEntityId(), params.getRelationshipId(), params);
return prop;
}
}
else
{

View File

@@ -68,6 +68,7 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
{
final RecognizedParams params = ResourceWebScriptHelper.getRecognizedParams(req);
final String entityId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.ENTITY_ID);
final String relationshipId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_ID);
switch (resourceMeta.getType())
{
@@ -83,7 +84,6 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
return Params.valueOf(null, params, postedObj);
}
case RELATIONSHIP:
String relationshipId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_ID);
if (StringUtils.isNotBlank(relationshipId))
{
throw new UnsupportedResourceOperationException("POST is executed against the collection URL");
@@ -95,6 +95,8 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
}
case OPERATION:
final String operationName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_RESOURCE);
final String propertyName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.PROPERTY);
if (StringUtils.isNotBlank(entityId) && StringUtils.isNotBlank(operationName))
{
Class objectType = resourceMeta.getObjectType(HttpMethod.POST);
@@ -104,8 +106,16 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
//Operations don't support a List as json body
postedObj = ResourceWebScriptHelper.extractJsonContent(req, jsonHelper, objectType);
}
if (StringUtils.isNotBlank(propertyName))
{
return Params.valueOf(entityId, relationshipId, params, postedObj);
}
else
{
return Params.valueOf(entityId, params, postedObj);
}
}
//Fall through to unsupported.
default:
throw new UnsupportedResourceOperationException("POST not supported for Actions");

View File

@@ -34,7 +34,9 @@ import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationE
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.content.ContentInfoImpl;
import org.alfresco.rest.framework.resource.parameters.Params;
import org.alfresco.rest.framework.resource.parameters.Params.RecognizedParams;
@@ -95,10 +97,20 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
}
case PROPERTY:
final String resourceName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_RESOURCE);
final String propertyName = req.getServiceMatch().getTemplateVars().get(ResourceLocator.PROPERTY);
if (StringUtils.isNotBlank(entityId) && StringUtils.isNotBlank(resourceName))
{
if (StringUtils.isNotBlank(propertyName))
{
return Params.valueOf(entityId, relationshipId, null, getStream(req), propertyName, params, getContentInfo(req));
}
else
{
return Params.valueOf(entityId, null, null, getStream(req), resourceName, params, getContentInfo(req));
}
}
//Fall through to unsupported.
default:
throw new UnsupportedResourceOperationException("PUT not supported for this request.");
@@ -185,12 +197,24 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
Object relResult = relationUpdater.update(params.getEntityId(), params.getPassedIn(), params);
return relResult;
case PROPERTY:
if (BinaryResourceAction.Update.class.isAssignableFrom(resource.getResource().getClass()))
{
if (resource.getMetaData().isDeleted(BinaryResourceAction.Update.class))
{
throw new DeletedResourceException("(UPDATE) "+resource.getMetaData().getUniqueId());
}
BinaryResourceAction.Update<Object> binUpdater = (BinaryResourceAction.Update<Object>) resource.getResource();
return binUpdater.updateProperty(params.getEntityId(), params.getContentInfo(), params.getStream(), params);
}
if (RelationshipResourceBinaryAction.Update.class.isAssignableFrom(resource.getResource().getClass()))
{
if (resource.getMetaData().isDeleted(RelationshipResourceBinaryAction.Update.class))
{
throw new DeletedResourceException("(UPDATE) "+resource.getMetaData().getUniqueId());
}
RelationshipResourceBinaryAction.Update<Object> binUpdater = (RelationshipResourceBinaryAction.Update<Object>) resource.getResource();
return binUpdater.updateProperty(params.getEntityId(), params.getRelationshipId(), params.getContentInfo(), params.getStream(), params);
}
default:
throw new UnsupportedResourceOperationException("PUT not supported for Actions");
}

View File

@@ -11,6 +11,7 @@ import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
@@ -22,7 +23,7 @@ import org.alfresco.rest.framework.resource.parameters.Parameters;
* @author Gethin James
*/
@RelationshipResource(name = "baaahh", entityResource=SheepEntityResource.class, title = "Sheep baaah")
public class SheepBaaaahResource implements RelationshipResourceAction.Read<Sheep>, RelationshipResourceAction.ReadById<Sheep>, BinaryResourceAction.Read, BinaryResourceAction.Delete,BinaryResourceAction.Update
public class SheepBaaaahResource implements RelationshipResourceAction.Read<Sheep>, RelationshipResourceAction.ReadById<Sheep>, RelationshipResourceBinaryAction.Read, RelationshipResourceBinaryAction.Delete,RelationshipResourceBinaryAction.Update
{
@Override
@@ -39,27 +40,26 @@ public class SheepBaaaahResource implements RelationshipResourceAction.Read<Shee
return CollectionWithPagingInfo.asPaged(params.getPaging(),toReturn,toReturn.size()!=3 ,3);
}
@Override
@WebApiDescription(title = "Deletes a photo")
@BinaryProperties("photo")
public void deleteProperty(String entityId, Parameters parameters)
{
}
@Override
@WebApiDescription(title = "Reads a photo")
@BinaryProperties("photo")
public BinaryResource readProperty(String entityId, Parameters parameters) throws EntityNotFoundException
public BinaryResource readProperty(String entityId, String id, Parameters parameters) throws EntityNotFoundException
{
return null;
}
@Override
@WebApiDescription(title = "Deletes a photo")
@BinaryProperties("photo")
public void deleteProperty(String entityId, String entityResourceId, Parameters parameters)
{
}
@Override
@WebApiDescription(title = "Updates a photo")
@BinaryProperties("photo")
public Object updateProperty(String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params)
public Object updateProperty(String entityId, String entityResourceId, BasicContentInfo contentInfo, InputStream stream, Parameters params)
{
return null;
}

View File

@@ -6,6 +6,7 @@ import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.content.FileBinaryResource;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
@@ -20,7 +21,7 @@ import java.io.File;
* @author Gethin James
*/
@RelationshipResource(name = "herd",entityResource=GoatEntityResourceForV3.class, title = "Goat Herd")
public class GoatRelationshipResource implements RelationshipResourceAction.Read<Herd>, BinaryResourceAction.Read
public class GoatRelationshipResource implements RelationshipResourceAction.Read<Herd>, RelationshipResourceBinaryAction.Read
{
@Override
public CollectionWithPagingInfo<Herd> readAll(String entityResourceId, Parameters params)
@@ -30,10 +31,9 @@ public class GoatRelationshipResource implements RelationshipResourceAction.Read
@WebApiDescription(title = "Download content", description = "Download content")
@BinaryProperties({"content"})
public BinaryResource readProperty(String herdId, Parameters parameters) throws EntityNotFoundException
public BinaryResource readProperty(String herdId, String entityResourceId, Parameters parameters) throws EntityNotFoundException
{
File file = TempFileProvider.createTempFile("Its a goat", ".txt");
return new FileBinaryResource(file);
}
}

View File

@@ -87,6 +87,11 @@ public class ParamsExtractorTests
assertNotNull(params.getRelationsFilter());
assertFalse(params.includeSource());
templateVars.put(ResourceLocator.RELATIONSHIP_RESOURCE, "codfish");
params = extractor.extractParams(mockRelationship(), request);
assertNotNull(params);
assertNull("For getting a Collection there should be no relationshipId params.",params.getRelationshipId());
templateVars.put(ResourceLocator.RELATIONSHIP_ID, "45678");
params = extractor.extractParams(mockRelationship(), request);
assertNotNull(params);
@@ -107,6 +112,14 @@ public class ParamsExtractorTests
assertTrue(params.hasBinaryProperty("codfish"));
assertFalse(params.hasBinaryProperty("something"));
assertEquals("codfish", params.getBinaryProperty());
templateVars.put(ResourceLocator.RELATIONSHIP_ID, "9865");
templateVars.put(ResourceLocator.PROPERTY, "monkFish");
params = extractor.extractParams(mockProperty(), request);
assertNotNull(params);
assertEquals("1234", params.getEntityId());
assertEquals("9865", params.getRelationshipId());
assertTrue(params.hasBinaryProperty("monkFish"));
return params;
}
@@ -187,6 +200,25 @@ public class ParamsExtractorTests
{
assertNotNull(uoe); //Must throw this exception
}
testExtractOperationParams(templateVars, request, extractor);
}
private Params testExtractOperationParams(Map<String, String> templateVars, WebScriptRequest request, ParamsExtractor extractor)
{
templateVars.clear();
templateVars.put(ResourceLocator.ENTITY_ID, "1234");
templateVars.put(ResourceLocator.RELATIONSHIP_RESOURCE, "codfish");
Params params = extractor.extractParams(mockOperation(), request);
assertNotNull(params);
assertNull("For a Collection there should be no relationshipId params.",params.getRelationshipId());
templateVars.put(ResourceLocator.RELATIONSHIP_ID, "9865");
templateVars.put(ResourceLocator.PROPERTY, "monkFish");
params = extractor.extractParams(mockOperation(), request);
assertNotNull(params);
assertEquals("1234", params.getEntityId());
assertEquals("9865", params.getRelationshipId());
return params;
}
@Test