mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged 5.2.N (5.2.1) to HEAD (5.2)
125783 rmunteanu: 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/HEAD/root@127809 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
package org.alfresco.rest.framework;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* An array of binary property names used on a resource method operation in the Rest API
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface BinaryProperties {
|
||||
String[] value();
|
||||
}
|
||||
|
||||
package org.alfresco.rest.framework;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* An array of binary property names used on a resource method operation in the Rest API
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface BinaryProperties {
|
||||
String[] value();
|
||||
}
|
||||
|
||||
|
@@ -1,167 +1,167 @@
|
||||
package org.alfresco.rest.framework.core;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
||||
/**
|
||||
* Generic methods used by ResourceInspector
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class ResourceInspectorUtil
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ResourceInspectorUtil.class);
|
||||
/**
|
||||
* Determine the expected type as the returned type of the method.
|
||||
* If the return type is a List it will return the generic element type instead of a List.
|
||||
* @param resource - resource with methods
|
||||
* @param method Method
|
||||
* @return Class - type of class it needs.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected static Class determineType(Class resource, Method method)
|
||||
{
|
||||
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
|
||||
|
||||
/*
|
||||
* The api is consistent that the object passed in must match the object passed out
|
||||
* 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, Operation.class);
|
||||
if (annot != null)
|
||||
{
|
||||
return determineOperationType(resource, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
Class returnType = GenericTypeResolver.resolveReturnType(resolvedMethod, resource);
|
||||
if (List.class.isAssignableFrom(returnType))
|
||||
{
|
||||
return GenericCollectionTypeResolver.getCollectionReturnType(method);
|
||||
}
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
|
||||
protected static Class determineOperationType(Class resource, Method method)
|
||||
{
|
||||
//Its an operation annotated method and its a bit special
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
if (paramTypes!= null)
|
||||
{
|
||||
switch (paramTypes.length)
|
||||
{
|
||||
case 4:
|
||||
//EntityResource operation by id, same logic as RelationshipEntityResource operation by id
|
||||
case 5:
|
||||
int position = paramTypes.length-3;
|
||||
if (Void.class.equals(paramTypes[position]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return paramTypes[position];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Your method signature should have 4 parameters (uniqueId, typePassedin, Parameters, WithResponse)," +
|
||||
" use Void if you are not interested in the second argument. "+resource.getName()+ " "+ method.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds methods for the given annotation
|
||||
*
|
||||
* It first finds all public member methods of the class or interface represented by objClass,
|
||||
* including those inherited from superclasses and superinterfaces.
|
||||
*
|
||||
* It then loops through these methods searching for a single Annotation of annotationType,
|
||||
* traversing its super methods if no annotation can be found on the given method itself.
|
||||
*
|
||||
* @param objClass - the class
|
||||
* @param annotationType - the annotation to find
|
||||
* @return - the List of Method or an empty List
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static List<Method> findMethodsByAnnotation(Class objClass, Class<? extends Annotation> annotationType)
|
||||
{
|
||||
|
||||
List<Method> annotatedMethods = new ArrayList<Method>();
|
||||
Method[] methods = objClass.getMethods();
|
||||
for (Method method : methods)
|
||||
{
|
||||
Annotation annot = AnnotationUtils.findAnnotation(method, annotationType);
|
||||
if (annot != null) {
|
||||
//Just to be sure, lets make sure its not a Bridged (Generic) Method
|
||||
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
|
||||
annotatedMethods.add(resolvedMethod);
|
||||
}
|
||||
}
|
||||
|
||||
return annotatedMethods;
|
||||
|
||||
}
|
||||
/**
|
||||
* Invokes a no arg method and returns the result
|
||||
* @param annotatedMethod Method
|
||||
* @param obj Object
|
||||
* @return result of method call
|
||||
*/
|
||||
public static Object invokeMethod(Method annotatedMethod, Object obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
return invokeMethod(annotatedMethod, obj, null);
|
||||
}
|
||||
catch (Throwable error)
|
||||
{
|
||||
logger.error("Invocation failure", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a method and returns the result
|
||||
* @param annotatedMethod Method
|
||||
* @param obj Object
|
||||
* @return result of method call
|
||||
*/
|
||||
public static Object invokeMethod(Method annotatedMethod, Object obj, Object... args) throws Throwable
|
||||
{
|
||||
if (annotatedMethod != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return annotatedMethod.invoke(obj, args);
|
||||
}
|
||||
catch (IllegalArgumentException error)
|
||||
{
|
||||
logger.warn("Invocation error", error);
|
||||
}
|
||||
catch (IllegalAccessException error)
|
||||
{
|
||||
logger.warn("IllegalAccessException", error);
|
||||
}
|
||||
catch (InvocationTargetException error)
|
||||
{
|
||||
logger.warn("InvocationTargetException", error);
|
||||
throw error.getCause();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.rest.framework.core;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
||||
/**
|
||||
* Generic methods used by ResourceInspector
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class ResourceInspectorUtil
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ResourceInspectorUtil.class);
|
||||
/**
|
||||
* Determine the expected type as the returned type of the method.
|
||||
* If the return type is a List it will return the generic element type instead of a List.
|
||||
* @param resource - resource with methods
|
||||
* @param method Method
|
||||
* @return Class - type of class it needs.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected static Class determineType(Class resource, Method method)
|
||||
{
|
||||
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
|
||||
|
||||
/*
|
||||
* The api is consistent that the object passed in must match the object passed out
|
||||
* 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, Operation.class);
|
||||
if (annot != null)
|
||||
{
|
||||
return determineOperationType(resource, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
Class returnType = GenericTypeResolver.resolveReturnType(resolvedMethod, resource);
|
||||
if (List.class.isAssignableFrom(returnType))
|
||||
{
|
||||
return GenericCollectionTypeResolver.getCollectionReturnType(method);
|
||||
}
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
|
||||
protected static Class determineOperationType(Class resource, Method method)
|
||||
{
|
||||
//Its an operation annotated method and its a bit special
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
if (paramTypes!= null)
|
||||
{
|
||||
switch (paramTypes.length)
|
||||
{
|
||||
case 4:
|
||||
//EntityResource operation by id, same logic as RelationshipEntityResource operation by id
|
||||
case 5:
|
||||
int position = paramTypes.length-3;
|
||||
if (Void.class.equals(paramTypes[position]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return paramTypes[position];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Your method signature should have 4 parameters (uniqueId, typePassedin, Parameters, WithResponse)," +
|
||||
" use Void if you are not interested in the second argument. "+resource.getName()+ " "+ method.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds methods for the given annotation
|
||||
*
|
||||
* It first finds all public member methods of the class or interface represented by objClass,
|
||||
* including those inherited from superclasses and superinterfaces.
|
||||
*
|
||||
* It then loops through these methods searching for a single Annotation of annotationType,
|
||||
* traversing its super methods if no annotation can be found on the given method itself.
|
||||
*
|
||||
* @param objClass - the class
|
||||
* @param annotationType - the annotation to find
|
||||
* @return - the List of Method or an empty List
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static List<Method> findMethodsByAnnotation(Class objClass, Class<? extends Annotation> annotationType)
|
||||
{
|
||||
|
||||
List<Method> annotatedMethods = new ArrayList<Method>();
|
||||
Method[] methods = objClass.getMethods();
|
||||
for (Method method : methods)
|
||||
{
|
||||
Annotation annot = AnnotationUtils.findAnnotation(method, annotationType);
|
||||
if (annot != null) {
|
||||
//Just to be sure, lets make sure its not a Bridged (Generic) Method
|
||||
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
|
||||
annotatedMethods.add(resolvedMethod);
|
||||
}
|
||||
}
|
||||
|
||||
return annotatedMethods;
|
||||
|
||||
}
|
||||
/**
|
||||
* Invokes a no arg method and returns the result
|
||||
* @param annotatedMethod Method
|
||||
* @param obj Object
|
||||
* @return result of method call
|
||||
*/
|
||||
public static Object invokeMethod(Method annotatedMethod, Object obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
return invokeMethod(annotatedMethod, obj, null);
|
||||
}
|
||||
catch (Throwable error)
|
||||
{
|
||||
logger.error("Invocation failure", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a method and returns the result
|
||||
* @param annotatedMethod Method
|
||||
* @param obj Object
|
||||
* @return result of method call
|
||||
*/
|
||||
public static Object invokeMethod(Method annotatedMethod, Object obj, Object... args) throws Throwable
|
||||
{
|
||||
if (annotatedMethod != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return annotatedMethod.invoke(obj, args);
|
||||
}
|
||||
catch (IllegalArgumentException error)
|
||||
{
|
||||
logger.warn("Invocation error", error);
|
||||
}
|
||||
catch (IllegalAccessException error)
|
||||
{
|
||||
logger.warn("IllegalAccessException", error);
|
||||
}
|
||||
catch (InvocationTargetException error)
|
||||
{
|
||||
logger.warn("InvocationTargetException", error);
|
||||
throw error.getCause();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,48 +1,48 @@
|
||||
package org.alfresco.rest.framework.jacksonextensions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonProcessingException;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.codehaus.jackson.map.DeserializationContext;
|
||||
import org.codehaus.jackson.map.JsonDeserializer;
|
||||
|
||||
public class NodeRefDeserializer extends JsonDeserializer<NodeRef>
|
||||
{
|
||||
private NodeRef getNodeRef(String nodeRefString)
|
||||
{
|
||||
NodeRef nodeRef = null;
|
||||
|
||||
if(!NodeRef.isNodeRef(nodeRefString))
|
||||
{
|
||||
nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeRefString);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeRef = new NodeRef(nodeRefString);
|
||||
}
|
||||
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeRef deserialize(JsonParser jp, DeserializationContext ctxt)
|
||||
throws IOException, JsonProcessingException
|
||||
{
|
||||
JsonToken curr = jp.getCurrentToken();
|
||||
|
||||
if (curr == JsonToken.VALUE_STRING)
|
||||
{
|
||||
String nodeRefString = jp.getText();
|
||||
NodeRef nodeRef = getNodeRef(nodeRefString);
|
||||
return nodeRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Unable to deserialize nodeRef: " + curr.asString());
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.rest.framework.jacksonextensions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonProcessingException;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.codehaus.jackson.map.DeserializationContext;
|
||||
import org.codehaus.jackson.map.JsonDeserializer;
|
||||
|
||||
public class NodeRefDeserializer extends JsonDeserializer<NodeRef>
|
||||
{
|
||||
private NodeRef getNodeRef(String nodeRefString)
|
||||
{
|
||||
NodeRef nodeRef = null;
|
||||
|
||||
if(!NodeRef.isNodeRef(nodeRefString))
|
||||
{
|
||||
nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeRefString);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeRef = new NodeRef(nodeRefString);
|
||||
}
|
||||
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeRef deserialize(JsonParser jp, DeserializationContext ctxt)
|
||||
throws IOException, JsonProcessingException
|
||||
{
|
||||
JsonToken curr = jp.getCurrentToken();
|
||||
|
||||
if (curr == JsonToken.VALUE_STRING)
|
||||
{
|
||||
String nodeRefString = jp.getText();
|
||||
NodeRef nodeRef = getNodeRef(nodeRefString);
|
||||
return nodeRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Unable to deserialize nodeRef: " + curr.asString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,25 +1,25 @@
|
||||
package org.alfresco.rest.framework.jacksonextensions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.codehaus.jackson.JsonGenerationException;
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
import org.codehaus.jackson.map.SerializerProvider;
|
||||
import org.codehaus.jackson.map.ser.std.SerializerBase;
|
||||
|
||||
public class NodeRefSerializer extends SerializerBase<NodeRef>
|
||||
{
|
||||
protected NodeRefSerializer()
|
||||
{
|
||||
super(NodeRef.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(NodeRef nodeRef, JsonGenerator jgen, SerializerProvider provider)
|
||||
throws IOException, JsonGenerationException
|
||||
{
|
||||
jgen.writeString(nodeRef.getId());
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.rest.framework.jacksonextensions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.codehaus.jackson.JsonGenerationException;
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
import org.codehaus.jackson.map.SerializerProvider;
|
||||
import org.codehaus.jackson.map.ser.std.SerializerBase;
|
||||
|
||||
public class NodeRefSerializer extends SerializerBase<NodeRef>
|
||||
{
|
||||
protected NodeRefSerializer()
|
||||
{
|
||||
super(NodeRef.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(NodeRef nodeRef, JsonGenerator jgen, SerializerProvider provider)
|
||||
throws IOException, JsonGenerationException
|
||||
{
|
||||
jgen.writeString(nodeRef.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,31 +1,31 @@
|
||||
package org.alfresco.rest.framework.jacksonextensions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonProcessingException;
|
||||
import org.codehaus.jackson.map.DeserializationContext;
|
||||
import org.codehaus.jackson.map.deser.std.StringDeserializer;
|
||||
|
||||
/**
|
||||
* Rest api string deserializer that ensures that empty strings are treated as null strings.
|
||||
*
|
||||
* @author steveglover
|
||||
*
|
||||
*/
|
||||
public class RestApiStringDeserializer extends StringDeserializer
|
||||
{
|
||||
@Override
|
||||
public String deserialize(JsonParser jp, DeserializationContext ctxt)
|
||||
throws IOException, JsonProcessingException
|
||||
{
|
||||
String ret = super.deserialize(jp, ctxt);
|
||||
|
||||
if(ret != null && ret.length() == 0)
|
||||
{
|
||||
ret = null;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
package org.alfresco.rest.framework.jacksonextensions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonProcessingException;
|
||||
import org.codehaus.jackson.map.DeserializationContext;
|
||||
import org.codehaus.jackson.map.deser.std.StringDeserializer;
|
||||
|
||||
/**
|
||||
* Rest api string deserializer that ensures that empty strings are treated as null strings.
|
||||
*
|
||||
* @author steveglover
|
||||
*
|
||||
*/
|
||||
public class RestApiStringDeserializer extends StringDeserializer
|
||||
{
|
||||
@Override
|
||||
public String deserialize(JsonParser jp, DeserializationContext ctxt)
|
||||
throws IOException, JsonProcessingException
|
||||
{
|
||||
String ret = super.deserialize(jp, ctxt);
|
||||
|
||||
if(ret != null && ret.length() == 0)
|
||||
{
|
||||
ret = null;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@@ -1,98 +1,98 @@
|
||||
package org.alfresco.rest.framework.jacksonextensions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.alfresco.rest.api.model.Document;
|
||||
import org.alfresco.rest.api.model.DocumentTarget;
|
||||
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.SiteTarget;
|
||||
import org.alfresco.rest.api.model.Target;
|
||||
import org.alfresco.service.cmr.favourites.FavouritesService.Type;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonProcessingException;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.codehaus.jackson.map.BeanProperty;
|
||||
import org.codehaus.jackson.map.BeanProperty.Std;
|
||||
import org.codehaus.jackson.map.DeserializationContext;
|
||||
import org.codehaus.jackson.map.JsonDeserializer;
|
||||
import org.codehaus.jackson.map.JsonMappingException;
|
||||
import org.codehaus.jackson.map.type.SimpleType;
|
||||
import org.codehaus.jackson.type.JavaType;
|
||||
|
||||
public class TargetDeserializer extends JsonDeserializer<Target>
|
||||
{
|
||||
@Override
|
||||
public Target deserialize(JsonParser jp, DeserializationContext ctxt)
|
||||
throws IOException, JsonProcessingException
|
||||
{
|
||||
Target target = null;
|
||||
JsonToken curr = jp.getCurrentToken();
|
||||
|
||||
if (curr == JsonToken.START_OBJECT)
|
||||
{
|
||||
while(jp.nextToken() != JsonToken.END_OBJECT)
|
||||
{
|
||||
String fieldname = jp.getCurrentName();
|
||||
if(Type.SITE.toString().equals(fieldname.toUpperCase()))
|
||||
{
|
||||
jp.nextToken();
|
||||
try
|
||||
{
|
||||
JavaType t = SimpleType.construct(Site.class);
|
||||
BeanProperty p = new Std("", t, null, null);
|
||||
JsonDeserializer<?> siteDeserializer = ctxt.getDeserializerProvider().findValueDeserializer(ctxt.getConfig(), t, p);
|
||||
|
||||
Site site = (Site)siteDeserializer.deserialize(jp, ctxt);
|
||||
target = new SiteTarget(site);
|
||||
}
|
||||
catch(JsonMappingException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Target body is invalid for target type");
|
||||
}
|
||||
}
|
||||
else if(Type.FILE.toString().equals(fieldname.toUpperCase()))
|
||||
{
|
||||
jp.nextToken();
|
||||
try
|
||||
{
|
||||
JavaType t = SimpleType.construct(Document.class);
|
||||
BeanProperty p = new Std("", t, null, null);
|
||||
JsonDeserializer<?> documentDeserializer = ctxt.getDeserializerProvider().findValueDeserializer(ctxt.getConfig(), t, p);
|
||||
|
||||
Document document = (Document)documentDeserializer.deserialize(jp, ctxt);
|
||||
target = new DocumentTarget(document);
|
||||
}
|
||||
catch(JsonMappingException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Target body is invalid for target type");
|
||||
}
|
||||
}
|
||||
else if(Type.FOLDER.toString().equals(fieldname.toUpperCase()))
|
||||
{
|
||||
jp.nextToken();
|
||||
try
|
||||
{
|
||||
JavaType t = SimpleType.construct(Folder.class);
|
||||
BeanProperty p = new Std("", t, null, null);
|
||||
JsonDeserializer<?> folderDeserializer = ctxt.getDeserializerProvider().findValueDeserializer(ctxt.getConfig(), t, p);
|
||||
|
||||
Folder folder = (Folder)folderDeserializer.deserialize(jp, ctxt);
|
||||
target = new FolderTarget(folder);
|
||||
}
|
||||
catch(JsonMappingException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Target body is invalid for target type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Unable to deserialize favourite: " + curr.asString());
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.rest.framework.jacksonextensions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.alfresco.rest.api.model.Document;
|
||||
import org.alfresco.rest.api.model.DocumentTarget;
|
||||
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.SiteTarget;
|
||||
import org.alfresco.rest.api.model.Target;
|
||||
import org.alfresco.service.cmr.favourites.FavouritesService.Type;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonProcessingException;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.codehaus.jackson.map.BeanProperty;
|
||||
import org.codehaus.jackson.map.BeanProperty.Std;
|
||||
import org.codehaus.jackson.map.DeserializationContext;
|
||||
import org.codehaus.jackson.map.JsonDeserializer;
|
||||
import org.codehaus.jackson.map.JsonMappingException;
|
||||
import org.codehaus.jackson.map.type.SimpleType;
|
||||
import org.codehaus.jackson.type.JavaType;
|
||||
|
||||
public class TargetDeserializer extends JsonDeserializer<Target>
|
||||
{
|
||||
@Override
|
||||
public Target deserialize(JsonParser jp, DeserializationContext ctxt)
|
||||
throws IOException, JsonProcessingException
|
||||
{
|
||||
Target target = null;
|
||||
JsonToken curr = jp.getCurrentToken();
|
||||
|
||||
if (curr == JsonToken.START_OBJECT)
|
||||
{
|
||||
while(jp.nextToken() != JsonToken.END_OBJECT)
|
||||
{
|
||||
String fieldname = jp.getCurrentName();
|
||||
if(Type.SITE.toString().equals(fieldname.toUpperCase()))
|
||||
{
|
||||
jp.nextToken();
|
||||
try
|
||||
{
|
||||
JavaType t = SimpleType.construct(Site.class);
|
||||
BeanProperty p = new Std("", t, null, null);
|
||||
JsonDeserializer<?> siteDeserializer = ctxt.getDeserializerProvider().findValueDeserializer(ctxt.getConfig(), t, p);
|
||||
|
||||
Site site = (Site)siteDeserializer.deserialize(jp, ctxt);
|
||||
target = new SiteTarget(site);
|
||||
}
|
||||
catch(JsonMappingException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Target body is invalid for target type");
|
||||
}
|
||||
}
|
||||
else if(Type.FILE.toString().equals(fieldname.toUpperCase()))
|
||||
{
|
||||
jp.nextToken();
|
||||
try
|
||||
{
|
||||
JavaType t = SimpleType.construct(Document.class);
|
||||
BeanProperty p = new Std("", t, null, null);
|
||||
JsonDeserializer<?> documentDeserializer = ctxt.getDeserializerProvider().findValueDeserializer(ctxt.getConfig(), t, p);
|
||||
|
||||
Document document = (Document)documentDeserializer.deserialize(jp, ctxt);
|
||||
target = new DocumentTarget(document);
|
||||
}
|
||||
catch(JsonMappingException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Target body is invalid for target type");
|
||||
}
|
||||
}
|
||||
else if(Type.FOLDER.toString().equals(fieldname.toUpperCase()))
|
||||
{
|
||||
jp.nextToken();
|
||||
try
|
||||
{
|
||||
JavaType t = SimpleType.construct(Folder.class);
|
||||
BeanProperty p = new Std("", t, null, null);
|
||||
JsonDeserializer<?> folderDeserializer = ctxt.getDeserializerProvider().findValueDeserializer(ctxt.getConfig(), t, p);
|
||||
|
||||
Folder folder = (Folder)folderDeserializer.deserialize(jp, ctxt);
|
||||
target = new FolderTarget(folder);
|
||||
}
|
||||
catch(JsonMappingException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Target body is invalid for target type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Unable to deserialize favourite: " + curr.asString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,119 +1,119 @@
|
||||
package org.alfresco.rest.framework.resource.actions.interfaces;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
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 org.alfresco.rest.framework.webscripts.WithResponse;
|
||||
|
||||
/**
|
||||
* Permissible actions for binary resources of an Entity Resource
|
||||
*
|
||||
* Supports full CRUD (Read, Update, Delete)
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
|
||||
public interface BinaryResourceAction
|
||||
{
|
||||
|
||||
/**
|
||||
* 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 parameters {@link Parameters}
|
||||
* @return BinaryResource - Either {@link FileBinaryResource} or {@link NodeBinaryResource}
|
||||
* @throws EntityNotFoundException
|
||||
*/
|
||||
public BinaryResource readProperty (String entityId, Parameters parameters) throws EntityNotFoundException;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP GET - Retrieve a binary resource
|
||||
*/
|
||||
public static interface ReadWithResponse 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 parameters {@link Parameters}
|
||||
* @return BinaryResource - Either {@link FileBinaryResource} or {@link NodeBinaryResource}
|
||||
* @throws EntityNotFoundException
|
||||
*/
|
||||
public BinaryResource readProperty (String entityId, Parameters parameters, WithResponse withResponse) 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 parameters {@link Parameters}
|
||||
*/
|
||||
public void deleteProperty (String entityId, Parameters parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP DELETE - Deletes a binary resource
|
||||
*/
|
||||
public static interface DeleteWithResponse 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 parameters {@link Parameters}
|
||||
*/
|
||||
public void deleteProperty (String entityId, Parameters parameters, WithResponse withResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 stream An inputstream
|
||||
* @param contentInfo Basic information about the content stream
|
||||
* @param params {@link Parameters}
|
||||
*/
|
||||
public E updateProperty (String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP PUT - Updates a binary resource if it exists, error if not
|
||||
*/
|
||||
public static interface UpdateWithResponse<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 stream An inputstream
|
||||
* @param contentInfo Basic information about the content stream
|
||||
* @param params {@link Parameters}
|
||||
*/
|
||||
public E updateProperty (String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params, WithResponse withResponse);
|
||||
}
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.actions.interfaces;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
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 org.alfresco.rest.framework.webscripts.WithResponse;
|
||||
|
||||
/**
|
||||
* Permissible actions for binary resources of an Entity Resource
|
||||
*
|
||||
* Supports full CRUD (Read, Update, Delete)
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
|
||||
public interface BinaryResourceAction
|
||||
{
|
||||
|
||||
/**
|
||||
* 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 parameters {@link Parameters}
|
||||
* @return BinaryResource - Either {@link FileBinaryResource} or {@link NodeBinaryResource}
|
||||
* @throws EntityNotFoundException
|
||||
*/
|
||||
public BinaryResource readProperty (String entityId, Parameters parameters) throws EntityNotFoundException;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP GET - Retrieve a binary resource
|
||||
*/
|
||||
public static interface ReadWithResponse 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 parameters {@link Parameters}
|
||||
* @return BinaryResource - Either {@link FileBinaryResource} or {@link NodeBinaryResource}
|
||||
* @throws EntityNotFoundException
|
||||
*/
|
||||
public BinaryResource readProperty (String entityId, Parameters parameters, WithResponse withResponse) 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 parameters {@link Parameters}
|
||||
*/
|
||||
public void deleteProperty (String entityId, Parameters parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP DELETE - Deletes a binary resource
|
||||
*/
|
||||
public static interface DeleteWithResponse 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 parameters {@link Parameters}
|
||||
*/
|
||||
public void deleteProperty (String entityId, Parameters parameters, WithResponse withResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 stream An inputstream
|
||||
* @param contentInfo Basic information about the content stream
|
||||
* @param params {@link Parameters}
|
||||
*/
|
||||
public E updateProperty (String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP PUT - Updates a binary resource if it exists, error if not
|
||||
*/
|
||||
public static interface UpdateWithResponse<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 stream An inputstream
|
||||
* @param contentInfo Basic information about the content stream
|
||||
* @param params {@link Parameters}
|
||||
*/
|
||||
public E updateProperty (String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params, WithResponse withResponse);
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +1,12 @@
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
|
||||
/**
|
||||
* Basic information about content. Typically taken from a HTTPServletRequest.
|
||||
* You may choose to trust it but there is no guarantee that it accurately describes the content.
|
||||
*/
|
||||
public interface BasicContentInfo {
|
||||
public String getMimeType();
|
||||
public String getEncoding();
|
||||
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
|
||||
/**
|
||||
* Basic information about content. Typically taken from a HTTPServletRequest.
|
||||
* You may choose to trust it but there is no guarantee that it accurately describes the content.
|
||||
*/
|
||||
public interface BasicContentInfo {
|
||||
public String getMimeType();
|
||||
public String getEncoding();
|
||||
|
||||
}
|
||||
|
@@ -1,102 +1,102 @@
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
|
||||
/**
|
||||
* A POJO property that is of type "Binary"
|
||||
*
|
||||
* You can add this to your object to be serialized as a normal property.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
|
||||
public class BinaryProperty implements ContentInfo, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 7392073427641063968L;
|
||||
|
||||
private final String mimeType;
|
||||
private final String encoding;
|
||||
private final long length;
|
||||
private final Locale locale;
|
||||
|
||||
/**
|
||||
* Sets the content length to zero, Locale to null, no stream and no caching
|
||||
* @param mimeType String
|
||||
* @param encoding String
|
||||
*/
|
||||
public BinaryProperty(String mimeType, String encoding)
|
||||
{
|
||||
super();
|
||||
this.mimeType = mimeType;
|
||||
this.encoding = encoding;
|
||||
this.length = 0;
|
||||
this.locale = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the preferred constructor to use. Takes the properties from content reader that it needs.
|
||||
* @param reader ContentReader
|
||||
*/
|
||||
public BinaryProperty(ContentReader reader)
|
||||
{
|
||||
super();
|
||||
this.mimeType = reader.getMimetype();
|
||||
this.encoding = reader.getEncoding();
|
||||
this.length = reader.getSize();
|
||||
this.locale = reader.getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets no stream and no caching
|
||||
* @param mimeType String
|
||||
* @param encoding String
|
||||
* @param length long
|
||||
* @param locale Locale
|
||||
*/
|
||||
public BinaryProperty(String mimeType, String encoding, long length, Locale locale)
|
||||
{
|
||||
super();
|
||||
this.mimeType = mimeType;
|
||||
this.encoding = encoding;
|
||||
this.length = length;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public String getMimeType()
|
||||
{
|
||||
return this.mimeType;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getEncoding()
|
||||
{
|
||||
return this.encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for serialization. If the length is unknown then this method returns null
|
||||
* and is therefore not serialized.
|
||||
*
|
||||
* @return Long size - null if unknown.
|
||||
*/
|
||||
public Long getSizeInBytes()
|
||||
{
|
||||
return this.length>0?this.length:null;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public long getLength()
|
||||
{
|
||||
return this.length;
|
||||
}
|
||||
@JsonIgnore
|
||||
public Locale getLocale()
|
||||
{
|
||||
return this.locale;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
|
||||
/**
|
||||
* A POJO property that is of type "Binary"
|
||||
*
|
||||
* You can add this to your object to be serialized as a normal property.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
|
||||
public class BinaryProperty implements ContentInfo, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 7392073427641063968L;
|
||||
|
||||
private final String mimeType;
|
||||
private final String encoding;
|
||||
private final long length;
|
||||
private final Locale locale;
|
||||
|
||||
/**
|
||||
* Sets the content length to zero, Locale to null, no stream and no caching
|
||||
* @param mimeType String
|
||||
* @param encoding String
|
||||
*/
|
||||
public BinaryProperty(String mimeType, String encoding)
|
||||
{
|
||||
super();
|
||||
this.mimeType = mimeType;
|
||||
this.encoding = encoding;
|
||||
this.length = 0;
|
||||
this.locale = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the preferred constructor to use. Takes the properties from content reader that it needs.
|
||||
* @param reader ContentReader
|
||||
*/
|
||||
public BinaryProperty(ContentReader reader)
|
||||
{
|
||||
super();
|
||||
this.mimeType = reader.getMimetype();
|
||||
this.encoding = reader.getEncoding();
|
||||
this.length = reader.getSize();
|
||||
this.locale = reader.getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets no stream and no caching
|
||||
* @param mimeType String
|
||||
* @param encoding String
|
||||
* @param length long
|
||||
* @param locale Locale
|
||||
*/
|
||||
public BinaryProperty(String mimeType, String encoding, long length, Locale locale)
|
||||
{
|
||||
super();
|
||||
this.mimeType = mimeType;
|
||||
this.encoding = encoding;
|
||||
this.length = length;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public String getMimeType()
|
||||
{
|
||||
return this.mimeType;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getEncoding()
|
||||
{
|
||||
return this.encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for serialization. If the length is unknown then this method returns null
|
||||
* and is therefore not serialized.
|
||||
*
|
||||
* @return Long size - null if unknown.
|
||||
*/
|
||||
public Long getSizeInBytes()
|
||||
{
|
||||
return this.length>0?this.length:null;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public long getLength()
|
||||
{
|
||||
return this.length;
|
||||
}
|
||||
@JsonIgnore
|
||||
public Locale getLocale()
|
||||
{
|
||||
return this.locale;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
/**
|
||||
* A resource that is of type "Binary"
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public interface BinaryResource
|
||||
{
|
||||
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
/**
|
||||
* A resource that is of type "Binary"
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public interface BinaryResource
|
||||
{
|
||||
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Basic information about content. Typically used with HTTPServletResponse
|
||||
*/
|
||||
public interface ContentInfo extends BasicContentInfo{
|
||||
public long getLength();
|
||||
public Locale getLocale();
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Basic information about content. Typically used with HTTPServletResponse
|
||||
*/
|
||||
public interface ContentInfo extends BasicContentInfo{
|
||||
public long getLength();
|
||||
public Locale getLocale();
|
||||
}
|
||||
|
@@ -1,44 +1,44 @@
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Basic implementation of information about the returned content.
|
||||
*/
|
||||
public class ContentInfoImpl implements ContentInfo
|
||||
{
|
||||
private final String mimeType;
|
||||
private final String encoding;
|
||||
private final long length;
|
||||
private final Locale locale;
|
||||
|
||||
public ContentInfoImpl(String mimeType, String encoding, long length, Locale locale)
|
||||
{
|
||||
super();
|
||||
this.mimeType = mimeType;
|
||||
this.encoding = encoding;
|
||||
this.length = length;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMimeType()
|
||||
{
|
||||
return this.mimeType;
|
||||
}
|
||||
@Override
|
||||
public String getEncoding()
|
||||
{
|
||||
return this.encoding;
|
||||
}
|
||||
@Override
|
||||
public long getLength()
|
||||
{
|
||||
return this.length;
|
||||
}
|
||||
@Override
|
||||
public Locale getLocale()
|
||||
{
|
||||
return this.locale;
|
||||
}
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Basic implementation of information about the returned content.
|
||||
*/
|
||||
public class ContentInfoImpl implements ContentInfo
|
||||
{
|
||||
private final String mimeType;
|
||||
private final String encoding;
|
||||
private final long length;
|
||||
private final Locale locale;
|
||||
|
||||
public ContentInfoImpl(String mimeType, String encoding, long length, Locale locale)
|
||||
{
|
||||
super();
|
||||
this.mimeType = mimeType;
|
||||
this.encoding = encoding;
|
||||
this.length = length;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMimeType()
|
||||
{
|
||||
return this.mimeType;
|
||||
}
|
||||
@Override
|
||||
public String getEncoding()
|
||||
{
|
||||
return this.encoding;
|
||||
}
|
||||
@Override
|
||||
public long getLength()
|
||||
{
|
||||
return this.length;
|
||||
}
|
||||
@Override
|
||||
public Locale getLocale()
|
||||
{
|
||||
return this.locale;
|
||||
}
|
||||
}
|
||||
|
@@ -1,48 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* A binary resource based on a File.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class FileBinaryResource extends AbstractBinaryResource
|
||||
{
|
||||
final File file;
|
||||
|
||||
public FileBinaryResource(File file)
|
||||
{
|
||||
this(file, null);
|
||||
}
|
||||
|
||||
public FileBinaryResource(File file, String attachFileName)
|
||||
{
|
||||
super(attachFileName, null);
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public File getFile()
|
||||
{
|
||||
return this.file;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* A binary resource based on a File.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class FileBinaryResource extends AbstractBinaryResource
|
||||
{
|
||||
final File file;
|
||||
|
||||
public FileBinaryResource(File file)
|
||||
{
|
||||
this(file, null);
|
||||
}
|
||||
|
||||
public FileBinaryResource(File file, String attachFileName)
|
||||
{
|
||||
super(attachFileName, null);
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public File getFile()
|
||||
{
|
||||
return this.file;
|
||||
}
|
||||
}
|
||||
|
@@ -1,63 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* A binary resource based on a Node reference.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class NodeBinaryResource extends AbstractBinaryResource
|
||||
{
|
||||
|
||||
final NodeRef nodeRef;
|
||||
final QName propertyQName;
|
||||
final ContentInfo contentInfo;
|
||||
|
||||
public NodeBinaryResource(NodeRef nodeRef, QName propertyQName, ContentInfo contentInfo, String attachFileName)
|
||||
{
|
||||
this(nodeRef, propertyQName, contentInfo, attachFileName, null);
|
||||
}
|
||||
|
||||
public NodeBinaryResource(NodeRef nodeRef, QName propertyQName, ContentInfo contentInfo, String attachFileName, CacheDirective cacheDirective)
|
||||
{
|
||||
super(attachFileName, cacheDirective);
|
||||
this.nodeRef = nodeRef;
|
||||
this.propertyQName = propertyQName;
|
||||
this.contentInfo = contentInfo;
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return this.nodeRef;
|
||||
}
|
||||
|
||||
public QName getPropertyQName()
|
||||
{
|
||||
return this.propertyQName;
|
||||
}
|
||||
|
||||
public ContentInfo getContentInfo()
|
||||
{
|
||||
return this.contentInfo;
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.rest.framework.resource.content;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* A binary resource based on a Node reference.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class NodeBinaryResource extends AbstractBinaryResource
|
||||
{
|
||||
|
||||
final NodeRef nodeRef;
|
||||
final QName propertyQName;
|
||||
final ContentInfo contentInfo;
|
||||
|
||||
public NodeBinaryResource(NodeRef nodeRef, QName propertyQName, ContentInfo contentInfo, String attachFileName)
|
||||
{
|
||||
this(nodeRef, propertyQName, contentInfo, attachFileName, null);
|
||||
}
|
||||
|
||||
public NodeBinaryResource(NodeRef nodeRef, QName propertyQName, ContentInfo contentInfo, String attachFileName, CacheDirective cacheDirective)
|
||||
{
|
||||
super(attachFileName, cacheDirective);
|
||||
this.nodeRef = nodeRef;
|
||||
this.propertyQName = propertyQName;
|
||||
this.contentInfo = contentInfo;
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return this.nodeRef;
|
||||
}
|
||||
|
||||
public QName getPropertyQName()
|
||||
{
|
||||
return this.propertyQName;
|
||||
}
|
||||
|
||||
public ContentInfo getContentInfo()
|
||||
{
|
||||
return this.contentInfo;
|
||||
}
|
||||
}
|
@@ -1,20 +1,20 @@
|
||||
package org.alfresco.rest.framework.resource.parameters;
|
||||
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Thrown when an invalid select syntax is used.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class InvalidSelectException extends InvalidArgumentException
|
||||
{
|
||||
private static final long serialVersionUID = -8631890798598434965L;
|
||||
|
||||
public static String DEFAULT_MESSAGE_ID = "framework.exception.InvalidSelect";
|
||||
|
||||
public InvalidSelectException(String paramName, Object queryParam)
|
||||
{
|
||||
super(DEFAULT_MESSAGE_ID, new Object[] {queryParam, paramName});
|
||||
}
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.parameters;
|
||||
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Thrown when an invalid select syntax is used.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class InvalidSelectException extends InvalidArgumentException
|
||||
{
|
||||
private static final long serialVersionUID = -8631890798598434965L;
|
||||
|
||||
public static String DEFAULT_MESSAGE_ID = "framework.exception.InvalidSelect";
|
||||
|
||||
public InvalidSelectException(String paramName, Object queryParam)
|
||||
{
|
||||
super(DEFAULT_MESSAGE_ID, new Object[] {queryParam, paramName});
|
||||
}
|
||||
}
|
||||
|
@@ -1,31 +1,31 @@
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Thrown when an invalid query syntax is used.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class InvalidQueryException extends InvalidArgumentException
|
||||
{
|
||||
private static final long serialVersionUID = 8825573452685077660L;
|
||||
public static String DEFAULT_MESSAGE_ID = "framework.exception.InvalidQuery";
|
||||
private Object queryParam;
|
||||
|
||||
public InvalidQueryException() {
|
||||
super(DEFAULT_MESSAGE_ID);
|
||||
}
|
||||
|
||||
public InvalidQueryException(Object queryParam)
|
||||
{
|
||||
super(DEFAULT_MESSAGE_ID, new Object[] {queryParam});
|
||||
this.queryParam = queryParam;
|
||||
}
|
||||
|
||||
public Object getQueryParam()
|
||||
{
|
||||
return queryParam;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Thrown when an invalid query syntax is used.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class InvalidQueryException extends InvalidArgumentException
|
||||
{
|
||||
private static final long serialVersionUID = 8825573452685077660L;
|
||||
public static String DEFAULT_MESSAGE_ID = "framework.exception.InvalidQuery";
|
||||
private Object queryParam;
|
||||
|
||||
public InvalidQueryException() {
|
||||
super(DEFAULT_MESSAGE_ID);
|
||||
}
|
||||
|
||||
public InvalidQueryException(Object queryParam)
|
||||
{
|
||||
super(DEFAULT_MESSAGE_ID, new Object[] {queryParam});
|
||||
this.queryParam = queryParam;
|
||||
}
|
||||
|
||||
public Object getQueryParam()
|
||||
{
|
||||
return queryParam;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,18 +1,18 @@
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
|
||||
/**
|
||||
* Represents a Query defined by a WHERE clause, passed in as a parameter in a GET call to the Rest api.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public interface Query
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the list of operations
|
||||
*/
|
||||
CommonTree getTree();
|
||||
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
|
||||
/**
|
||||
* Represents a Query defined by a WHERE clause, passed in as a parameter in a GET call to the Rest api.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public interface Query
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the list of operations
|
||||
*/
|
||||
CommonTree getTree();
|
||||
|
||||
}
|
||||
|
@@ -1,264 +1,264 @@
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.antlr.WhereClauseParser;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
import org.antlr.runtime.tree.Tree;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides helper methods for handling a WHERE query.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public abstract class QueryHelper
|
||||
{
|
||||
/**
|
||||
* An interface used when walking a query tree. Calls are made to methods when the particular clause is encountered.
|
||||
*/
|
||||
public static interface WalkerCallback
|
||||
{
|
||||
/**
|
||||
* Called any time an EXISTS clause is encountered.
|
||||
* @param propertyName Name of the property
|
||||
* @param negated returns true if "NOT EXISTS" was used
|
||||
*/
|
||||
void exists(String propertyName, boolean negated);
|
||||
|
||||
/**
|
||||
* Called any time a BETWEEN clause is encountered.
|
||||
* @param propertyName Name of the property
|
||||
* @param firstValue String
|
||||
* @param secondValue String
|
||||
* @param negated returns true if "NOT BETWEEN" was used
|
||||
*/
|
||||
void between(String propertyName, String firstValue, String secondValue, boolean negated);
|
||||
|
||||
/**
|
||||
* One of EQUALS LESSTHAN GREATERTHAN LESSTHANOREQUALS GREATERTHANOREQUALS;
|
||||
*/
|
||||
void comparison(int type, String propertyName, String propertyValue);
|
||||
|
||||
/**
|
||||
* Called any time an IN clause is encountered.
|
||||
* @param property Name of the property
|
||||
* @param negated returns true if "NOT IN" was used
|
||||
* @param propertyValues the property values
|
||||
*/
|
||||
void in(String property, boolean negated, String... propertyValues);
|
||||
|
||||
|
||||
/**
|
||||
* Called any time a MATCHES clause is encountered.
|
||||
* @param property Name of the property
|
||||
* @param propertyValue String
|
||||
* @param negated returns true if "NOT MATCHES" was used
|
||||
*/
|
||||
void matches(String property, String propertyValue, boolean negated);
|
||||
|
||||
/**
|
||||
* Called any time an AND is encountered.
|
||||
*/
|
||||
void and();
|
||||
/**
|
||||
* Called any time an OR is encountered.
|
||||
*/
|
||||
void or();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation. Override the methods you are interested in. If you don't
|
||||
* override the methods then an InvalidQueryException will be thrown.
|
||||
*/
|
||||
private static final String UNSUPPORTED_TEXT = "Unsupported Predicate";
|
||||
private static final InvalidQueryException UNSUPPORTED = new InvalidQueryException(UNSUPPORTED_TEXT);
|
||||
|
||||
public static class WalkerCallbackAdapter implements WalkerCallback
|
||||
{
|
||||
@Override
|
||||
public void exists(String propertyName, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void between(String propertyName, String firstValue, String secondValue, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void comparison(int type, String propertyName, String propertyValue) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void in(String propertyName, boolean negated, String... propertyValues) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void matches(String property, String value, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void and() {throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void or() {throw UNSUPPORTED;}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks a query with a callback for each operation
|
||||
* @param query the query
|
||||
* @param callback a callback
|
||||
*/
|
||||
public static void walk(Query query, WalkerCallback callback)
|
||||
{
|
||||
|
||||
CommonTree tree = query.getTree();
|
||||
if (tree != null)
|
||||
{
|
||||
LinkedList<Tree> stack = new LinkedList<Tree>();
|
||||
stack.push(tree);
|
||||
callbackTree(tree, callback, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a tree type and calls the corresponding callback method.
|
||||
* @param tree Tree
|
||||
* @param callback WalkerCallback
|
||||
* @param negated boolean
|
||||
*/
|
||||
protected static void callbackTree(Tree tree, WalkerCallback callback, boolean negated)
|
||||
{
|
||||
if (tree != null)
|
||||
{
|
||||
switch (tree.getType()) {
|
||||
case WhereClauseParser.EXISTS:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
callback.exists(tree.getChild(0).getText(), negated);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.MATCHES:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
callback.matches(tree.getChild(0).getText(), stripQuotes(tree.getChild(1).getText()), negated);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.IN:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
List<Tree> children = getChildren(tree);
|
||||
//Don't need the first item because its the property name
|
||||
String[] inVals = new String[children.size()-1];
|
||||
for (int i = 1; i < children.size(); i++) {
|
||||
inVals[i-1] = stripQuotes(children.get(i).getText());
|
||||
}
|
||||
callback.in(tree.getChild(0).getText(), negated, inVals);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.BETWEEN:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
callback.between(tree.getChild(0).getText(), stripQuotes(tree.getChild(1).getText()), stripQuotes(tree.getChild(2).getText()), negated);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.EQUALS: //fall through (comparison)
|
||||
case WhereClauseParser.LESSTHAN: //fall through (comparison)
|
||||
case WhereClauseParser.GREATERTHAN: //fall through (comparison)
|
||||
case WhereClauseParser.LESSTHANOREQUALS: //fall through (comparison)
|
||||
case WhereClauseParser.GREATERTHANOREQUALS:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType() &&
|
||||
WhereClauseParser.PROPERTYVALUE == tree.getChild(1).getType())
|
||||
{
|
||||
callback.comparison(tree.getType(), tree.getChild(0).getText(), stripQuotes(tree.getChild(1).getText()));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.NEGATION:
|
||||
//Negate the next element
|
||||
callbackTree(tree.getChild(0), callback, true);
|
||||
return;
|
||||
case WhereClauseParser.OR:
|
||||
callback.or();
|
||||
List<Tree> children = getChildren(tree);
|
||||
for (Tree child : children) {
|
||||
callbackTree(child, callback, negated);
|
||||
}
|
||||
return;
|
||||
case WhereClauseParser.AND:
|
||||
callback.and();
|
||||
List<Tree> childrenOfAnd = getChildren(tree);
|
||||
for (Tree child : childrenOfAnd) {
|
||||
callbackTree(child, callback, negated);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
}
|
||||
callbackTree(tree.getChild(0), callback, negated); //Callback on the next node
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the siblings of the current tree item (does not include the current item)
|
||||
* that are after it in the tree (but at the same level).
|
||||
* @param tree the current tree
|
||||
* @return siblings - all the elements at the same level in the tree
|
||||
*/
|
||||
// public static List<Tree> getYoungerSiblings(Tree tree)
|
||||
// {
|
||||
// Tree parent = tree.getParent();
|
||||
//
|
||||
// if (parent!=null && parent.getChildCount() > 0)
|
||||
// {
|
||||
// List<Tree> sibs = new ArrayList<Tree>(parent.getChildCount()-1);
|
||||
// boolean laterChildren = false;
|
||||
// for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
// Tree child = parent.getChild(i);
|
||||
// if (tree.equals(child))
|
||||
// {
|
||||
// laterChildren = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (laterChildren) sibs.add(child);
|
||||
// }
|
||||
// }
|
||||
// return sibs;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* Gets the children as a List
|
||||
* @param tree Tree
|
||||
* @return either emptyList or the children.
|
||||
*/
|
||||
public static List<Tree> getChildren(Tree tree)
|
||||
{
|
||||
if (tree!=null && tree.getChildCount() > 0)
|
||||
{
|
||||
List<Tree> children = new ArrayList<Tree>(tree.getChildCount());
|
||||
for (int i = 0; i < tree.getChildCount(); i++) {
|
||||
Tree child = tree.getChild(i);
|
||||
children.add(child);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
//Default
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static final String SINGLE_QUOTE = "'";
|
||||
|
||||
/**
|
||||
* Strips off any leading or trailing single quotes.
|
||||
* @param toBeStripped String
|
||||
* @return the String that has been stripped
|
||||
*/
|
||||
public static String stripQuotes(String toBeStripped)
|
||||
{
|
||||
if (StringUtils.isNotEmpty(toBeStripped) && toBeStripped.startsWith(SINGLE_QUOTE) && toBeStripped.endsWith(SINGLE_QUOTE))
|
||||
{
|
||||
return toBeStripped.substring(1,toBeStripped.length()-1);
|
||||
}
|
||||
return toBeStripped; //default to return the String unchanged.
|
||||
}
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.antlr.WhereClauseParser;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
import org.antlr.runtime.tree.Tree;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides helper methods for handling a WHERE query.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public abstract class QueryHelper
|
||||
{
|
||||
/**
|
||||
* An interface used when walking a query tree. Calls are made to methods when the particular clause is encountered.
|
||||
*/
|
||||
public static interface WalkerCallback
|
||||
{
|
||||
/**
|
||||
* Called any time an EXISTS clause is encountered.
|
||||
* @param propertyName Name of the property
|
||||
* @param negated returns true if "NOT EXISTS" was used
|
||||
*/
|
||||
void exists(String propertyName, boolean negated);
|
||||
|
||||
/**
|
||||
* Called any time a BETWEEN clause is encountered.
|
||||
* @param propertyName Name of the property
|
||||
* @param firstValue String
|
||||
* @param secondValue String
|
||||
* @param negated returns true if "NOT BETWEEN" was used
|
||||
*/
|
||||
void between(String propertyName, String firstValue, String secondValue, boolean negated);
|
||||
|
||||
/**
|
||||
* One of EQUALS LESSTHAN GREATERTHAN LESSTHANOREQUALS GREATERTHANOREQUALS;
|
||||
*/
|
||||
void comparison(int type, String propertyName, String propertyValue);
|
||||
|
||||
/**
|
||||
* Called any time an IN clause is encountered.
|
||||
* @param property Name of the property
|
||||
* @param negated returns true if "NOT IN" was used
|
||||
* @param propertyValues the property values
|
||||
*/
|
||||
void in(String property, boolean negated, String... propertyValues);
|
||||
|
||||
|
||||
/**
|
||||
* Called any time a MATCHES clause is encountered.
|
||||
* @param property Name of the property
|
||||
* @param propertyValue String
|
||||
* @param negated returns true if "NOT MATCHES" was used
|
||||
*/
|
||||
void matches(String property, String propertyValue, boolean negated);
|
||||
|
||||
/**
|
||||
* Called any time an AND is encountered.
|
||||
*/
|
||||
void and();
|
||||
/**
|
||||
* Called any time an OR is encountered.
|
||||
*/
|
||||
void or();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation. Override the methods you are interested in. If you don't
|
||||
* override the methods then an InvalidQueryException will be thrown.
|
||||
*/
|
||||
private static final String UNSUPPORTED_TEXT = "Unsupported Predicate";
|
||||
private static final InvalidQueryException UNSUPPORTED = new InvalidQueryException(UNSUPPORTED_TEXT);
|
||||
|
||||
public static class WalkerCallbackAdapter implements WalkerCallback
|
||||
{
|
||||
@Override
|
||||
public void exists(String propertyName, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void between(String propertyName, String firstValue, String secondValue, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void comparison(int type, String propertyName, String propertyValue) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void in(String propertyName, boolean negated, String... propertyValues) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void matches(String property, String value, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void and() {throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void or() {throw UNSUPPORTED;}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks a query with a callback for each operation
|
||||
* @param query the query
|
||||
* @param callback a callback
|
||||
*/
|
||||
public static void walk(Query query, WalkerCallback callback)
|
||||
{
|
||||
|
||||
CommonTree tree = query.getTree();
|
||||
if (tree != null)
|
||||
{
|
||||
LinkedList<Tree> stack = new LinkedList<Tree>();
|
||||
stack.push(tree);
|
||||
callbackTree(tree, callback, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a tree type and calls the corresponding callback method.
|
||||
* @param tree Tree
|
||||
* @param callback WalkerCallback
|
||||
* @param negated boolean
|
||||
*/
|
||||
protected static void callbackTree(Tree tree, WalkerCallback callback, boolean negated)
|
||||
{
|
||||
if (tree != null)
|
||||
{
|
||||
switch (tree.getType()) {
|
||||
case WhereClauseParser.EXISTS:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
callback.exists(tree.getChild(0).getText(), negated);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.MATCHES:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
callback.matches(tree.getChild(0).getText(), stripQuotes(tree.getChild(1).getText()), negated);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.IN:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
List<Tree> children = getChildren(tree);
|
||||
//Don't need the first item because its the property name
|
||||
String[] inVals = new String[children.size()-1];
|
||||
for (int i = 1; i < children.size(); i++) {
|
||||
inVals[i-1] = stripQuotes(children.get(i).getText());
|
||||
}
|
||||
callback.in(tree.getChild(0).getText(), negated, inVals);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.BETWEEN:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
callback.between(tree.getChild(0).getText(), stripQuotes(tree.getChild(1).getText()), stripQuotes(tree.getChild(2).getText()), negated);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.EQUALS: //fall through (comparison)
|
||||
case WhereClauseParser.LESSTHAN: //fall through (comparison)
|
||||
case WhereClauseParser.GREATERTHAN: //fall through (comparison)
|
||||
case WhereClauseParser.LESSTHANOREQUALS: //fall through (comparison)
|
||||
case WhereClauseParser.GREATERTHANOREQUALS:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType() &&
|
||||
WhereClauseParser.PROPERTYVALUE == tree.getChild(1).getType())
|
||||
{
|
||||
callback.comparison(tree.getType(), tree.getChild(0).getText(), stripQuotes(tree.getChild(1).getText()));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WhereClauseParser.NEGATION:
|
||||
//Negate the next element
|
||||
callbackTree(tree.getChild(0), callback, true);
|
||||
return;
|
||||
case WhereClauseParser.OR:
|
||||
callback.or();
|
||||
List<Tree> children = getChildren(tree);
|
||||
for (Tree child : children) {
|
||||
callbackTree(child, callback, negated);
|
||||
}
|
||||
return;
|
||||
case WhereClauseParser.AND:
|
||||
callback.and();
|
||||
List<Tree> childrenOfAnd = getChildren(tree);
|
||||
for (Tree child : childrenOfAnd) {
|
||||
callbackTree(child, callback, negated);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
}
|
||||
callbackTree(tree.getChild(0), callback, negated); //Callback on the next node
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the siblings of the current tree item (does not include the current item)
|
||||
* that are after it in the tree (but at the same level).
|
||||
* @param tree the current tree
|
||||
* @return siblings - all the elements at the same level in the tree
|
||||
*/
|
||||
// public static List<Tree> getYoungerSiblings(Tree tree)
|
||||
// {
|
||||
// Tree parent = tree.getParent();
|
||||
//
|
||||
// if (parent!=null && parent.getChildCount() > 0)
|
||||
// {
|
||||
// List<Tree> sibs = new ArrayList<Tree>(parent.getChildCount()-1);
|
||||
// boolean laterChildren = false;
|
||||
// for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
// Tree child = parent.getChild(i);
|
||||
// if (tree.equals(child))
|
||||
// {
|
||||
// laterChildren = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (laterChildren) sibs.add(child);
|
||||
// }
|
||||
// }
|
||||
// return sibs;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* Gets the children as a List
|
||||
* @param tree Tree
|
||||
* @return either emptyList or the children.
|
||||
*/
|
||||
public static List<Tree> getChildren(Tree tree)
|
||||
{
|
||||
if (tree!=null && tree.getChildCount() > 0)
|
||||
{
|
||||
List<Tree> children = new ArrayList<Tree>(tree.getChildCount());
|
||||
for (int i = 0; i < tree.getChildCount(); i++) {
|
||||
Tree child = tree.getChild(i);
|
||||
children.add(child);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
//Default
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static final String SINGLE_QUOTE = "'";
|
||||
|
||||
/**
|
||||
* Strips off any leading or trailing single quotes.
|
||||
* @param toBeStripped String
|
||||
* @return the String that has been stripped
|
||||
*/
|
||||
public static String stripQuotes(String toBeStripped)
|
||||
{
|
||||
if (StringUtils.isNotEmpty(toBeStripped) && toBeStripped.startsWith(SINGLE_QUOTE) && toBeStripped.endsWith(SINGLE_QUOTE))
|
||||
{
|
||||
return toBeStripped.substring(1,toBeStripped.length()-1);
|
||||
}
|
||||
return toBeStripped; //default to return the String unchanged.
|
||||
}
|
||||
}
|
||||
|
@@ -1,35 +1,35 @@
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
|
||||
/**
|
||||
* Represents a Query defined by a WHERE clause, passed in as a parameter in a GET call to the Rest api.
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class QueryImpl implements Query
|
||||
{
|
||||
public static final Query EMPTY = new QueryImpl();
|
||||
private final CommonTree tree;
|
||||
|
||||
private QueryImpl()
|
||||
{
|
||||
super();
|
||||
this.tree = null;
|
||||
}
|
||||
|
||||
public QueryImpl(CommonTree tree) {
|
||||
super();
|
||||
this.tree = tree;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonTree getTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueryImpl [tree=" + tree + "]";
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
|
||||
/**
|
||||
* Represents a Query defined by a WHERE clause, passed in as a parameter in a GET call to the Rest api.
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class QueryImpl implements Query
|
||||
{
|
||||
public static final Query EMPTY = new QueryImpl();
|
||||
private final CommonTree tree;
|
||||
|
||||
private QueryImpl()
|
||||
{
|
||||
super();
|
||||
this.tree = null;
|
||||
}
|
||||
|
||||
public QueryImpl(CommonTree tree) {
|
||||
super();
|
||||
this.tree = tree;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonTree getTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueryImpl [tree=" + tree + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user