mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged searchapi (5.2.1) to 5.2.N (5.2.1)
129774 gjames: SEARCH-113: Moving more api logic to helper classes, using a "trait" style git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@130165 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -37,6 +37,7 @@ import org.alfresco.rest.framework.core.exceptions.ApiException;
|
||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||
import org.alfresco.rest.framework.jacksonextensions.JacksonHelper.Writer;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.alfresco.rest.framework.webscripts.ApiWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
import org.codehaus.jackson.JsonGenerationException;
|
||||
@@ -48,7 +49,7 @@ import org.springframework.extensions.webscripts.WebScriptException;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||
|
||||
public class NetworkWebScriptGet extends ApiWebScript
|
||||
public class NetworkWebScriptGet extends ApiWebScript implements ResponseWriter
|
||||
{
|
||||
private Networks networks;
|
||||
private ResourceWebScriptHelper helper;
|
||||
@@ -108,11 +109,11 @@ public class NetworkWebScriptGet extends ApiWebScript
|
||||
}
|
||||
catch (ApiException | WebScriptException apiException)
|
||||
{
|
||||
assistant.renderException(apiException, res);
|
||||
renderException(apiException, res, assistant);
|
||||
}
|
||||
catch (RuntimeException runtimeException)
|
||||
{
|
||||
assistant.renderException(runtimeException, res);
|
||||
renderException(runtimeException, res, assistant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -39,6 +39,8 @@ import org.alfresco.rest.framework.jacksonextensions.JacksonHelper.Writer;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Paging;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.alfresco.rest.framework.webscripts.ApiWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
import org.codehaus.jackson.JsonGenerationException;
|
||||
@@ -56,7 +58,7 @@ import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||
* @author steveglover
|
||||
*
|
||||
*/
|
||||
public class NetworksWebScriptGet extends ApiWebScript
|
||||
public class NetworksWebScriptGet extends ApiWebScript implements RecognizedParamsExtractor, ResponseWriter
|
||||
{
|
||||
private Networks networks;
|
||||
private ResourceWebScriptHelper helper;
|
||||
@@ -82,7 +84,7 @@ public class NetworksWebScriptGet extends ApiWebScript
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
final Paging paging = ResourceWebScriptHelper.findPaging(req);
|
||||
final Paging paging = findPaging(req);
|
||||
|
||||
// apply content type
|
||||
res.setContentType(Format.JSON.mimetype() + ";charset=UTF-8");
|
||||
@@ -116,11 +118,11 @@ public class NetworksWebScriptGet extends ApiWebScript
|
||||
}
|
||||
catch (ApiException | WebScriptException apiException)
|
||||
{
|
||||
assistant.renderException(apiException, res);
|
||||
renderException(apiException, res, assistant);
|
||||
}
|
||||
catch (RuntimeException runtimeException)
|
||||
{
|
||||
assistant.renderException(runtimeException, res);
|
||||
renderException(runtimeException, res, assistant);
|
||||
}
|
||||
}
|
||||
}
|
@@ -33,12 +33,13 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.repo.web.scripts.TenantWebScriptServletRuntime;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.springframework.extensions.config.ServerProperties;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.extensions.webscripts.*;
|
||||
import org.springframework.extensions.webscripts.servlet.ServletAuthenticatorFactory;
|
||||
|
||||
public class PublicApiTenantWebScriptServletRuntime extends TenantWebScriptServletRuntime
|
||||
public class PublicApiTenantWebScriptServletRuntime extends TenantWebScriptServletRuntime implements ResponseWriter
|
||||
{
|
||||
private static final Pattern CMIS_URI_PATTERN = Pattern.compile(".*/cmis/versions/[0-9]+\\.[0-9]+/.*");
|
||||
private ApiAssistant apiAssistant;
|
||||
@@ -142,7 +143,7 @@ public class PublicApiTenantWebScriptServletRuntime extends TenantWebScriptServl
|
||||
else
|
||||
{
|
||||
try {
|
||||
apiAssistant.renderException((Exception)exception, response);
|
||||
renderException((Exception)exception, response, apiAssistant);
|
||||
} catch (IOException e) {
|
||||
logger.error("Internal error", e);
|
||||
throw new WebScriptException("Internal error", e);
|
||||
|
@@ -32,6 +32,7 @@ import org.alfresco.rest.api.model.Person;
|
||||
import org.alfresco.rest.api.model.Site;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
|
||||
/**
|
||||
@@ -44,9 +45,9 @@ public interface Queries
|
||||
{
|
||||
// General
|
||||
static String PARAM_TERM = "term";
|
||||
static String PARAM_ORDERBY = ResourceWebScriptHelper.PARAM_ORDERBY;
|
||||
static String PARAM_FIELDS = ResourceWebScriptHelper.PARAM_FILTER_FIELDS;
|
||||
static String PARAM_INCLUDE = ResourceWebScriptHelper.PARAM_INCLUDE;
|
||||
static String PARAM_ORDERBY = RecognizedParamsExtractor.PARAM_ORDERBY;
|
||||
static String PARAM_FIELDS = RecognizedParamsExtractor.PARAM_FILTER_FIELDS;
|
||||
static String PARAM_INCLUDE = RecognizedParamsExtractor.PARAM_INCLUDE;
|
||||
|
||||
// Node query
|
||||
static String PARAM_ROOT_NODE_ID = "rootNodeId";
|
||||
|
@@ -57,7 +57,7 @@ import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.Query;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
@@ -107,7 +107,7 @@ import java.util.Set;
|
||||
*
|
||||
* @since publicapi1.0
|
||||
*/
|
||||
public class QuickShareLinksImpl implements QuickShareLinks, InitializingBean
|
||||
public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExtractor, InitializingBean
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(QuickShareLinksImpl.class);
|
||||
|
||||
@@ -404,7 +404,7 @@ public class QuickShareLinksImpl implements QuickShareLinks, InitializingBean
|
||||
|
||||
// hmm ... can we simplify ?
|
||||
String filterStatusCreated = "(" + Renditions.PARAM_STATUS + "='" + Rendition.RenditionStatus.CREATED + "')";
|
||||
Query whereQuery = ResourceWebScriptHelper.getWhereClause(filterStatusCreated);
|
||||
Query whereQuery = getWhereClause(filterStatusCreated);
|
||||
Params.RecognizedParams recParams = new Params.RecognizedParams(null, null, null, null, null, null, whereQuery, null, false);
|
||||
Parameters params = Params.valueOf(recParams, null, null, null);
|
||||
|
||||
|
@@ -29,6 +29,7 @@ import java.io.IOException;
|
||||
|
||||
import org.alfresco.rest.framework.resource.SerializablePagedCollection;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
import org.codehaus.jackson.JsonGenerationException;
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
@@ -90,8 +91,8 @@ public class SerializerOfCollectionWithPaging extends SerializerBase<Serializabl
|
||||
}
|
||||
if (pagedCol.getPaging() != null)
|
||||
{
|
||||
jgen.writeNumberField(ResourceWebScriptHelper.PARAM_PAGING_SKIP, pagedCol.getPaging().getSkipCount());
|
||||
jgen.writeNumberField(ResourceWebScriptHelper.PARAM_PAGING_MAX, pagedCol.getPaging().getMaxItems());
|
||||
jgen.writeNumberField(RecognizedParamsExtractor.PARAM_PAGING_SKIP, pagedCol.getPaging().getSkipCount());
|
||||
jgen.writeNumberField(RecognizedParamsExtractor.PARAM_PAGING_MAX, pagedCol.getPaging().getMaxItems());
|
||||
}
|
||||
jgen.writeEndObject();
|
||||
}
|
||||
|
@@ -56,34 +56,16 @@ public class ApiAssistant {
|
||||
|
||||
private static Log logger = LogFactory.getLog(ApiAssistant.class);
|
||||
|
||||
public final static String UTF8 = "UTF-8";
|
||||
public final static ContentInfo DEFAULT_JSON_CONTENT = new ContentInfoImpl(Format.JSON.mimetype(),UTF8, 0, null);
|
||||
public final static Cache CACHE_NEVER = new Cache(new RequiredCache()
|
||||
{
|
||||
@Override
|
||||
public boolean getNeverCache()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIsPublic()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMustRevalidate()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
private ExceptionResolver<Exception> defaultResolver = new DefaultExceptionResolver();
|
||||
private ExceptionResolver<WebScriptException> webScriptExceptionResolver;
|
||||
private ExceptionResolver<Exception> resolver;
|
||||
private JacksonHelper jsonHelper;
|
||||
|
||||
/**
|
||||
* Determines the api being used from the templateVars
|
||||
* @param templateVars
|
||||
* @return Api
|
||||
*/
|
||||
public static Api determineApi(Map<String, String> templateVars)
|
||||
{
|
||||
String apiScope = templateVars.get("apiScope");
|
||||
@@ -92,6 +74,11 @@ public class ApiAssistant {
|
||||
return Api.valueOf(apiName,apiScope,apiVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves an exception as a json error.
|
||||
* @param exception
|
||||
* @return ErrorResponse
|
||||
*/
|
||||
public ErrorResponse resolveException(Exception ex)
|
||||
{
|
||||
ErrorResponse error = null;
|
||||
@@ -110,99 +97,6 @@ public class ApiAssistant {
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the response headers with any information we know about the content
|
||||
* @param res WebScriptResponse
|
||||
* @param contentInfo Content Information
|
||||
*/
|
||||
public void setContentInfoOnResponse(WebScriptResponse res, ContentInfo contentInfo)
|
||||
{
|
||||
if (contentInfo != null)
|
||||
{
|
||||
//Set content info on the response
|
||||
res.setContentType(contentInfo.getMimeType());
|
||||
res.setContentEncoding(contentInfo.getEncoding());
|
||||
|
||||
if (res instanceof WrappingWebScriptResponse)
|
||||
{
|
||||
WrappingWebScriptResponse wrappedRes = ((WrappingWebScriptResponse) res);
|
||||
res = wrappedRes.getNext();
|
||||
}
|
||||
|
||||
if (res instanceof WebScriptServletResponse)
|
||||
{
|
||||
WebScriptServletResponse servletResponse = (WebScriptServletResponse) res;
|
||||
if (contentInfo.getLength() > 0)
|
||||
{
|
||||
if (contentInfo.getLength() > 0 && contentInfo.getLength() < Integer.MAX_VALUE)
|
||||
{
|
||||
servletResponse.getHttpServletResponse().setContentLength((int) contentInfo.getLength());
|
||||
}
|
||||
}
|
||||
if (contentInfo.getLocale() != null)
|
||||
{
|
||||
servletResponse.getHttpServletResponse().setLocale(contentInfo.getLocale());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an exception to the output stream as Json.
|
||||
* @param exception
|
||||
* @param response
|
||||
* @throws IOException
|
||||
*/
|
||||
public void renderException(Exception exception, final WebScriptResponse response) throws IOException {
|
||||
renderErrorResponse(resolveException(exception), response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a JSON error response
|
||||
* @param errorResponse The error
|
||||
* @param res web script response
|
||||
* @throws IOException
|
||||
*/
|
||||
public void renderErrorResponse(ErrorResponse errorResponse, final WebScriptResponse res) throws IOException {
|
||||
|
||||
String logId = "";
|
||||
|
||||
if (Status.STATUS_INTERNAL_SERVER_ERROR == errorResponse.getStatusCode() || logger.isDebugEnabled())
|
||||
{
|
||||
logId = org.alfresco.util.GUID.generate();
|
||||
logger.error(logId+" : "+errorResponse.getStackTrace());
|
||||
}
|
||||
|
||||
String stackMessage = I18NUtil.getMessage(DefaultExceptionResolver.STACK_MESSAGE_ID);
|
||||
|
||||
final ErrorResponse errorToWrite = new ErrorResponse(errorResponse.getErrorKey(),
|
||||
errorResponse.getStatusCode(),
|
||||
errorResponse.getBriefSummary(),
|
||||
stackMessage,
|
||||
logId,
|
||||
errorResponse.getAdditionalState(),
|
||||
DefaultExceptionResolver.ERROR_URL);
|
||||
|
||||
setContentInfoOnResponse(res, DEFAULT_JSON_CONTENT);
|
||||
|
||||
// Status must be set before the response is written by Jackson (which will by default close and commit the response).
|
||||
// In a r/w txn, web script buffered responses ensure that it doesn't really matter but for r/o txns this is important.
|
||||
res.setStatus(errorToWrite.getStatusCode());
|
||||
|
||||
jsonHelper.withWriter(res.getOutputStream(), new JacksonHelper.Writer()
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
|
||||
throws JsonGenerationException, JsonMappingException, IOException
|
||||
{
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("error", errorToWrite);
|
||||
objectMapper.writeValue(generator, obj);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JacksonHelper getJsonHelper() {
|
||||
return jsonHelper;
|
||||
}
|
||||
|
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* 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/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.framework.tools;
|
||||
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.jacksonextensions.BeanPropertiesFilter;
|
||||
import org.alfresco.rest.framework.resource.parameters.InvalidSelectException;
|
||||
import org.alfresco.rest.framework.resource.parameters.Paging;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.resource.parameters.SortColumn;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.InvalidQueryException;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.Query;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.QueryImpl;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.WhereCompiler;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.antlr.runtime.tree.CommonErrorNode;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
import org.antlr.runtime.tree.RewriteCardinalityException;
|
||||
import org.antlr.runtime.tree.Tree;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/*
|
||||
* Extracts recognized parameters from the HTTP request.
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public interface RecognizedParamsExtractor
|
||||
{
|
||||
public static final String PARAM_RELATIONS = "relations";
|
||||
public static final String PARAM_FILTER_FIELDS = "fields";
|
||||
|
||||
@Deprecated
|
||||
public static final String PARAM_FILTER_PROPERTIES = "properties";
|
||||
|
||||
public static final String PARAM_PAGING_SKIP = "skipCount";
|
||||
public static final String PARAM_PAGING_MAX = "maxItems";
|
||||
public static final String PARAM_ORDERBY = "orderBy";
|
||||
public static final String PARAM_WHERE = "where";
|
||||
public static final String PARAM_SELECT = "select";
|
||||
public static final String PARAM_INCLUDE = "include";
|
||||
public static final String PARAM_INCLUDE_SOURCE_ENTITY = "includeSource";
|
||||
public static final List<String> KNOWN_PARAMS = Arrays.asList(
|
||||
PARAM_RELATIONS, PARAM_FILTER_PROPERTIES, PARAM_FILTER_FIELDS,PARAM_PAGING_SKIP,PARAM_PAGING_MAX,
|
||||
PARAM_ORDERBY, PARAM_WHERE, PARAM_SELECT, PARAM_INCLUDE_SOURCE_ENTITY);
|
||||
|
||||
default Log rpeLogger() {
|
||||
return LogFactory.getLog(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the formal set of params that any rest service could potentially have passed in as request params
|
||||
* @param req WebScriptRequest
|
||||
* @return RecognizedParams a POJO containing the params for use with the Params objects
|
||||
*/
|
||||
default Params.RecognizedParams getRecognizedParams(WebScriptRequest req)
|
||||
{
|
||||
Paging paging = findPaging(req);
|
||||
List<SortColumn> sorting = getSort(req.getParameter(PARAM_ORDERBY));
|
||||
Map<String, BeanPropertiesFilter> relationFilter = getRelationFilter(req.getParameter(PARAM_RELATIONS));
|
||||
Query whereQuery = getWhereClause(req.getParameter(PARAM_WHERE));
|
||||
Map<String, String[]> requestParams = getRequestParameters(req);
|
||||
boolean includeSource = Boolean.valueOf(req.getParameter(PARAM_INCLUDE_SOURCE_ENTITY));
|
||||
|
||||
List<String> includedFields = getIncludeClause(req.getParameter(PARAM_INCLUDE));
|
||||
List<String> selectFields = getSelectClause(req.getParameter(PARAM_SELECT));
|
||||
|
||||
String fields = req.getParameter(PARAM_FILTER_FIELDS);
|
||||
String properties = req.getParameter(PARAM_FILTER_PROPERTIES);
|
||||
|
||||
if ((fields != null) && (properties != null))
|
||||
{
|
||||
if (rpeLogger().isWarnEnabled())
|
||||
{
|
||||
rpeLogger().warn("Taking 'fields' param [" + fields + "] and ignoring deprecated 'properties' param [" + properties + "]");
|
||||
}
|
||||
}
|
||||
|
||||
BeanPropertiesFilter filter = getFilter((fields != null ? fields : properties), includedFields);
|
||||
|
||||
return new Params.RecognizedParams(requestParams, paging, filter, relationFilter, includedFields, selectFields, whereQuery, sorting, includeSource);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes the web request and looks for a "fields" parameter (otherwise deprecated "properties" parameter).
|
||||
*
|
||||
* Parses the parameter and produces a list of bean properties to use as a filter A
|
||||
* SimpleBeanPropertyFilter it returned that uses the bean properties. If no
|
||||
* filter param is set then a default BeanFilter is returned that will never
|
||||
* filter fields (ie. Returns all bean properties).
|
||||
*
|
||||
* If selectList is provided then it will take precedence (ie. be included) over the fields/properties filter
|
||||
* for top-level entries (bean properties).
|
||||
*
|
||||
* For example, this will return entries from both select & properties, eg.
|
||||
*
|
||||
* select=abc,def&properties=id,name,ghi
|
||||
*
|
||||
* Note: it should be noted that API-generic "fields" clause does not currently work for sub-entries.
|
||||
*
|
||||
* Hence, even if the API-specific "select" clause allows selection of a sub-entries this cannot be used
|
||||
* with "fields" filtering. For example, an API-specific method may implement and return "abc/blah", eg.
|
||||
*
|
||||
* select=abc/blah
|
||||
*
|
||||
* However the following will not return "abc/blah" if used with fields filtering, eg.
|
||||
*
|
||||
* select=abc/blah&fields=id,name,ghi
|
||||
*
|
||||
* If fields filtering is desired then it would require "abc" to be selected and returned as a whole, eg.
|
||||
*
|
||||
* select=abc&fields=id,name,ghi
|
||||
*
|
||||
* @param filterParams
|
||||
* @param selectList
|
||||
* @return
|
||||
*/
|
||||
default BeanPropertiesFilter getFilter(String filterParams, List<String> selectList)
|
||||
{
|
||||
if (filterParams != null)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(filterParams, ",");
|
||||
Set<String> filteredProperties = new HashSet<String>(st.countTokens());
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
filteredProperties.add(st.nextToken());
|
||||
}
|
||||
|
||||
// if supplied, the select takes precedence over the filter (fields/properties) for top-level bean properties
|
||||
if (selectList != null)
|
||||
{
|
||||
for (String select : selectList)
|
||||
{
|
||||
String[] split = select.split("/");
|
||||
filteredProperties.add(split[0]);
|
||||
}
|
||||
}
|
||||
|
||||
rpeLogger().debug("Filtering using the following properties: " + filteredProperties);
|
||||
BeanPropertiesFilter filter = new BeanPropertiesFilter(filteredProperties);
|
||||
return filter;
|
||||
}
|
||||
return BeanPropertiesFilter.ALLOW_ALL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes the "select" parameter and turns it into a List<String> property names
|
||||
* @param selectParam String
|
||||
* @return bean property names potentially using JSON Pointer syntax
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Deprecated
|
||||
default List<String> getSelectClause(String selectParam) throws InvalidArgumentException
|
||||
{
|
||||
return getClause(selectParam, "SELECT");
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the "include" parameter and turns it into a List<String> property names
|
||||
* @param includeParam String
|
||||
* @return bean property names potentially using JSON Pointer syntax
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default List<String> getIncludeClause(String includeParam) throws InvalidArgumentException
|
||||
{
|
||||
return getClause(includeParam, "INCLUDE");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clause specificed in paramName
|
||||
* @param param
|
||||
* @param paramName
|
||||
* @return bean property names potentially using JSON Pointer syntax
|
||||
*/
|
||||
default List<String> getClause(String param, String paramName)
|
||||
{
|
||||
if (param == null) return Collections.emptyList();
|
||||
|
||||
try {
|
||||
CommonTree selectedPropsTree = WhereCompiler.compileSelectClause(param);
|
||||
if (selectedPropsTree instanceof CommonErrorNode)
|
||||
{
|
||||
rpeLogger().debug("Error parsing the "+paramName+" clause "+selectedPropsTree);
|
||||
throw new InvalidSelectException(paramName, selectedPropsTree);
|
||||
}
|
||||
if (selectedPropsTree.getChildCount() == 0 && !selectedPropsTree.getText().isEmpty())
|
||||
{
|
||||
return Arrays.asList(selectedPropsTree.getText());
|
||||
}
|
||||
List<Tree> children = (List<Tree>) selectedPropsTree.getChildren();
|
||||
if (children!= null && !children.isEmpty())
|
||||
{
|
||||
List<String> properties = new ArrayList<String>(children.size());
|
||||
for (Tree child : children) {
|
||||
properties.add(child.getText());
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
catch (RewriteCardinalityException re)
|
||||
{
|
||||
//Catch any error so it doesn't get thrown up the stack
|
||||
rpeLogger().debug("Unhandled Error parsing the "+paramName+" clause: "+re);
|
||||
}
|
||||
catch (RecognitionException e)
|
||||
{
|
||||
rpeLogger().debug("Error parsing the \"+paramName+\" clause: "+param);
|
||||
}
|
||||
catch (InvalidQueryException iqe)
|
||||
{
|
||||
throw new InvalidSelectException(paramName, iqe.getQueryParam());
|
||||
}
|
||||
//Default to throw out an invalid query
|
||||
throw new InvalidSelectException(paramName, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the "where" parameter and turns it into a Java Object that can be used for querying
|
||||
* @param whereParam String
|
||||
* @return Query a parsed version of the where clause, represented in Java
|
||||
*/
|
||||
default Query getWhereClause(String whereParam) throws InvalidQueryException
|
||||
{
|
||||
if (whereParam == null) return QueryImpl.EMPTY;
|
||||
|
||||
try {
|
||||
CommonTree whereTree = WhereCompiler.compileWhereClause(whereParam);
|
||||
if (whereTree instanceof CommonErrorNode)
|
||||
{
|
||||
rpeLogger().debug("Error parsing the WHERE clause "+whereTree);
|
||||
throw new InvalidQueryException(whereTree);
|
||||
}
|
||||
return new QueryImpl(whereTree);
|
||||
} catch (RewriteCardinalityException re) { //Catch any error so it doesn't get thrown up the stack
|
||||
rpeLogger().info("Unhandled Error parsing the WHERE clause: "+re);
|
||||
} catch (RecognitionException e) {
|
||||
whereParam += ", "+WhereCompiler.resolveMessage(e);
|
||||
rpeLogger().info("Error parsing the WHERE clause: "+whereParam);
|
||||
}
|
||||
//Default to throw out an invalid query
|
||||
throw new InvalidQueryException(whereParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the Sort parameter as a String and parses it into a List of SortColumn objects.
|
||||
* The format is a comma seperated list of "columnName sortDirection",
|
||||
* e.g. "name DESC, age ASC". It is not case sensitive and the sort direction is optional
|
||||
* It default to sort ASCENDING.
|
||||
* @param sortParams - String passed in on the request
|
||||
* @return - the sort columns or an empty list if the params were invalid.
|
||||
*/
|
||||
default List<SortColumn> getSort(String sortParams)
|
||||
{
|
||||
if (sortParams != null)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(sortParams, ",");
|
||||
List<SortColumn> sortedColumns = new ArrayList<SortColumn>(st.countTokens());
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String token = st.nextToken();
|
||||
StringTokenizer columnDesc = new StringTokenizer(token, " ");
|
||||
if (columnDesc.countTokens() <= 2)
|
||||
{
|
||||
String columnName = columnDesc.nextToken();
|
||||
String sortOrder = SortColumn.ASCENDING;
|
||||
if (columnDesc.hasMoreTokens())
|
||||
{
|
||||
String sortDef = columnDesc.nextToken().toUpperCase();
|
||||
if (SortColumn.ASCENDING.equals(sortDef) || SortColumn.DESCENDING.equals(sortDef))
|
||||
{
|
||||
sortOrder = sortDef;
|
||||
}
|
||||
else
|
||||
{
|
||||
rpeLogger().debug("Invalid sort order definition ("+sortDef+"). Valid values are "+SortColumn.ASCENDING+" or "+SortColumn.DESCENDING+".");
|
||||
}
|
||||
}
|
||||
sortedColumns.add(new SortColumn(columnName, SortColumn.ASCENDING.equals(sortOrder)));
|
||||
}
|
||||
// filteredProperties.add();
|
||||
}
|
||||
// logger.debug("Filtering using the following properties: " + filteredProperties);
|
||||
// BeanPropertiesFilter filter = new BeanPropertiesFilter(filteredProperties);
|
||||
return sortedColumns;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find paging setings based on the request parameters.
|
||||
*
|
||||
* @param req
|
||||
* @return Paging
|
||||
*/
|
||||
default Paging findPaging(WebScriptRequest req)
|
||||
{
|
||||
int skipped = Paging.DEFAULT_SKIP_COUNT;
|
||||
int max = Paging.DEFAULT_MAX_ITEMS;
|
||||
String skip = req.getParameter(PARAM_PAGING_SKIP);
|
||||
String maxItems = req.getParameter(PARAM_PAGING_MAX);
|
||||
|
||||
try
|
||||
{
|
||||
if (skip != null) { skipped = Integer.parseInt(skip);}
|
||||
if (maxItems != null) { max = Integer.parseInt(maxItems); }
|
||||
if (max < 0 || skipped < 0)
|
||||
{
|
||||
throw new InvalidArgumentException("Negative values not supported.");
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException error)
|
||||
{
|
||||
if (rpeLogger().isDebugEnabled())
|
||||
{
|
||||
rpeLogger().debug("Invalid paging params skip: " + skip + ",maxItems:" + maxItems);
|
||||
}
|
||||
throw new InvalidArgumentException();
|
||||
}
|
||||
|
||||
return Paging.valueOf(skipped, max);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes the web request and looks for a "fields" parameter (otherwise deprecated "properties" parameter).
|
||||
*
|
||||
* Parses the parameter and produces a list of bean properties to use as a filter A
|
||||
* SimpleBeanPropertyFilter it returned that uses the bean properties. If no
|
||||
* filter param is set then a default BeanFilter is returned that will never
|
||||
* filter fields (ie. Returns all bean properties).
|
||||
*
|
||||
* @param filterParams String
|
||||
* @return BeanPropertyFilter - if no parameter then returns a new
|
||||
* ReturnAllBeanProperties class
|
||||
*/
|
||||
default BeanPropertiesFilter getFilter(String filterParams)
|
||||
{
|
||||
return getFilter(filterParams, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the web request and looks for a "relations" parameter Parses the
|
||||
* parameter and produces a list of bean properties to use as a filter A
|
||||
* SimpleBeanPropertiesFilter it returned that uses the properties If no
|
||||
* filter param is set then a default BeanFilter is returned that will never
|
||||
* filter properties (ie. Returns all bean properties).
|
||||
*
|
||||
* @param filterParams String
|
||||
* @return BeanPropertiesFilter - if no parameter then returns a new
|
||||
* ReturnAllBeanProperties class
|
||||
*/
|
||||
default Map<String, BeanPropertiesFilter> getRelationFilter(String filterParams)
|
||||
{
|
||||
if (filterParams != null)
|
||||
{
|
||||
// Split by a comma when not in a bracket
|
||||
String[] relations = filterParams.split(",(?![^()]*+\\))");
|
||||
Map<String, BeanPropertiesFilter> filterMap = new HashMap<String, BeanPropertiesFilter>(relations.length);
|
||||
|
||||
for (String relation : relations)
|
||||
{
|
||||
int bracketLocation = relation.indexOf("(");
|
||||
if (bracketLocation != -1)
|
||||
{
|
||||
// We have properties
|
||||
String relationKey = relation.substring(0, bracketLocation);
|
||||
String props = relation.substring(bracketLocation + 1, relation.length() - 1);
|
||||
filterMap.put(relationKey, getFilter(props));
|
||||
}
|
||||
else
|
||||
{
|
||||
// no properties so just get the String
|
||||
filterMap.put(relation, getFilter(null));
|
||||
}
|
||||
}
|
||||
return filterMap;
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds all request parameters that aren't already know about (eg. not paging or filter params)
|
||||
* and returns them for use.
|
||||
*
|
||||
* @param req - the WebScriptRequest object
|
||||
* @return the request parameters
|
||||
*/
|
||||
default Map<String, String[]> getRequestParameters(WebScriptRequest req)
|
||||
{
|
||||
if (req!= null)
|
||||
{
|
||||
String[] paramNames = req.getParameterNames();
|
||||
if (paramNames!= null)
|
||||
{
|
||||
Map<String, String[]> requestParameteters = new HashMap<String, String[]>(paramNames.length);
|
||||
|
||||
for (int i = 0; i < paramNames.length; i++)
|
||||
{
|
||||
String paramName = paramNames[i];
|
||||
if (!KNOWN_PARAMS.contains(paramName))
|
||||
{
|
||||
String[] vals = req.getParameterValues(paramName);
|
||||
requestParameteters.put(paramName, vals);
|
||||
}
|
||||
}
|
||||
return requestParameteters;
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
}
|
103
source/java/org/alfresco/rest/framework/tools/RequestReader.java
Normal file
103
source/java/org/alfresco/rest/framework/tools/RequestReader.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* 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/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.framework.tools;
|
||||
|
||||
import org.alfresco.rest.framework.core.exceptions.ApiException;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.jacksonextensions.JacksonHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.codehaus.jackson.map.JsonMappingException;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* Reads information from the request
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public interface RequestReader
|
||||
{
|
||||
/**
|
||||
* Extracts the body contents from the request
|
||||
*
|
||||
* @param req the request
|
||||
* @param jsonHelper Jackson Helper
|
||||
* @param requiredType the type to return
|
||||
* @return the Object in the required type
|
||||
*/
|
||||
default <T> T extractJsonContent(WebScriptRequest req, JacksonHelper jsonHelper, Class<T> requiredType)
|
||||
{
|
||||
Reader reader;
|
||||
try
|
||||
{
|
||||
reader = req.getContent().getReader();
|
||||
return jsonHelper.construct(reader, requiredType);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
rrLogger().warn("Could not read content from HTTP request body.", e);
|
||||
throw new InvalidArgumentException("Could not read content from HTTP request body.");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ApiException("Could not read content from HTTP request body.", e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the body contents from the request as a List, the JSON can be an array or just a single value without the [] symbols
|
||||
*
|
||||
* @param req the request
|
||||
* @param jsonHelper Jackson Helper
|
||||
* @param requiredType the type to return (without the List param)
|
||||
* @return A List of "Object" as the required type
|
||||
*/
|
||||
default <T> List<T> extractJsonContentAsList(WebScriptRequest req, JacksonHelper jsonHelper, Class<T> requiredType)
|
||||
{
|
||||
Reader reader;
|
||||
try
|
||||
{
|
||||
reader = req.getContent().getReader();
|
||||
return jsonHelper.constructList(reader, requiredType);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ApiException("Could not read content from HTTP request body.", e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
default Log rrLogger() {
|
||||
return LogFactory.getLog(this.getClass());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* 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/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.framework.tools;
|
||||
|
||||
import org.alfresco.rest.framework.Api;
|
||||
import org.alfresco.rest.framework.core.exceptions.DefaultExceptionResolver;
|
||||
import org.alfresco.rest.framework.core.exceptions.ErrorResponse;
|
||||
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
|
||||
import org.alfresco.rest.framework.jacksonextensions.BeanPropertiesFilter;
|
||||
import org.alfresco.rest.framework.jacksonextensions.ExecutionResult;
|
||||
import org.alfresco.rest.framework.jacksonextensions.JacksonHelper;
|
||||
import org.alfresco.rest.framework.resource.SerializablePagedCollection;
|
||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.content.ContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.ContentInfoImpl;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.webscripts.WithResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.codehaus.jackson.JsonGenerationException;
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
import org.codehaus.jackson.map.JsonMappingException;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
import org.springframework.extensions.webscripts.*;
|
||||
import org.springframework.extensions.webscripts.servlet.WebScriptServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* Writes to the response
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public interface ResponseWriter
|
||||
{
|
||||
|
||||
String UTF8 = "UTF-8";
|
||||
ContentInfo DEFAULT_JSON_CONTENT = new ContentInfoImpl(Format.JSON.mimetype(),UTF8, 0, null);
|
||||
Cache CACHE_NEVER = new Cache(new Description.RequiredCache()
|
||||
{
|
||||
@Override
|
||||
public boolean getNeverCache()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIsPublic()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMustRevalidate()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
default Log resWriterLogger() {
|
||||
return LogFactory.getLog(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the response headers with any information we know about the content
|
||||
* @param res WebScriptResponse
|
||||
* @param contentInfo Content Information
|
||||
*/
|
||||
default void setContentInfoOnResponse(WebScriptResponse res, ContentInfo contentInfo)
|
||||
{
|
||||
if (contentInfo != null)
|
||||
{
|
||||
//Set content info on the response
|
||||
res.setContentType(contentInfo.getMimeType());
|
||||
res.setContentEncoding(contentInfo.getEncoding());
|
||||
|
||||
if (res instanceof WrappingWebScriptResponse)
|
||||
{
|
||||
WrappingWebScriptResponse wrappedRes = ((WrappingWebScriptResponse) res);
|
||||
res = wrappedRes.getNext();
|
||||
}
|
||||
|
||||
if (res instanceof WebScriptServletResponse)
|
||||
{
|
||||
WebScriptServletResponse servletResponse = (WebScriptServletResponse) res;
|
||||
if (contentInfo.getLength() > 0)
|
||||
{
|
||||
if (contentInfo.getLength() > 0 && contentInfo.getLength() < Integer.MAX_VALUE)
|
||||
{
|
||||
servletResponse.getHttpServletResponse().setContentLength((int) contentInfo.getLength());
|
||||
}
|
||||
}
|
||||
if (contentInfo.getLocale() != null)
|
||||
{
|
||||
servletResponse.getHttpServletResponse().setLocale(contentInfo.getLocale());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The response status must be set before the response is written by Jackson (which will by default close and commit the response).
|
||||
* In a r/w txn, web script buffered responses ensure that it doesn't really matter but for r/o txns this is important.
|
||||
*
|
||||
* If you set content information via the contentInfo object and ALSO the headers then "headers" will win because they are
|
||||
* set last.
|
||||
*
|
||||
* @param res
|
||||
* @param status
|
||||
* @param cache
|
||||
* @param contentInfo
|
||||
* @param headers
|
||||
*/
|
||||
default void setResponse(final WebScriptResponse res, int status, Cache cache, ContentInfo contentInfo, Map<String, List<String>> headers)
|
||||
{
|
||||
res.setStatus(status);
|
||||
if (cache != null) res.setCache(cache);
|
||||
setContentInfoOnResponse(res,contentInfo);
|
||||
if (headers != null && !headers.isEmpty())
|
||||
{
|
||||
for (Map.Entry<String, List<String>> header:headers.entrySet())
|
||||
{
|
||||
for (int i=0; i < header.getValue().size(); i++) {
|
||||
if (i==0)
|
||||
{
|
||||
//If its the first one then set the header overwriting.
|
||||
res.setHeader(header.getKey(), header.getValue().get(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
//If its not the first one than update the header
|
||||
res.addHeader(header.getKey(), header.getValue().get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the response using the WithResponse object
|
||||
* @param res
|
||||
* @param withResponse
|
||||
*/
|
||||
default void setResponse(final WebScriptResponse res, WithResponse withResponse)
|
||||
{
|
||||
setResponse(res, withResponse.getStatus(), withResponse.getCache(), withResponse.getContentInfo(), withResponse.getHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a JSON error response
|
||||
* @param errorResponse The error
|
||||
* @param res web script response
|
||||
* @throws IOException
|
||||
*/
|
||||
default void renderErrorResponse(final ErrorResponse errorResponse, final WebScriptResponse res, final JacksonHelper jsonHelper) throws IOException {
|
||||
|
||||
String logId = "";
|
||||
|
||||
if (Status.STATUS_INTERNAL_SERVER_ERROR == errorResponse.getStatusCode() || resWriterLogger().isDebugEnabled())
|
||||
{
|
||||
logId = org.alfresco.util.GUID.generate();
|
||||
resWriterLogger().error(logId+" : "+errorResponse.getStackTrace());
|
||||
}
|
||||
|
||||
String stackMessage = I18NUtil.getMessage(DefaultExceptionResolver.STACK_MESSAGE_ID);
|
||||
|
||||
final ErrorResponse errorToWrite = new ErrorResponse(errorResponse.getErrorKey(),
|
||||
errorResponse.getStatusCode(),
|
||||
errorResponse.getBriefSummary(),
|
||||
stackMessage,
|
||||
logId,
|
||||
errorResponse.getAdditionalState(),
|
||||
DefaultExceptionResolver.ERROR_URL);
|
||||
|
||||
setContentInfoOnResponse(res, DEFAULT_JSON_CONTENT);
|
||||
|
||||
// Status must be set before the response is written by Jackson (which will by default close and commit the response).
|
||||
// In a r/w txn, web script buffered responses ensure that it doesn't really matter but for r/o txns this is important.
|
||||
res.setStatus(errorToWrite.getStatusCode());
|
||||
|
||||
jsonHelper.withWriter(res.getOutputStream(), new JacksonHelper.Writer()
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
|
||||
throws JsonGenerationException, JsonMappingException, IOException
|
||||
{
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("error", errorToWrite);
|
||||
objectMapper.writeValue(generator, obj);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders an exception to the output stream as Json.
|
||||
* @param exception
|
||||
* @param response
|
||||
* @throws IOException
|
||||
*/
|
||||
default void renderException(final Exception exception, final WebScriptResponse response, final ApiAssistant assistant) throws IOException {
|
||||
renderErrorResponse(assistant.resolveException(exception), response, assistant.getJsonHelper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the result of an execution.
|
||||
*
|
||||
* @param res WebScriptResponse
|
||||
* @param toSerialize result of an execution
|
||||
* @throws IOException
|
||||
*/
|
||||
default void renderJsonResponse(final WebScriptResponse res, final Object toSerialize, final JacksonHelper jsonHelper)
|
||||
throws IOException
|
||||
{
|
||||
jsonHelper.withWriter(res.getOutputStream(), new JacksonHelper.Writer()
|
||||
{
|
||||
@Override
|
||||
public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
|
||||
throws JsonGenerationException, JsonMappingException, IOException
|
||||
{
|
||||
objectMapper.writeValue(generator, toSerialize);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -53,6 +53,7 @@ import org.alfresco.rest.framework.resource.content.FileBinaryResource;
|
||||
import org.alfresco.rest.framework.resource.content.NodeBinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -80,7 +81,7 @@ import org.springframework.http.HttpMethod;
|
||||
*/
|
||||
// TODO for requests that pass in input streams e.g. binary content for workflow, this is going to need a way to re-read the input stream a la
|
||||
// code in RepositoryContainer due to retrying transaction logic
|
||||
public abstract class AbstractResourceWebScript extends ApiWebScript implements HttpMethodSupport, ActionExecutor
|
||||
public abstract class AbstractResourceWebScript extends ApiWebScript implements HttpMethodSupport, ActionExecutor, ResponseWriter
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(AbstractResourceWebScript.class);
|
||||
|
||||
@@ -146,18 +147,18 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
}
|
||||
else
|
||||
{
|
||||
renderJsonResponse(res, toSerialize);
|
||||
renderJsonResponse(res, toSerialize, assistant.getJsonHelper());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (AlfrescoRuntimeException | ApiException | WebScriptException xception )
|
||||
{
|
||||
assistant.renderException(xception, res);
|
||||
renderException(xception, res, assistant);
|
||||
}
|
||||
catch (RuntimeException runtimeException)
|
||||
{
|
||||
assistant.renderException(runtimeException, res);
|
||||
renderException(runtimeException, res, assistant);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +166,7 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
{
|
||||
final String entityCollectionName = ResourceInspector.findEntityCollectionNameName(resource.getMetaData());
|
||||
final ResourceOperation operation = resource.getMetaData().getOperation(getHttpMethod());
|
||||
final WithResponse callBack = new WithResponse(operation.getSuccessStatus(), ApiAssistant.DEFAULT_JSON_CONTENT,ApiAssistant.CACHE_NEVER);
|
||||
final WithResponse callBack = new WithResponse(operation.getSuccessStatus(), DEFAULT_JSON_CONTENT,CACHE_NEVER);
|
||||
Object toReturn = transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
|
||||
{
|
||||
@@ -199,7 +200,7 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
{
|
||||
NodeBinaryResource nodeResource = (NodeBinaryResource) resource;
|
||||
ContentInfo contentInfo = nodeResource.getContentInfo();
|
||||
assistant.setContentInfoOnResponse(res, contentInfo);
|
||||
setContentInfoOnResponse(res, contentInfo);
|
||||
// if requested, set attachment
|
||||
boolean attach = StringUtils.isNotEmpty(nodeResource.getAttachFileName());
|
||||
Map<String, Object> model = getModelForCacheDirective(nodeResource.getCacheDirective());
|
||||
@@ -217,70 +218,6 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The response status must be set before the response is written by Jackson (which will by default close and commit the response).
|
||||
* In a r/w txn, web script buffered responses ensure that it doesn't really matter but for r/o txns this is important.
|
||||
*
|
||||
* If you set content information via the contentInfo object and ALSO the headers then "headers" will win because they are
|
||||
* set last.
|
||||
*
|
||||
* @param res
|
||||
* @param status
|
||||
* @param cache
|
||||
* @param contentInfo
|
||||
* @param headers
|
||||
*/
|
||||
public void setResponse(final WebScriptResponse res, int status, Cache cache, ContentInfo contentInfo, Map<String, List<String>> headers)
|
||||
{
|
||||
res.setStatus(status);
|
||||
if (cache != null) res.setCache(cache);
|
||||
assistant.setContentInfoOnResponse(res,contentInfo);
|
||||
if (headers != null && !headers.isEmpty())
|
||||
{
|
||||
for (Map.Entry<String, List<String>> header:headers.entrySet())
|
||||
{
|
||||
for (int i=0; i < header.getValue().size(); i++) {
|
||||
if (i==0)
|
||||
{
|
||||
//If its the first one then set the header overwriting.
|
||||
res.setHeader(header.getKey(), header.getValue().get(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
//If its not the first one than update the header
|
||||
res.addHeader(header.getKey(), header.getValue().get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setResponse(final WebScriptResponse res, WithResponse withResponse)
|
||||
{
|
||||
setResponse(res, withResponse.getStatus(), withResponse.getCache(), withResponse.getContentInfo(), withResponse.getHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the result of an execution.
|
||||
*
|
||||
* @param res WebScriptResponse
|
||||
* @param toSerialize result of an execution
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void renderJsonResponse(final WebScriptResponse res, final Object toSerialize)
|
||||
throws IOException
|
||||
{
|
||||
assistant.getJsonHelper().withWriter(res.getOutputStream(), new JacksonHelper.Writer()
|
||||
{
|
||||
@Override
|
||||
public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
|
||||
throws JsonGenerationException, JsonMappingException, IOException
|
||||
{
|
||||
objectMapper.writeValue(generator, toSerialize);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setLocator(ResourceLocator locator)
|
||||
{
|
||||
this.locator = locator;
|
||||
|
@@ -38,6 +38,7 @@ import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResou
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||
@@ -48,7 +49,7 @@ import org.springframework.http.HttpMethod;
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class ResourceWebScriptDelete extends AbstractResourceWebScript implements ParamsExtractor
|
||||
public class ResourceWebScriptDelete extends AbstractResourceWebScript implements ParamsExtractor, RecognizedParamsExtractor
|
||||
{
|
||||
|
||||
public ResourceWebScriptDelete()
|
||||
@@ -63,7 +64,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
|
||||
{
|
||||
String entityId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.ENTITY_ID);
|
||||
String relationshipId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_ID);
|
||||
final Params.RecognizedParams params = ResourceWebScriptHelper.getRecognizedParams(req);
|
||||
final Params.RecognizedParams params = getRecognizedParams(req);
|
||||
|
||||
switch (resourceMeta.getType())
|
||||
{
|
||||
@@ -215,7 +216,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
|
||||
public Void execute(final ResourceWithMetadata resource, final Params params, final WebScriptResponse res, boolean isReadOnly)
|
||||
{
|
||||
final ResourceOperation operation = resource.getMetaData().getOperation(HttpMethod.DELETE);
|
||||
final WithResponse callBack = new WithResponse(operation.getSuccessStatus(), ApiAssistant.DEFAULT_JSON_CONTENT,ApiAssistant.CACHE_NEVER);
|
||||
final WithResponse callBack = new WithResponse(operation.getSuccessStatus(), DEFAULT_JSON_CONTENT,CACHE_NEVER);
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
|
@@ -40,6 +40,7 @@ import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params.RecognizedParams;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -51,7 +52,7 @@ import org.springframework.http.HttpMethod;
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class ResourceWebScriptGet extends AbstractResourceWebScript implements ParamsExtractor
|
||||
public class ResourceWebScriptGet extends AbstractResourceWebScript implements ParamsExtractor, RecognizedParamsExtractor
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ResourceWebScriptGet.class);
|
||||
|
||||
@@ -67,7 +68,7 @@ public class ResourceWebScriptGet extends AbstractResourceWebScript implements P
|
||||
{
|
||||
final String entityId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.ENTITY_ID);
|
||||
final String relationshipId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_ID);
|
||||
final RecognizedParams params = ResourceWebScriptHelper.getRecognizedParams(req);
|
||||
final RecognizedParams params = getRecognizedParams(req);
|
||||
|
||||
switch (resourceMeta.getType())
|
||||
{
|
||||
|
@@ -67,6 +67,7 @@ import org.alfresco.rest.framework.resource.parameters.where.Query;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.QueryImpl;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.WhereCompiler;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
@@ -92,336 +93,10 @@ import org.springframework.http.HttpMethod;
|
||||
public class ResourceWebScriptHelper
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ResourceWebScriptHelper.class);
|
||||
public static final String PARAM_RELATIONS = "relations";
|
||||
|
||||
public static final String PARAM_FILTER_FIELDS = "fields";
|
||||
|
||||
@Deprecated
|
||||
public static final String PARAM_FILTER_PROPERTIES = "properties";
|
||||
|
||||
public static final String PARAM_PAGING_SKIP = "skipCount";
|
||||
public static final String PARAM_PAGING_MAX = "maxItems";
|
||||
public static final String PARAM_ORDERBY = "orderBy";
|
||||
public static final String PARAM_WHERE = "where";
|
||||
|
||||
public static final String PARAM_SELECT = "select";
|
||||
|
||||
public static final String PARAM_INCLUDE = "include";
|
||||
public static final String PARAM_INCLUDE_SOURCE_ENTITY = "includeSource";
|
||||
|
||||
public static final List<String> KNOWN_PARAMS = Arrays.asList(
|
||||
PARAM_RELATIONS, PARAM_FILTER_PROPERTIES, PARAM_FILTER_FIELDS,PARAM_PAGING_SKIP,PARAM_PAGING_MAX,
|
||||
PARAM_ORDERBY, PARAM_WHERE, PARAM_SELECT, PARAM_INCLUDE_SOURCE_ENTITY);
|
||||
|
||||
private ResourceLocator locator;
|
||||
|
||||
private ActionExecutor executor;
|
||||
|
||||
/**
|
||||
* Takes the web request and looks for a "fields" parameter (otherwise deprecated "properties" parameter).
|
||||
*
|
||||
* Parses the parameter and produces a list of bean properties to use as a filter A
|
||||
* SimpleBeanPropertyFilter it returned that uses the bean properties. If no
|
||||
* filter param is set then a default BeanFilter is returned that will never
|
||||
* filter fields (ie. Returns all bean properties).
|
||||
*
|
||||
* @param filterParams String
|
||||
* @return BeanPropertyFilter - if no parameter then returns a new
|
||||
* ReturnAllBeanProperties class
|
||||
*/
|
||||
public static BeanPropertiesFilter getFilter(String filterParams)
|
||||
{
|
||||
return getFilter(filterParams, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the web request and looks for a "fields" parameter (otherwise deprecated "properties" parameter).
|
||||
*
|
||||
* Parses the parameter and produces a list of bean properties to use as a filter A
|
||||
* SimpleBeanPropertyFilter it returned that uses the bean properties. If no
|
||||
* filter param is set then a default BeanFilter is returned that will never
|
||||
* filter fields (ie. Returns all bean properties).
|
||||
*
|
||||
* If selectList is provided then it will take precedence (ie. be included) over the fields/properties filter
|
||||
* for top-level entries (bean properties).
|
||||
*
|
||||
* For example, this will return entries from both select & properties, eg.
|
||||
*
|
||||
* select=abc,def&properties=id,name,ghi
|
||||
*
|
||||
* Note: it should be noted that API-generic "fields" clause does not currently work for sub-entries.
|
||||
*
|
||||
* Hence, even if the API-specific "select" clause allows selection of a sub-entries this cannot be used
|
||||
* with "fields" filtering. For example, an API-specific method may implement and return "abc/blah", eg.
|
||||
*
|
||||
* select=abc/blah
|
||||
*
|
||||
* However the following will not return "abc/blah" if used with fields filtering, eg.
|
||||
*
|
||||
* select=abc/blah&fields=id,name,ghi
|
||||
*
|
||||
* If fields filtering is desired then it would require "abc" to be selected and returned as a whole, eg.
|
||||
*
|
||||
* select=abc&fields=id,name,ghi
|
||||
*
|
||||
* @param filterParams
|
||||
* @param selectList
|
||||
* @return
|
||||
*/
|
||||
public static BeanPropertiesFilter getFilter(String filterParams, List<String> selectList)
|
||||
{
|
||||
if (filterParams != null)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(filterParams, ",");
|
||||
Set<String> filteredProperties = new HashSet<String>(st.countTokens());
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
filteredProperties.add(st.nextToken());
|
||||
}
|
||||
|
||||
// if supplied, the select takes precedence over the filter (fields/properties) for top-level bean properties
|
||||
if (selectList != null)
|
||||
{
|
||||
for (String select : selectList)
|
||||
{
|
||||
String[] split = select.split("/");
|
||||
filteredProperties.add(split[0]);
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("Filtering using the following properties: " + filteredProperties);
|
||||
BeanPropertiesFilter filter = new BeanPropertiesFilter(filteredProperties);
|
||||
return filter;
|
||||
}
|
||||
return BeanPropertiesFilter.ALLOW_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the web request and looks for a "relations" parameter Parses the
|
||||
* parameter and produces a list of bean properties to use as a filter A
|
||||
* SimpleBeanPropertiesFilter it returned that uses the properties If no
|
||||
* filter param is set then a default BeanFilter is returned that will never
|
||||
* filter properties (ie. Returns all bean properties).
|
||||
*
|
||||
* @param filterParams String
|
||||
* @return BeanPropertiesFilter - if no parameter then returns a new
|
||||
* ReturnAllBeanProperties class
|
||||
*/
|
||||
public static Map<String, BeanPropertiesFilter> getRelationFilter(String filterParams)
|
||||
{
|
||||
if (filterParams != null)
|
||||
{
|
||||
// Split by a comma when not in a bracket
|
||||
String[] relations = filterParams.split(",(?![^()]*+\\))");
|
||||
Map<String, BeanPropertiesFilter> filterMap = new HashMap<String, BeanPropertiesFilter>(relations.length);
|
||||
|
||||
for (String relation : relations)
|
||||
{
|
||||
int bracketLocation = relation.indexOf("(");
|
||||
if (bracketLocation != -1)
|
||||
{
|
||||
// We have properties
|
||||
String relationKey = relation.substring(0, bracketLocation);
|
||||
String props = relation.substring(bracketLocation + 1, relation.length() - 1);
|
||||
filterMap.put(relationKey, getFilter(props));
|
||||
}
|
||||
else
|
||||
{
|
||||
// no properties so just get the String
|
||||
filterMap.put(relation, getFilter(null));
|
||||
}
|
||||
}
|
||||
return filterMap;
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the "select" parameter and turns it into a List<String> property names
|
||||
* @param selectParam String
|
||||
* @return bean property names potentially using JSON Pointer syntax
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Deprecated
|
||||
public static List<String> getSelectClause(String selectParam) throws InvalidArgumentException
|
||||
{
|
||||
return getClause(selectParam, "SELECT");
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the "include" parameter and turns it into a List<String> property names
|
||||
* @param includeParam String
|
||||
* @return bean property names potentially using JSON Pointer syntax
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<String> getIncludeClause(String includeParam) throws InvalidArgumentException
|
||||
{
|
||||
return getClause(includeParam, "INCLUDE");
|
||||
}
|
||||
|
||||
private static List<String> getClause(String param, String paramName)
|
||||
{
|
||||
if (param == null) return Collections.emptyList();
|
||||
|
||||
try {
|
||||
CommonTree selectedPropsTree = WhereCompiler.compileSelectClause(param);
|
||||
if (selectedPropsTree instanceof CommonErrorNode)
|
||||
{
|
||||
logger.debug("Error parsing the "+paramName+" clause "+selectedPropsTree);
|
||||
throw new InvalidSelectException(paramName, selectedPropsTree);
|
||||
}
|
||||
if (selectedPropsTree.getChildCount() == 0 && !selectedPropsTree.getText().isEmpty())
|
||||
{
|
||||
return Arrays.asList(selectedPropsTree.getText());
|
||||
}
|
||||
List<Tree> children = (List<Tree>) selectedPropsTree.getChildren();
|
||||
if (children!= null && !children.isEmpty())
|
||||
{
|
||||
List<String> properties = new ArrayList<String>(children.size());
|
||||
for (Tree child : children) {
|
||||
properties.add(child.getText());
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
catch (RewriteCardinalityException re)
|
||||
{
|
||||
//Catch any error so it doesn't get thrown up the stack
|
||||
logger.debug("Unhandled Error parsing the "+paramName+" clause: "+re);
|
||||
}
|
||||
catch (RecognitionException e)
|
||||
{
|
||||
logger.debug("Error parsing the \"+paramName+\" clause: "+param);
|
||||
}
|
||||
catch (InvalidQueryException iqe)
|
||||
{
|
||||
throw new InvalidSelectException(paramName, iqe.getQueryParam());
|
||||
}
|
||||
//Default to throw out an invalid query
|
||||
throw new InvalidSelectException(paramName, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the "where" parameter and turns it into a Java Object that can be used for querying
|
||||
* @param whereParam String
|
||||
* @return Query a parsed version of the where clause, represented in Java
|
||||
*/
|
||||
public static Query getWhereClause(String whereParam) throws InvalidQueryException
|
||||
{
|
||||
if (whereParam == null) return QueryImpl.EMPTY;
|
||||
|
||||
try {
|
||||
CommonTree whereTree = WhereCompiler.compileWhereClause(whereParam);
|
||||
if (whereTree instanceof CommonErrorNode)
|
||||
{
|
||||
logger.debug("Error parsing the WHERE clause "+whereTree);
|
||||
throw new InvalidQueryException(whereTree);
|
||||
}
|
||||
return new QueryImpl(whereTree);
|
||||
} catch (RewriteCardinalityException re) { //Catch any error so it doesn't get thrown up the stack
|
||||
logger.info("Unhandled Error parsing the WHERE clause: "+re);
|
||||
} catch (RecognitionException e) {
|
||||
whereParam += ", "+WhereCompiler.resolveMessage(e);
|
||||
logger.info("Error parsing the WHERE clause: "+whereParam);
|
||||
}
|
||||
//Default to throw out an invalid query
|
||||
throw new InvalidQueryException(whereParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the Sort parameter as a String and parses it into a List of SortColumn objects.
|
||||
* The format is a comma seperated list of "columnName sortDirection",
|
||||
* e.g. "name DESC, age ASC". It is not case sensitive and the sort direction is optional
|
||||
* It default to sort ASCENDING.
|
||||
* @param sortParams - String passed in on the request
|
||||
* @return - the sort columns or an empty list if the params were invalid.
|
||||
*/
|
||||
public static List<SortColumn> getSort(String sortParams)
|
||||
{
|
||||
if (sortParams != null)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(sortParams, ",");
|
||||
List<SortColumn> sortedColumns = new ArrayList<SortColumn>(st.countTokens());
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String token = st.nextToken();
|
||||
StringTokenizer columnDesc = new StringTokenizer(token, " ");
|
||||
if (columnDesc.countTokens() <= 2)
|
||||
{
|
||||
String columnName = columnDesc.nextToken();
|
||||
String sortOrder = SortColumn.ASCENDING;
|
||||
if (columnDesc.hasMoreTokens())
|
||||
{
|
||||
String sortDef = columnDesc.nextToken().toUpperCase();
|
||||
if (SortColumn.ASCENDING.equals(sortDef) || SortColumn.DESCENDING.equals(sortDef))
|
||||
{
|
||||
sortOrder = sortDef;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug("Invalid sort order definition ("+sortDef+"). Valid values are "+SortColumn.ASCENDING+" or "+SortColumn.DESCENDING+".");
|
||||
}
|
||||
}
|
||||
sortedColumns.add(new SortColumn(columnName, SortColumn.ASCENDING.equals(sortOrder)));
|
||||
}
|
||||
// filteredProperties.add();
|
||||
}
|
||||
// logger.debug("Filtering using the following properties: " + filteredProperties);
|
||||
// BeanPropertiesFilter filter = new BeanPropertiesFilter(filteredProperties);
|
||||
return sortedColumns;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the body contents from the request
|
||||
*
|
||||
* @param req the request
|
||||
* @param jsonHelper Jackson Helper
|
||||
* @param requiredType the type to return
|
||||
* @return the Object in the required type
|
||||
*/
|
||||
public static <T> T extractJsonContent(WebScriptRequest req, JacksonHelper jsonHelper, Class<T> requiredType)
|
||||
{
|
||||
Reader reader;
|
||||
try
|
||||
{
|
||||
reader = req.getContent().getReader();
|
||||
return jsonHelper.construct(reader, requiredType);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
logger.warn("Could not read content from HTTP request body.", e);
|
||||
throw new InvalidArgumentException("Could not read content from HTTP request body.");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ApiException("Could not read content from HTTP request body.", e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the body contents from the request as a List, the JSON can be an array or just a single value without the [] symbols
|
||||
*
|
||||
* @param req the request
|
||||
* @param jsonHelper Jackson Helper
|
||||
* @param requiredType the type to return (without the List param)
|
||||
* @return A List of "Object" as the required type
|
||||
*/
|
||||
public static <T> List<T> extractJsonContentAsList(WebScriptRequest req, JacksonHelper jsonHelper, Class<T> requiredType)
|
||||
{
|
||||
Reader reader;
|
||||
try
|
||||
{
|
||||
reader = req.getContent().getReader();
|
||||
return jsonHelper.constructList(reader, requiredType);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ApiException("Could not read content from HTTP request body.", e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id of theObj to the uniqueId. Attempts to find a set method and
|
||||
* invoke it. If it fails it just swallows the exceptions and doesn't throw
|
||||
@@ -471,41 +146,6 @@ public class ResourceWebScriptHelper
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Renders the response result
|
||||
// *
|
||||
// * @param response
|
||||
// * @param result
|
||||
// */
|
||||
// public static void renderResponseDep(Map<String, Object> response, Object result)
|
||||
// {
|
||||
//
|
||||
// if (result == null) { return; }
|
||||
//
|
||||
// if (result instanceof Collection)
|
||||
// {
|
||||
// response.put("list", result);
|
||||
// }
|
||||
// else if (result instanceof CollectionWithPagingInfo)
|
||||
// {
|
||||
// CollectionWithPagingInfo<?> col = (CollectionWithPagingInfo<?>) result;
|
||||
// if (col.getCollection() !=null && !col.getCollection().isEmpty())
|
||||
// {
|
||||
// response.put("list", col);
|
||||
// }
|
||||
// }
|
||||
// else if (result instanceof Pair<?,?>)
|
||||
// {
|
||||
// Pair<?,?> aPair = (Pair<?, ?>) result;
|
||||
// response.put("entry", aPair.getFirst());
|
||||
// response.put("relations", aPair.getSecond());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// response.put("entry", result);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Looks at the object passed in and recursively expands any @EmbeddedEntityResource annotations or related relationship.
|
||||
* {@link org.alfresco.rest.framework.resource.EmbeddedEntityResource EmbeddedEntityResource} is expanded by calling the ReadById method for this entity.
|
||||
@@ -677,7 +317,7 @@ public class ResourceWebScriptHelper
|
||||
paramFilter = filters.get(resourceKey);
|
||||
}
|
||||
final Params executionParams = Params.valueOf(paramFilter, uniqueEntityId, params.getRequest());
|
||||
final WithResponse callBack = new WithResponse(Status.STATUS_OK, ApiAssistant.DEFAULT_JSON_CONTENT,ApiAssistant.CACHE_NEVER);
|
||||
final WithResponse callBack = new WithResponse(Status.STATUS_OK, ResponseWriter.DEFAULT_JSON_CONTENT,ResponseWriter.CACHE_NEVER);
|
||||
//Read only because this only occurs for GET requests
|
||||
Object result = executor.executeAction(resource, executionParams, callBack);
|
||||
return processAdditionsToTheResponse(null, api, null, executionParams, result);
|
||||
@@ -705,118 +345,6 @@ public class ResourceWebScriptHelper
|
||||
return null; //default
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all request parameters that aren't already known about (eg. not paging or filter params)
|
||||
* and returns them for use.
|
||||
*
|
||||
* @param req - the WebScriptRequest object
|
||||
* @return the request parameters
|
||||
*/
|
||||
public static Map<String, String[]> getRequestParameters(WebScriptRequest req)
|
||||
{
|
||||
if (req!= null)
|
||||
{
|
||||
String[] paramNames = req.getParameterNames();
|
||||
if (paramNames!= null)
|
||||
{
|
||||
Map<String, String[]> requestParameteters = new HashMap<String, String[]>(paramNames.length);
|
||||
|
||||
for (int i = 0; i < paramNames.length; i++)
|
||||
{
|
||||
String paramName = paramNames[i];
|
||||
if (!KNOWN_PARAMS.contains(paramName))
|
||||
{
|
||||
String[] vals = req.getParameterValues(paramName);
|
||||
requestParameteters.put(paramName, vals);
|
||||
}
|
||||
}
|
||||
return requestParameteters;
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the formal set of params that any rest service could potentially have passed in as request params
|
||||
* @param req WebScriptRequest
|
||||
* @return RecognizedParams a POJO containing the params for use with the Params objects
|
||||
*/
|
||||
public static RecognizedParams getRecognizedParams(WebScriptRequest req)
|
||||
{
|
||||
Paging paging = findPaging(req);
|
||||
List<SortColumn> sorting = getSort(req.getParameter(ResourceWebScriptHelper.PARAM_ORDERBY));
|
||||
Map<String, BeanPropertiesFilter> relationFilter = getRelationFilter(req.getParameter(ResourceWebScriptHelper.PARAM_RELATIONS));
|
||||
Query whereQuery = getWhereClause(req.getParameter(ResourceWebScriptHelper.PARAM_WHERE));
|
||||
Map<String, String[]> requestParams = getRequestParameters(req);
|
||||
boolean includeSource = Boolean.valueOf(req.getParameter(ResourceWebScriptHelper.PARAM_INCLUDE_SOURCE_ENTITY));
|
||||
|
||||
List<String> includedFields = getIncludeClause(req.getParameter(ResourceWebScriptHelper.PARAM_INCLUDE));
|
||||
List<String> selectFields = getSelectClause(req.getParameter(ResourceWebScriptHelper.PARAM_SELECT));
|
||||
|
||||
String fields = req.getParameter(ResourceWebScriptHelper.PARAM_FILTER_FIELDS);
|
||||
String properties = req.getParameter(ResourceWebScriptHelper.PARAM_FILTER_PROPERTIES);
|
||||
|
||||
if ((fields != null) && (properties != null))
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("Taking 'fields' param [" + fields + "] and ignoring deprecated 'properties' param [" + properties + "]");
|
||||
}
|
||||
}
|
||||
|
||||
BeanPropertiesFilter filter = getFilter((fields != null ? fields : properties), includedFields);
|
||||
|
||||
return new RecognizedParams(requestParams, paging, filter, relationFilter, includedFields, selectFields, whereQuery, sorting, includeSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find paging setings based on the request parameters.
|
||||
*
|
||||
* @param req
|
||||
* @return Paging
|
||||
*/
|
||||
public static Paging findPaging(WebScriptRequest req)
|
||||
{
|
||||
int skipped = Paging.DEFAULT_SKIP_COUNT;
|
||||
int max = Paging.DEFAULT_MAX_ITEMS;
|
||||
String skip = req.getParameter(PARAM_PAGING_SKIP);
|
||||
String maxItems = req.getParameter(PARAM_PAGING_MAX);
|
||||
|
||||
try
|
||||
{
|
||||
if (skip != null) { skipped = Integer.parseInt(skip);}
|
||||
if (maxItems != null) { max = Integer.parseInt(maxItems); }
|
||||
if (skipped < 0)
|
||||
{
|
||||
throw new InvalidArgumentException("Negative values not supported for skipCount.");
|
||||
}
|
||||
if (max < 1)
|
||||
{
|
||||
throw new InvalidArgumentException("Only positive values supported for maxItems.");
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException error)
|
||||
{
|
||||
String errorMsg = "Invalid paging parameters skipCount: " + skip + ", maxItems:" + maxItems;
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug(errorMsg);
|
||||
}
|
||||
if (skip == null)
|
||||
{
|
||||
errorMsg = "Invalid paging parameter maxItems:" + maxItems;
|
||||
}
|
||||
if (maxItems == null)
|
||||
{
|
||||
errorMsg = "Invalid paging parameter skipCount:" + skip;
|
||||
}
|
||||
throw new InvalidArgumentException(errorMsg);
|
||||
}
|
||||
|
||||
return Paging.valueOf(skipped, max);
|
||||
}
|
||||
|
||||
public void setLocator(ResourceLocator locator)
|
||||
{
|
||||
this.locator = locator;
|
||||
|
@@ -45,6 +45,8 @@ import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResou
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params.RecognizedParams;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.framework.tools.RequestReader;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequestImpl;
|
||||
@@ -56,7 +58,8 @@ import org.springframework.http.HttpMethod;
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class ResourceWebScriptPost extends AbstractResourceWebScript implements ParamsExtractor
|
||||
public class ResourceWebScriptPost extends AbstractResourceWebScript implements ParamsExtractor,
|
||||
RecognizedParamsExtractor, RequestReader
|
||||
{
|
||||
|
||||
public ResourceWebScriptPost()
|
||||
@@ -69,7 +72,7 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
@Override
|
||||
public Params extractParams(ResourceMetadata resourceMeta, WebScriptRequest req)
|
||||
{
|
||||
final RecognizedParams params = ResourceWebScriptHelper.getRecognizedParams(req);
|
||||
final RecognizedParams params = getRecognizedParams(req);
|
||||
final String entityId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.ENTITY_ID);
|
||||
final String relationshipId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_ID);
|
||||
final ResourceOperation operation = resourceMeta.getOperation(HttpMethod.POST);
|
||||
@@ -168,7 +171,7 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
Object jsonContent = null;
|
||||
if (objType != null)
|
||||
{
|
||||
jsonContent = ResourceWebScriptHelper.extractJsonContent(req, assistant.getJsonHelper(), objType);
|
||||
jsonContent = extractJsonContent(req, assistant.getJsonHelper(), objType);
|
||||
}
|
||||
|
||||
if (isTypeOperation)
|
||||
@@ -203,11 +206,11 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
if (isTypeOperation)
|
||||
{
|
||||
// Operations don't support a List as json body
|
||||
return ResourceWebScriptHelper.extractJsonContent(req, assistant.getJsonHelper(), objType);
|
||||
return extractJsonContent(req, assistant.getJsonHelper(), objType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ResourceWebScriptHelper.extractJsonContentAsList(req, assistant.getJsonHelper(), objType);
|
||||
return extractJsonContentAsList(req, assistant.getJsonHelper(), objType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -44,6 +44,8 @@ import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||
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;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.framework.tools.RequestReader;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -57,7 +59,8 @@ import org.springframework.http.MediaType;
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class ResourceWebScriptPut extends AbstractResourceWebScript implements ParamsExtractor
|
||||
public class ResourceWebScriptPut extends AbstractResourceWebScript implements ParamsExtractor,
|
||||
RecognizedParamsExtractor, RequestReader
|
||||
{
|
||||
|
||||
private static Log logger = LogFactory.getLog(ResourceWebScriptPut.class);
|
||||
@@ -75,7 +78,7 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
|
||||
|
||||
final String relationshipId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.RELATIONSHIP_ID);
|
||||
final String entityId = req.getServiceMatch().getTemplateVars().get(ResourceLocator.ENTITY_ID);
|
||||
final RecognizedParams params = ResourceWebScriptHelper.getRecognizedParams(req);
|
||||
final RecognizedParams params = getRecognizedParams(req);
|
||||
final ResourceOperation operation = resourceMeta.getOperation(HttpMethod.PUT);
|
||||
|
||||
switch (resourceMeta.getType())
|
||||
@@ -87,7 +90,7 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
|
||||
} else
|
||||
{
|
||||
|
||||
Object putEnt = ResourceWebScriptHelper.extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
|
||||
Object putEnt = extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
|
||||
return Params.valueOf(entityId,params,putEnt, req);
|
||||
}
|
||||
case RELATIONSHIP:
|
||||
@@ -96,7 +99,7 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
|
||||
throw new UnsupportedResourceOperationException("PUT is executed against the instance URL");
|
||||
} else
|
||||
{
|
||||
Object putRel = ResourceWebScriptHelper.extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
|
||||
Object putRel = extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
|
||||
ResourceWebScriptHelper.setUniqueId(putRel,relationshipId);
|
||||
return Params.valueOf(entityId, params, putRel, req);
|
||||
}
|
||||
|
@@ -39,6 +39,7 @@ import org.alfresco.rest.framework.resource.EntityResource;
|
||||
import org.alfresco.rest.framework.resource.RelationshipResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.alfresco.rest.framework.webscripts.AbstractResourceWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.ApiWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
@@ -81,7 +82,7 @@ public abstract class AbstractContextTest
|
||||
|
||||
static Params NOT_USED = Params.valueOf("notUsed", null, mock(WebScriptRequest.class));
|
||||
static final Params.RecognizedParams NULL_PARAMS = new Params.RecognizedParams(null, null, null, null, null, null, null, null, false);
|
||||
static final WithResponse callBack = new WithResponse(Status.STATUS_OK, ApiAssistant.DEFAULT_JSON_CONTENT,ApiAssistant.CACHE_NEVER);
|
||||
static final WithResponse callBack = new WithResponse(Status.STATUS_OK, ResponseWriter.DEFAULT_JSON_CONTENT,ResponseWriter.CACHE_NEVER);
|
||||
static Api api = Api.valueOf("alfrescomock", "private", "1");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package org.alfresco.rest.framework.tests.core;
|
||||
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractorTest;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
@@ -37,7 +38,7 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||
@SuiteClasses({ InspectorTests.class, JsonJacksonTests.class, ParamsExtractorTests.class,
|
||||
ResourceLocatorTests.class, ResourceWebScriptHelperTests.class, SerializeTests.class,
|
||||
WhereTests.class, ExecutionTests.class, WithResponseTest.class,
|
||||
ExceptionResolverTests.class })
|
||||
ExceptionResolverTests.class, RecognizedParamsExtractorTest.class})
|
||||
public class AllRestFrameworkTest
|
||||
{
|
||||
|
||||
|
@@ -51,6 +51,7 @@ import org.alfresco.rest.framework.tests.api.mocks.Grass;
|
||||
import org.alfresco.rest.framework.tests.api.mocks.Sheep;
|
||||
import org.alfresco.rest.framework.tests.api.mocks3.FlockEntityResource;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.alfresco.rest.framework.webscripts.AbstractResourceWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.ApiWebScript;
|
||||
import org.junit.Test;
|
||||
@@ -80,7 +81,7 @@ import java.util.Map;
|
||||
* Tests the execution of resources
|
||||
*/
|
||||
|
||||
public class ExecutionTests extends AbstractContextTest
|
||||
public class ExecutionTests extends AbstractContextTest implements ResponseWriter
|
||||
{
|
||||
static final Api api3 = Api.valueOf("alfrescomock", "private", "3");
|
||||
|
||||
@@ -99,7 +100,7 @@ public class ExecutionTests extends AbstractContextTest
|
||||
entityResource = locator.locateEntityResource(api,"cow", HttpMethod.GET);
|
||||
result = executor.execute(entityResource, Params.valueOf((String)null, null, mock(WebScriptRequest.class)), response, true);
|
||||
assertNotNull(result);
|
||||
verify(response, times(1)).setCache((Cache) ApiAssistant.CACHE_NEVER);
|
||||
verify(response, times(1)).setCache((Cache) ResponseWriter.CACHE_NEVER);
|
||||
|
||||
response = mock(WebScriptResponse.class);
|
||||
result = executor.execute(entityResource, Params.valueOf("543", null, mock(WebScriptRequest.class)), response, true);
|
||||
@@ -305,7 +306,7 @@ public class ExecutionTests extends AbstractContextTest
|
||||
|
||||
ErrorResponse defaultError = new DefaultExceptionResolver().resolveException(new NullPointerException());
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
apiAssistant.renderErrorResponse(defaultError, mockResponse(out));
|
||||
renderErrorResponse(defaultError, mockResponse(out), apiAssistant.getJsonHelper());
|
||||
String errorMessage = out.toString();
|
||||
// System.out.println(errorMessage);
|
||||
assertTrue(errorMessage.contains("\"errorKey\":\"framework.exception.ApiDefault\""));
|
||||
@@ -316,7 +317,7 @@ public class ExecutionTests extends AbstractContextTest
|
||||
|
||||
ErrorResponse anError = simpleMappingExceptionResolver.resolveException(new ApiException("nothing"));
|
||||
out = new ByteArrayOutputStream();
|
||||
apiAssistant.renderErrorResponse(anError, mockResponse(out));
|
||||
renderErrorResponse(anError, mockResponse(out),apiAssistant.getJsonHelper());
|
||||
errorMessage = out.toString();
|
||||
// System.out.println(errorMessage);
|
||||
assertTrue(errorMessage.contains("\"errorKey\":\"nothing\""));
|
||||
@@ -326,7 +327,7 @@ public class ExecutionTests extends AbstractContextTest
|
||||
|
||||
anError = simpleMappingExceptionResolver.resolveException(new EntityNotFoundException("2"));
|
||||
out = new ByteArrayOutputStream();
|
||||
apiAssistant.renderErrorResponse(anError, mockResponse(out));
|
||||
renderErrorResponse(anError, mockResponse(out),apiAssistant.getJsonHelper());
|
||||
errorMessage = out.toString();
|
||||
System.out.println(errorMessage);
|
||||
assertTrue(errorMessage.contains("\"errorKey\":\"framework.exception.EntityNotFound\""));
|
||||
|
@@ -77,6 +77,7 @@ import org.alfresco.rest.framework.tests.api.mocks3.SheepBlackSheepResourceIsNoM
|
||||
import org.alfresco.rest.framework.tests.api.mocks3.SheepEntityResourceWithDeletedMethods;
|
||||
import org.alfresco.rest.framework.tests.api.mocks3.SlimGoat;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.alfresco.rest.framework.webscripts.ApiWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.WithResponse;
|
||||
import org.alfresco.util.Pair;
|
||||
@@ -466,7 +467,7 @@ public class InspectorTests
|
||||
OperationResourceMetaData operationResourceMetaData = (OperationResourceMetaData) resourceMetadata;
|
||||
Method actionMethod = operationResourceMetaData.getOperationMethod();
|
||||
String result = null;
|
||||
final WithResponse wr = new WithResponse(Status.STATUS_OK, ApiAssistant.DEFAULT_JSON_CONTENT, ApiAssistant.CACHE_NEVER);
|
||||
final WithResponse wr = new WithResponse(Status.STATUS_OK, ResponseWriter.DEFAULT_JSON_CONTENT, ResponseWriter.CACHE_NEVER);
|
||||
|
||||
switch (resourceMetadata.getUniqueId())
|
||||
{
|
||||
|
@@ -49,6 +49,7 @@ import org.alfresco.rest.framework.tests.api.mocks.Farmer;
|
||||
import org.alfresco.rest.framework.tests.api.mocks.Goat;
|
||||
import org.alfresco.rest.framework.tests.api.mocks.Grass;
|
||||
import org.alfresco.rest.framework.tests.api.mocks.UniqueIdMethodButNoSetter;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
@@ -63,329 +64,6 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
public class ResourceWebScriptHelperTests
|
||||
{
|
||||
|
||||
|
||||
@Test
|
||||
public void getFilterTest()
|
||||
{
|
||||
BeanPropertiesFilter theFilter = ResourceWebScriptHelper.getFilter(null);
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Null passed in so must return the default BeanPropertiesFilter.ALLOW_ALL class", BeanPropertiesFilter.AllProperties.class.equals(theFilter.getClass()));
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getFilter("bob");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must return the BeanPropertiesFilter class", theFilter instanceof BeanPropertiesFilter);
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getFilter("50,fred,b.z");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must return the BeanPropertiesFilter class", theFilter instanceof BeanPropertiesFilter);
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getFilter("50,fred,");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must return the BeanPropertiesFilter class", theFilter instanceof BeanPropertiesFilter);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getSortingTest()
|
||||
{
|
||||
List<SortColumn> theSort = ResourceWebScriptHelper.getSort(null);
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Null passed in so empty sort list should be returned.", theSort.isEmpty());
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("name ASC");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("name ");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("name DESC");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(!theSort.get(0).asc); //desc
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("name desc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(!theSort.get(0).asc); //desc
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("name,age desc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 2);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
assertEquals("age", theSort.get(1).column);
|
||||
assertTrue(!theSort.get(1).asc); //desc
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort(" name, age desc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 2);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
assertEquals("age", theSort.get(1).column);
|
||||
assertTrue(!theSort.get(1).asc); //desc
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("name DESC, age desc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 2);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(!theSort.get(0).asc); //desc
|
||||
assertEquals("age", theSort.get(1).column);
|
||||
assertTrue(!theSort.get(1).asc); //desc
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("age Desc, name Asc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 2);
|
||||
assertEquals("age", theSort.get(0).column);
|
||||
assertTrue(!theSort.get(0).asc); //desc
|
||||
assertEquals("name", theSort.get(1).column);
|
||||
assertTrue(theSort.get(1).asc);
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("name des"); //invalid, should be desc
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc); //Defaults to ascending because the sort order was invalid
|
||||
|
||||
theSort = ResourceWebScriptHelper.getSort("name asc,"); //invalid, should be desc
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIncludeClauseTest()
|
||||
{
|
||||
getClauseTest("include");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSelectClauseTest()
|
||||
{
|
||||
getClauseTest("select");
|
||||
}
|
||||
|
||||
// at the moment select and include are parsed the same way, hence common/shared test
|
||||
private void getClauseTest(String paramName)
|
||||
{
|
||||
List<String> theClause = getClause(paramName, null);
|
||||
assertNotNull(theClause);
|
||||
assertFalse("Null passed in so nothing in the "+paramName, theClause.size() > 0);
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getClause(paramName, ",,,");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getClause(paramName, "(,,,");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getClause(paramName, "(,,,)");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getClause(paramName, "x/,z");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getClause(paramName, "/x'n,/z");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getClause(paramName, "/foo/0");
|
||||
fail("Should throw an InvalidSelectException. Legal identifiers must start with a letter not zero");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getClause(paramName, "/");
|
||||
fail("Should throw an InvalidSelectException. No identifier specified.");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getClause(paramName, "path, isLink");
|
||||
fail("Should throw an InvalidSelectException. No identifier specified.");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
theClause = getClause(paramName, "king/kong");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("king/kong",theClause.get(0));
|
||||
|
||||
theClause = getClause(paramName, "x,y");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 2);
|
||||
assertEquals("x",theClause.get(0));
|
||||
assertEquals("y",theClause.get(1));
|
||||
|
||||
theClause = getClause(paramName, "x,/z");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 2);
|
||||
assertEquals("x",theClause.get(0));
|
||||
assertEquals("/z",theClause.get(1));
|
||||
|
||||
theClause = getClause(paramName, "/b");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("/b",theClause.get(0));
|
||||
|
||||
theClause = getClause(paramName, "/be,/he");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 2);
|
||||
assertEquals("/be",theClause.get(0));
|
||||
assertEquals("/he",theClause.get(1));
|
||||
|
||||
theClause = getClause(paramName, "/king/kong");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("/king/kong",theClause.get(0));
|
||||
|
||||
theClause = getClause(paramName, "/name,/person/age");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 2);
|
||||
assertEquals("/name",theClause.get(0));
|
||||
assertEquals("/person/age",theClause.get(1));
|
||||
|
||||
theClause = getClause(paramName, "/foo");
|
||||
assertTrue("has a valid select",theClause.size() == 1);
|
||||
assertEquals("/foo",theClause.get(0));
|
||||
|
||||
theClause = getClause(paramName, "/foo/anArray/x");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("/foo/anArray/x",theClause.get(0));
|
||||
|
||||
theClause = getClause(paramName, "/foo/anArray/x,/person/age,/eggs/bacon/sausage,/p");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 4);
|
||||
assertEquals("/foo/anArray/x",theClause.get(0));
|
||||
assertEquals("/person/age",theClause.get(1));
|
||||
assertEquals("/eggs/bacon/sausage",theClause.get(2));
|
||||
assertEquals("/p",theClause.get(3));
|
||||
|
||||
theClause = getClause(paramName, "/foo/_bar ");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("/foo/_bar",theClause.get(0));
|
||||
}
|
||||
|
||||
private List<String> getClause(String paramName, String paramValue)
|
||||
{
|
||||
if (paramName.equalsIgnoreCase("include"))
|
||||
{
|
||||
return ResourceWebScriptHelper.getIncludeClause(paramValue);
|
||||
}
|
||||
else if (paramName.equalsIgnoreCase("select"))
|
||||
{
|
||||
return ResourceWebScriptHelper.getSelectClause(paramValue);
|
||||
}
|
||||
|
||||
fail("Unexpected clause: "+paramName);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRelationFilterTest()
|
||||
{
|
||||
Map<String, BeanPropertiesFilter> theFilter = ResourceWebScriptHelper.getRelationFilter(null);
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Null passed in so nothing to filter.",theFilter.isEmpty());
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getRelationFilter("bob");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a single relationship", theFilter.size() == 1);
|
||||
assertTrue("Must be a single relationship called bob", theFilter.containsKey("bob"));
|
||||
BeanPropertiesFilter aFilter = theFilter.get("bob");
|
||||
assertTrue("No bean properties specified so need a BeanPropertiesFilter.ALLOW_ALL class", BeanPropertiesFilter.AllProperties.class.equals(aFilter.getClass()));
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getRelationFilter("bob,hope");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a two relationships", theFilter.size() == 2);
|
||||
assertTrue("Must have hope.", theFilter.containsKey("hope"));
|
||||
aFilter = theFilter.get("hope");
|
||||
assertTrue("No bean properties specified so need a BeanPropertiesFilter.ALLOW_ALL class", BeanPropertiesFilter.AllProperties.class.equals(aFilter.getClass()));
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getRelationFilter("bob(name),hope");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a two relationships", theFilter.size() == 2);
|
||||
assertTrue("Must have bob.", theFilter.containsKey("bob"));
|
||||
aFilter = theFilter.get("bob");
|
||||
assertTrue("Bean properties specified so must be an BeanPropertiesFilter class", BeanPropertiesFilter.class.equals(aFilter.getClass()));
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getRelationFilter("bob,hope(age,name)");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a two relationships", theFilter.size() == 2);
|
||||
aFilter = theFilter.get("bob");
|
||||
assertTrue("No bean properties specified so need a BeanPropertiesFilter.ALLOW_ALL class", BeanPropertiesFilter.AllProperties.class.equals(aFilter.getClass()));
|
||||
aFilter = theFilter.get("hope");
|
||||
assertTrue("Bean properties specified so must be an BeanPropertiesFilter class", BeanPropertiesFilter.class.equals(aFilter.getClass()));
|
||||
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getRelationFilter("bob(name,age),nohope,hope(height,width)");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a three relationships", theFilter.size() == 3);
|
||||
aFilter = theFilter.get("bob");
|
||||
assertTrue("Bean properties specified so must be an BeanPropertiesFilter class", BeanPropertiesFilter.class.equals(aFilter.getClass()));
|
||||
aFilter = theFilter.get("nohope");
|
||||
assertTrue("No bean properties specified so need a ReturnAllBeanProperties class", BeanPropertiesFilter.AllProperties.class.equals(aFilter.getClass()));
|
||||
aFilter = theFilter.get("hope");
|
||||
assertTrue("Bean properties specified so must be an BeanPropertiesFilter class", BeanPropertiesFilter.class.equals(aFilter.getClass()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setUniqueIdTest()
|
||||
{
|
||||
@@ -406,161 +84,4 @@ public class ResourceWebScriptHelperTests
|
||||
assertNotNull("There should not be an error, errors should be swallowed up.",invalidbj);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findPagingTest()
|
||||
{
|
||||
WebScriptRequest request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("34");
|
||||
when(request.getParameter("maxItems")).thenReturn("50");
|
||||
|
||||
Paging pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue(pagin.getSkipCount() == 34);
|
||||
assertTrue(pagin.getMaxItems() == 50);
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn(null);
|
||||
when(request.getParameter("maxItems")).thenReturn(null);
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue(pagin.getSkipCount() == Paging.DEFAULT_SKIP_COUNT);
|
||||
assertTrue(pagin.getMaxItems() == Paging.DEFAULT_MAX_ITEMS);
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("55");
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue(pagin.getSkipCount() == 55);
|
||||
assertTrue(pagin.getMaxItems() == Paging.DEFAULT_MAX_ITEMS);
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn(null);
|
||||
when(request.getParameter("maxItems")).thenReturn("45");
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue(pagin.getMaxItems() == 45);
|
||||
assertTrue(pagin.getSkipCount() == Paging.DEFAULT_SKIP_COUNT);
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("apple");
|
||||
when(request.getParameter("maxItems")).thenReturn("pear");
|
||||
try
|
||||
{
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("0");
|
||||
when(request.getParameter("maxItems")).thenReturn("0");
|
||||
try
|
||||
{
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
//Test Case cloud-2198
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("0");
|
||||
when(request.getParameter("maxItems")).thenReturn("a");
|
||||
try
|
||||
{
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("s");
|
||||
when(request.getParameter("maxItems")).thenReturn("5");
|
||||
try
|
||||
{
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("0");
|
||||
when(request.getParameter("maxItems")).thenReturn("-2");
|
||||
try
|
||||
{
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("-3");
|
||||
when(request.getParameter("maxItems")).thenReturn("5");
|
||||
try
|
||||
{
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("maxItems")).thenReturn("5");
|
||||
pagin = ResourceWebScriptHelper.findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue("skip count defaults to 0", pagin.getSkipCount() == Paging.DEFAULT_SKIP_COUNT);
|
||||
|
||||
//End of Test Case cloud-2198
|
||||
}
|
||||
|
||||
@Test
|
||||
public void paramsTest()
|
||||
{
|
||||
Map<String,List<String>> mockParams = new HashMap<String,List<String>>();
|
||||
mockParams.put("age", Arrays.asList("23","45"));
|
||||
mockParams.put("name", Arrays.asList("fred"));
|
||||
WebScriptRequest request = mockRequest(mockParams);
|
||||
Map<String, String[]> params = ResourceWebScriptHelper.getRequestParameters(request);
|
||||
assertNotNull(params);
|
||||
Params paramObj = ParamsExtender.valueOf(params);
|
||||
assertNotNull(paramObj);
|
||||
String aValue = paramObj.getParameter("age");
|
||||
assertEquals("23", aValue);
|
||||
|
||||
aValue = paramObj.getParameter("name");
|
||||
assertEquals("fred", aValue);
|
||||
|
||||
}
|
||||
|
||||
private WebScriptRequest mockRequest(final Map<String,List<String>> params)
|
||||
{
|
||||
final String[] paramNames = params.keySet().toArray(new String[]{});
|
||||
WebScriptRequest request = mock(WebScriptRequest.class);
|
||||
when(request.getParameterNames()).thenReturn(paramNames);
|
||||
when(request.getParameterValues(anyString())).thenAnswer(new Answer<String[]>() {
|
||||
@Override
|
||||
public String[] answer(InvocationOnMock invocation) throws Throwable {
|
||||
Object[] args = invocation.getArguments();
|
||||
return params.get((String) args[0]).toArray(new String[]{});
|
||||
}
|
||||
});
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -57,6 +57,7 @@ import org.alfresco.rest.framework.tests.api.mocks.Grass;
|
||||
import org.alfresco.rest.framework.tests.api.mocks.Sheep;
|
||||
import org.alfresco.rest.framework.tests.api.mocks3.Flock;
|
||||
import org.alfresco.rest.framework.tests.api.mocks3.SlimGoat;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.framework.webscripts.AbstractResourceWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -91,7 +92,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class SerializeTests extends AbstractContextTest
|
||||
public class SerializeTests extends AbstractContextTest implements RecognizedParamsExtractor
|
||||
{
|
||||
|
||||
@Test
|
||||
@@ -197,7 +198,7 @@ public class SerializeTests extends AbstractContextTest
|
||||
public void testExpandRelations() throws IOException
|
||||
{
|
||||
assertNotNull(helper);
|
||||
Map<String, BeanPropertiesFilter> rFilter = ResourceWebScriptHelper.getRelationFilter("blacksheep,baaahh");
|
||||
Map<String, BeanPropertiesFilter> rFilter = getRelationFilter("blacksheep,baaahh");
|
||||
ExecutionResult res = (ExecutionResult) helper.processAdditionsToTheResponse(mock(WebScriptResponse.class), api,"sheep",ParamsExtender.valueOf(rFilter,"1"),new Farmer("180"));
|
||||
assertNotNull(res);
|
||||
String out = writeResponse(res);
|
||||
@@ -239,7 +240,7 @@ public class SerializeTests extends AbstractContextTest
|
||||
public void testExpandRecursiveRelations() throws IOException
|
||||
{
|
||||
ExecutionResult exec1 = new ExecutionResult(new Farmer("180"),null);
|
||||
ExecutionResult exec2 = new ExecutionResult(new Farmer("456"),ResourceWebScriptHelper.getFilter("age"));
|
||||
ExecutionResult exec2 = new ExecutionResult(new Farmer("456"),getFilter("age"));
|
||||
CollectionWithPagingInfo<ExecutionResult> coll = CollectionWithPagingInfo.asPaged(null, Arrays.asList(exec1, exec2));
|
||||
ExecutionResult execResult = new ExecutionResult(new Sheep("ssheep"),null);
|
||||
Map<String,Object> related = new HashMap<String,Object>();
|
||||
@@ -436,12 +437,12 @@ public class SerializeTests extends AbstractContextTest
|
||||
public void testFilter() throws IOException, JSONException
|
||||
{
|
||||
assertNotNull(helper);
|
||||
BeanPropertiesFilter theFilter = ResourceWebScriptHelper.getFilter("age");
|
||||
BeanPropertiesFilter theFilter = getFilter("age");
|
||||
Object res = new ExecutionResult(new Sheep("bob"),theFilter);
|
||||
String out = writeResponse(res);
|
||||
assertTrue("Filter must only return the age.", StringUtils.contains(out, "{\"age\":3}"));
|
||||
|
||||
theFilter = ResourceWebScriptHelper.getFilter("age,name");
|
||||
theFilter = getFilter("age,name");
|
||||
res = new ExecutionResult(new Sheep("bob"),theFilter);
|
||||
out = writeResponse(res);
|
||||
JSONObject jsonRsp = new JSONObject(new JSONTokener(out));
|
||||
@@ -452,8 +453,8 @@ public class SerializeTests extends AbstractContextTest
|
||||
assertTrue("The age should be 3", entry.getInt("age") == 3);
|
||||
|
||||
// unit test filter with "include" taking precendence over "fields" filter
|
||||
List<String> theInclude = ResourceWebScriptHelper.getIncludeClause("name");
|
||||
theFilter = ResourceWebScriptHelper.getFilter("age", theInclude);
|
||||
List<String> theInclude = getIncludeClause("name");
|
||||
theFilter = getFilter("age", theInclude);
|
||||
res = new ExecutionResult(new Sheep("bob"),theFilter);
|
||||
out = writeResponse(res);
|
||||
jsonRsp = new JSONObject(new JSONTokener(out));
|
||||
@@ -464,7 +465,7 @@ public class SerializeTests extends AbstractContextTest
|
||||
assertTrue("The age should be 3", entry.getInt("age") == 3);
|
||||
|
||||
Api v3 = Api.valueOf(api.getName(), api.getScope().toString(), "3");
|
||||
Map<String, BeanPropertiesFilter> relFiler = ResourceWebScriptHelper.getRelationFilter("herd");
|
||||
Map<String, BeanPropertiesFilter> relFiler = getRelationFilter("herd");
|
||||
res = helper.processAdditionsToTheResponse(mock(WebScriptResponse.class), v3,"goat",ParamsExtender.valueOf(relFiler, "notUsed"),new SlimGoat());
|
||||
out = writeResponse(res);
|
||||
jsonRsp = new JSONObject(new JSONTokener(out));
|
||||
@@ -476,7 +477,7 @@ public class SerializeTests extends AbstractContextTest
|
||||
assertEquals("The name should be 'bigun'", "bigun", entry.getString("name"));
|
||||
assertTrue("The quantity should be 56", entry.getInt("quantity") == 56);
|
||||
|
||||
relFiler = ResourceWebScriptHelper.getRelationFilter("herd(name)");
|
||||
relFiler = getRelationFilter("herd(name)");
|
||||
res = helper.processAdditionsToTheResponse(mock(WebScriptResponse.class), v3,"goat",ParamsExtender.valueOf(relFiler, "notUsed"),new SlimGoat());
|
||||
out = writeResponse(res);
|
||||
assertTrue("Must return only the herd name.", StringUtils.contains(out, "{\"name\":\"bigun\"}"));
|
||||
|
@@ -37,16 +37,17 @@ import org.alfresco.rest.framework.resource.parameters.where.InvalidQueryExcepti
|
||||
import org.alfresco.rest.framework.resource.parameters.where.Query;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper.WalkerCallbackAdapter;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
import org.junit.Test;
|
||||
|
||||
public class WhereTests {
|
||||
public class WhereTests implements RecognizedParamsExtractor
|
||||
{
|
||||
|
||||
@Test
|
||||
public void basicTest() throws IOException {
|
||||
|
||||
Query theQuery = ResourceWebScriptHelper.getWhereClause(" ( fred > g ) ");
|
||||
Query theQuery = getWhereClause(" ( fred > g ) ");
|
||||
CommonTree ast = theQuery.getTree();
|
||||
//check AST structure
|
||||
assertEquals(WhereClauseParser.GREATERTHAN, ast.getType());
|
||||
@@ -57,13 +58,13 @@ public class WhereTests {
|
||||
@Test
|
||||
public void existClauseTest()
|
||||
{
|
||||
Query theQuery = ResourceWebScriptHelper.getWhereClause(null);
|
||||
Query theQuery = getWhereClause(null);
|
||||
assertNotNull(theQuery);
|
||||
assertTrue("Null passed in so nothing to theQuery.", theQuery.getTree() == null);
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("fred");
|
||||
theQuery = getWhereClause("fred");
|
||||
fail("Should throw an InvalidQueryException");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -73,7 +74,7 @@ public class WhereTests {
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(noClosingBracket");
|
||||
theQuery = getWhereClause("(noClosingBracket");
|
||||
fail("Should throw an InvalidQueryException");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -83,7 +84,7 @@ public class WhereTests {
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("noOpeningBracket)");
|
||||
theQuery = getWhereClause("noOpeningBracket)");
|
||||
fail("Should throw an InvalidQueryException");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -94,7 +95,7 @@ public class WhereTests {
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(EXISTS(target.file))");
|
||||
theQuery = getWhereClause("(EXISTS(target.file))");
|
||||
fail("Should throw an InvalidQueryException");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -102,34 +103,34 @@ public class WhereTests {
|
||||
//this is correct
|
||||
}
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(exists(/target/file))");
|
||||
theQuery = getWhereClause("(exists(/target/file))");
|
||||
assertExistsPropertyEquals("/target/file", theQuery, false);
|
||||
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(EXISTS(b))");
|
||||
theQuery = getWhereClause("(EXISTS(b))");
|
||||
assertExistsPropertyEquals("b", theQuery, false);
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause(" ( EXISTS ( whitespace ) ) ");
|
||||
theQuery = getWhereClause(" ( EXISTS ( whitespace ) ) ");
|
||||
assertExistsPropertyEquals("whitespace", theQuery, false);
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(exists ( folder ))");
|
||||
theQuery = getWhereClause("(exists ( folder ))");
|
||||
assertExistsPropertyEquals("folder", theQuery, false);
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(NOT EXISTS(b))");
|
||||
theQuery = getWhereClause("(NOT EXISTS(b))");
|
||||
assertExistsPropertyEquals("b", theQuery, true);
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause(" (NOT EXISTS(b))");
|
||||
theQuery = getWhereClause(" (NOT EXISTS(b))");
|
||||
assertExistsPropertyEquals("b", theQuery, true);
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( NOT EXISTS(b))");
|
||||
theQuery = getWhereClause("( NOT EXISTS(b))");
|
||||
assertExistsPropertyEquals("b", theQuery, true);
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause(" ( NOT EXISTS(b))");
|
||||
theQuery = getWhereClause(" ( NOT EXISTS(b))");
|
||||
assertExistsPropertyEquals("b", theQuery, true);
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(exists folder)");
|
||||
theQuery = getWhereClause("(exists folder)");
|
||||
fail("Should throw an InvalidQueryException, 'folder' should have a bracket around it");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -137,7 +138,7 @@ public class WhereTests {
|
||||
//this is correct
|
||||
}
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(EXISTS(/target/folder) AND NOT EXISTS(/target/site))");
|
||||
theQuery = getWhereClause("(EXISTS(/target/folder) AND NOT EXISTS(/target/site))");
|
||||
assertNotNull(theQuery);
|
||||
CommonTree tree = theQuery.getTree();
|
||||
assertNotNull(tree);
|
||||
@@ -166,7 +167,7 @@ public class WhereTests {
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(EXISTS(/target/folder)OR EXISTS(/target/site))");
|
||||
theQuery = getWhereClause("(EXISTS(/target/folder)OR EXISTS(/target/site))");
|
||||
fail("Should throw an InvalidQueryException, the OR should have a space before it.");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -174,7 +175,7 @@ public class WhereTests {
|
||||
//this is correct
|
||||
}
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(NOT EXISTS(/target/folder) OR EXISTS(/target/site))");
|
||||
theQuery = getWhereClause("(NOT EXISTS(/target/folder) OR EXISTS(/target/site))");
|
||||
QueryHelper.walk(theQuery, new WalkerCallbackAdapter(){
|
||||
@Override
|
||||
public void exists(String propertyName, boolean negated) {
|
||||
@@ -196,7 +197,7 @@ public class WhereTests {
|
||||
|
||||
});
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(EXISTS ( /target/folder ) OR EXISTS( /target/site ) )");
|
||||
theQuery = getWhereClause("(EXISTS ( /target/folder ) OR EXISTS( /target/site ) )");
|
||||
QueryHelper.walk(theQuery, new WalkerCallbackAdapter(){
|
||||
int i=0;
|
||||
@Override
|
||||
@@ -220,7 +221,7 @@ public class WhereTests {
|
||||
|
||||
});
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(EXISTS(target/file) AND EXISTS(target/folder) AND EXISTS(target/site))");
|
||||
theQuery = getWhereClause("(EXISTS(target/file) AND EXISTS(target/folder) AND EXISTS(target/site))");
|
||||
QueryHelper.walk(theQuery, new WalkerCallbackAdapter(){
|
||||
int i=0;
|
||||
@Override
|
||||
@@ -254,25 +255,25 @@ public class WhereTests {
|
||||
@Test
|
||||
public void inClauseTest()
|
||||
{
|
||||
Query theQuery = ResourceWebScriptHelper.getWhereClause("( dueAt in (5,8) )");
|
||||
Query theQuery = getWhereClause("( dueAt in (5,8) )");
|
||||
inChecks(theQuery, "dueAt", "5", "8");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( fred/bloggs in (head,elbow) )");
|
||||
theQuery = getWhereClause("( fred/bloggs in (head,elbow) )");
|
||||
inChecks(theQuery, "fred/bloggs", "head", "elbow");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( nextOne in (5,8,4) )");
|
||||
theQuery = getWhereClause("( nextOne in (5,8,4) )");
|
||||
inChecks(theQuery, "nextOne", "5", "8", "4");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( nextOne in (5,56,fred) )");
|
||||
theQuery = getWhereClause("( nextOne in (5,56,fred) )");
|
||||
inChecks(theQuery, "nextOne", "5", "56", "fred");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( nextOne in (5,56,'fred&') )");
|
||||
theQuery = getWhereClause("( nextOne in (5,56,'fred&') )");
|
||||
inChecks(theQuery, "nextOne", "5", "56", "fred&");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( nextOne in ('me , you',56,egg) )");
|
||||
theQuery = getWhereClause("( nextOne in ('me , you',56,egg) )");
|
||||
inChecks(theQuery, "nextOne", "me , you", "56", "egg");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( NOT nextOne in (5,56,fred, king, kong, 'fred\\'^') )");
|
||||
theQuery = getWhereClause("( NOT nextOne in (5,56,fred, king, kong, 'fred\\'^') )");
|
||||
CommonTree tree = theQuery.getTree();
|
||||
assertNotNull(tree);
|
||||
QueryHelper.walk(theQuery, new WalkerCallbackAdapter(){
|
||||
@@ -293,15 +294,15 @@ public class WhereTests {
|
||||
@Test
|
||||
public void betweenClauseTest()
|
||||
{
|
||||
Query theQuery = ResourceWebScriptHelper.getWhereClause("( dueAt between (5,8) )");
|
||||
Query theQuery = getWhereClause("( dueAt between (5,8) )");
|
||||
betweenChecks(theQuery, "dueAt", "5", "8");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( fred/bloggs between (head,elbow) )");
|
||||
theQuery = getWhereClause("( fred/bloggs between (head,elbow) )");
|
||||
betweenChecks(theQuery, "fred/bloggs", "head", "elbow");
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( nextOne between (5,8,4) )");
|
||||
theQuery = getWhereClause("( nextOne between (5,8,4) )");
|
||||
fail("Should throw an InvalidQueryException, between can have only two values.");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -311,7 +312,7 @@ public class WhereTests {
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( nextOne between 5,8 )");
|
||||
theQuery = getWhereClause("( nextOne between 5,8 )");
|
||||
fail("Should throw an InvalidQueryException, Need brackets.");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -319,7 +320,7 @@ public class WhereTests {
|
||||
//this is correct
|
||||
}
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(NOT dueAt between (5,8) AND nextOne between (green,blue))");
|
||||
theQuery = getWhereClause("(NOT dueAt between (5,8) AND nextOne between (green,blue))");
|
||||
QueryHelper.walk(theQuery, new WalkerCallbackAdapter(){
|
||||
@Override
|
||||
public void between(String property, String firstVal, String secondVal, boolean negated) {
|
||||
@@ -349,18 +350,18 @@ public class WhereTests {
|
||||
@Test
|
||||
public void matchesClauseTest()
|
||||
{
|
||||
Query theQuery = ResourceWebScriptHelper.getWhereClause("(fred matches(bob))");
|
||||
Query theQuery = getWhereClause("(fred matches(bob))");
|
||||
matchesChecks(theQuery, "fred", "bob");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( king/kong/hair/shoulders/knees/toes matches ('fred%') )");
|
||||
theQuery = getWhereClause("( king/kong/hair/shoulders/knees/toes matches ('fred%') )");
|
||||
matchesChecks(theQuery, "king/kong/hair/shoulders/knees/toes", "fred%");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( niceone matches (bob) )");
|
||||
theQuery = getWhereClause("( niceone matches (bob) )");
|
||||
matchesChecks(theQuery, "niceone", "bob");
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( fred matches bob )");
|
||||
theQuery = getWhereClause("( fred matches bob )");
|
||||
fail("Should throw an InvalidQueryException, Need brackets.");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -373,25 +374,25 @@ public class WhereTests {
|
||||
@Test
|
||||
public void comparisonClauseTest()
|
||||
{
|
||||
Query theQuery = ResourceWebScriptHelper.getWhereClause("( dueAt > '12.04.345' )");
|
||||
Query theQuery = getWhereClause("( dueAt > '12.04.345' )");
|
||||
int comparisonOperator = WhereClauseParser.GREATERTHAN;
|
||||
comparisonChecks(theQuery, comparisonOperator, "dueAt", "12.04.345");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( dueAt >= '12.04.345' )");
|
||||
theQuery = getWhereClause("( dueAt >= '12.04.345' )");
|
||||
comparisonOperator = WhereClauseParser.GREATERTHANOREQUALS;
|
||||
comparisonChecks(theQuery, comparisonOperator, "dueAt", "12.04.345");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( dueAt < '12.04.345' )");
|
||||
theQuery = getWhereClause("( dueAt < '12.04.345' )");
|
||||
comparisonOperator = WhereClauseParser.LESSTHAN;
|
||||
comparisonChecks(theQuery, comparisonOperator, "dueAt", "12.04.345");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( dueAt <= '12.04.345' )");
|
||||
theQuery = getWhereClause("( dueAt <= '12.04.345' )");
|
||||
comparisonOperator = WhereClauseParser.LESSTHANOREQUALS;
|
||||
comparisonChecks(theQuery, comparisonOperator, "dueAt", "12.04.345");
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( Fred/Bloggs = %$NICE&* )");
|
||||
theQuery = getWhereClause("( Fred/Bloggs = %$NICE&* )");
|
||||
fail("Should throw an InvalidQueryException, needs single quotes");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -399,13 +400,13 @@ public class WhereTests {
|
||||
//this is correct
|
||||
}
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( Fred/Bloggs = '%$NICE&*' )");
|
||||
theQuery = getWhereClause("( Fred/Bloggs = '%$NICE&*' )");
|
||||
comparisonOperator = WhereClauseParser.EQUALS;
|
||||
comparisonChecks(theQuery, comparisonOperator, "Fred/Bloggs", "%$NICE&*");
|
||||
|
||||
try
|
||||
{
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( Ken = (456) )");
|
||||
theQuery = getWhereClause("( Ken = (456) )");
|
||||
fail("Should throw an InvalidQueryException, needs single quotes no brackets");
|
||||
}
|
||||
catch (InvalidQueryException error)
|
||||
@@ -413,15 +414,15 @@ public class WhereTests {
|
||||
//this is correct
|
||||
}
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( Ken = '456' )");
|
||||
theQuery = getWhereClause("( Ken = '456' )");
|
||||
comparisonOperator = WhereClauseParser.EQUALS;
|
||||
comparisonChecks(theQuery, comparisonOperator, "Ken", "456");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( DogHouse = 'Cat\\\'s House' )");
|
||||
theQuery = getWhereClause("( DogHouse = 'Cat\\\'s House' )");
|
||||
comparisonOperator = WhereClauseParser.EQUALS;
|
||||
comparisonChecks(theQuery, comparisonOperator, "DogHouse", "Cat\\\'s House");
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( KING_KONG >= 'Mighty Mouse' )");
|
||||
theQuery = getWhereClause("( KING_KONG >= 'Mighty Mouse' )");
|
||||
comparisonOperator = WhereClauseParser.GREATERTHANOREQUALS;
|
||||
comparisonChecks(theQuery, comparisonOperator, "KING_KONG", "Mighty Mouse");
|
||||
|
||||
@@ -442,25 +443,25 @@ public class WhereTests {
|
||||
@Test
|
||||
public void getChildrenTests()
|
||||
{
|
||||
Query theQuery = ResourceWebScriptHelper.getWhereClause("(fred matches(bob))");
|
||||
Query theQuery = getWhereClause("(fred matches(bob))");
|
||||
assertNotNull(theQuery);
|
||||
CommonTree tree = theQuery.getTree();
|
||||
assertNotNull(tree);
|
||||
assertTrue(2 == QueryHelper.getChildren(tree).size());
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("( dueAt between (5,8) )");
|
||||
theQuery = getWhereClause("( dueAt between (5,8) )");
|
||||
assertNotNull(theQuery);
|
||||
tree = theQuery.getTree();
|
||||
assertNotNull(tree);
|
||||
assertTrue(3 == QueryHelper.getChildren(tree).size());
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(NOT EXISTS(b))");
|
||||
theQuery = getWhereClause("(NOT EXISTS(b))");
|
||||
assertNotNull(theQuery);
|
||||
tree = theQuery.getTree();
|
||||
assertNotNull(tree);
|
||||
assertTrue(1 == QueryHelper.getChildren(tree).size());
|
||||
|
||||
theQuery = ResourceWebScriptHelper.getWhereClause("(EXISTS(/target/folder) AND EXISTS(/target/site))");
|
||||
theQuery = getWhereClause("(EXISTS(/target/folder) AND EXISTS(/target/site))");
|
||||
assertNotNull(theQuery);
|
||||
tree = theQuery.getTree();
|
||||
assertNotNull(tree);
|
||||
|
@@ -39,6 +39,7 @@ import static org.mockito.Mockito.when;
|
||||
import org.alfresco.rest.framework.resource.content.ContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.ContentInfoImpl;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.alfresco.rest.framework.webscripts.AbstractResourceWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.ApiWebScript;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptDelete;
|
||||
@@ -70,17 +71,17 @@ public class WithResponseTest
|
||||
@Test
|
||||
public void testDefaults() throws Exception
|
||||
{
|
||||
WithResponse callBack = new WithResponse(Status.STATUS_OK,ApiAssistant.DEFAULT_JSON_CONTENT, ApiAssistant.CACHE_NEVER);
|
||||
WithResponse callBack = new WithResponse(Status.STATUS_OK, ResponseWriter.DEFAULT_JSON_CONTENT, ResponseWriter.CACHE_NEVER);
|
||||
assertEquals(Status.STATUS_OK, callBack.getStatus());
|
||||
assertEquals(ApiAssistant.DEFAULT_JSON_CONTENT, callBack.getContentInfo());
|
||||
assertEquals(ApiAssistant.CACHE_NEVER, callBack.getCache());
|
||||
assertEquals(ResponseWriter.DEFAULT_JSON_CONTENT, callBack.getContentInfo());
|
||||
assertEquals(ResponseWriter.CACHE_NEVER, callBack.getCache());
|
||||
assertTrue(callBack.getHeaders().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetHeader() throws Exception
|
||||
{
|
||||
WithResponse callBack = new WithResponse(Status.STATUS_OK,ApiAssistant.DEFAULT_JSON_CONTENT, ApiAssistant.CACHE_NEVER);
|
||||
WithResponse callBack = new WithResponse(Status.STATUS_OK,ResponseWriter.DEFAULT_JSON_CONTENT, ResponseWriter.CACHE_NEVER);
|
||||
callBack.setHeader("king", "can");
|
||||
callBack.setHeader("king", "kong");
|
||||
assertTrue(callBack.getHeaders().size() == 1);
|
||||
@@ -92,7 +93,7 @@ public class WithResponseTest
|
||||
@Test
|
||||
public void testAddHeader() throws Exception
|
||||
{
|
||||
WithResponse callBack = new WithResponse(Status.STATUS_OK,ApiAssistant.DEFAULT_JSON_CONTENT, ApiAssistant.CACHE_NEVER);
|
||||
WithResponse callBack = new WithResponse(Status.STATUS_OK,ResponseWriter.DEFAULT_JSON_CONTENT, ResponseWriter.CACHE_NEVER);
|
||||
callBack.addHeader("king", "can");
|
||||
callBack.addHeader("king", "kong");
|
||||
assertTrue(callBack.getHeaders().size() == 1);
|
||||
@@ -105,7 +106,7 @@ public class WithResponseTest
|
||||
@Test
|
||||
public void testSetters() throws Exception
|
||||
{
|
||||
WithResponse callBack = new WithResponse(Status.STATUS_OK, ApiAssistant.DEFAULT_JSON_CONTENT, ApiAssistant.CACHE_NEVER);
|
||||
WithResponse callBack = new WithResponse(Status.STATUS_OK, ResponseWriter.DEFAULT_JSON_CONTENT, ResponseWriter.CACHE_NEVER);
|
||||
callBack.setStatus(Status.STATUS_GONE);
|
||||
Cache myCache = new Cache(new Description.RequiredCache()
|
||||
{
|
||||
@@ -142,7 +143,7 @@ public class WithResponseTest
|
||||
{
|
||||
AbstractResourceWebScript responseWriter = new ResourceWebScriptDelete();
|
||||
responseWriter.setAssistant(new ApiAssistant());
|
||||
WithResponse wr = new WithResponse(Status.STATUS_OK, ApiAssistant.DEFAULT_JSON_CONTENT, ApiAssistant.CACHE_NEVER);
|
||||
WithResponse wr = new WithResponse(Status.STATUS_OK, ResponseWriter.DEFAULT_JSON_CONTENT, ResponseWriter.CACHE_NEVER);
|
||||
|
||||
WebScriptResponse response = mock(WebScriptResponse.class);
|
||||
|
||||
|
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* 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/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.framework.tools;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.jacksonextensions.BeanPropertiesFilter;
|
||||
import org.alfresco.rest.framework.resource.parameters.InvalidSelectException;
|
||||
import org.alfresco.rest.framework.resource.parameters.Paging;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.resource.parameters.SortColumn;
|
||||
import org.alfresco.rest.framework.tests.core.ParamsExtender;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Test the RecognizedParamsExtractor
|
||||
*
|
||||
* @author Gethin James
|
||||
*/
|
||||
public class RecognizedParamsExtractorTest implements RecognizedParamsExtractor
|
||||
{
|
||||
|
||||
|
||||
@Test
|
||||
public void getFilterTest()
|
||||
{
|
||||
BeanPropertiesFilter theFilter = getFilter(null);
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Null passed in so must return the default BeanPropertiesFilter.ALLOW_ALL class", BeanPropertiesFilter.AllProperties.class.equals(theFilter.getClass()));
|
||||
|
||||
theFilter = getFilter("bob");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must return the BeanPropertiesFilter class", theFilter instanceof BeanPropertiesFilter);
|
||||
|
||||
theFilter = getFilter("50,fred,b.z");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must return the BeanPropertiesFilter class", theFilter instanceof BeanPropertiesFilter);
|
||||
|
||||
theFilter = getFilter("50,fred,");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must return the BeanPropertiesFilter class", theFilter instanceof BeanPropertiesFilter);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getSortingTest()
|
||||
{
|
||||
List<SortColumn> theSort = getSort(null);
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Null passed in so empty sort list should be returned.", theSort.isEmpty());
|
||||
|
||||
theSort = getSort("name ASC");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
|
||||
theSort = getSort("name ");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
|
||||
theSort = getSort("name DESC");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(!theSort.get(0).asc); //desc
|
||||
|
||||
theSort = getSort("name desc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(!theSort.get(0).asc); //desc
|
||||
|
||||
theSort = getSort("name,age desc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 2);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
assertEquals("age", theSort.get(1).column);
|
||||
assertTrue(!theSort.get(1).asc); //desc
|
||||
|
||||
theSort = getSort(" name, age desc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 2);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
assertEquals("age", theSort.get(1).column);
|
||||
assertTrue(!theSort.get(1).asc); //desc
|
||||
|
||||
theSort = getSort("name DESC, age desc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 2);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(!theSort.get(0).asc); //desc
|
||||
assertEquals("age", theSort.get(1).column);
|
||||
assertTrue(!theSort.get(1).asc); //desc
|
||||
|
||||
theSort = getSort("age Desc, name Asc");
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 2);
|
||||
assertEquals("age", theSort.get(0).column);
|
||||
assertTrue(!theSort.get(0).asc); //desc
|
||||
assertEquals("name", theSort.get(1).column);
|
||||
assertTrue(theSort.get(1).asc);
|
||||
|
||||
theSort = getSort("name des"); //invalid, should be desc
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc); //Defaults to ascending because the sort order was invalid
|
||||
|
||||
theSort = getSort("name asc,"); //invalid, should be desc
|
||||
assertNotNull(theSort);
|
||||
assertTrue("Must have a value for column: NAME", !theSort.isEmpty());
|
||||
assertTrue(theSort.size() == 1);
|
||||
assertEquals("name", theSort.get(0).column);
|
||||
assertTrue(theSort.get(0).asc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIncludeClauseTest()
|
||||
{
|
||||
getClauseTest("include");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSelectClauseTest()
|
||||
{
|
||||
getClauseTest("select");
|
||||
}
|
||||
|
||||
// at the moment select and include are parsed the same way, hence common/shared test
|
||||
private void getClauseTest(String paramName)
|
||||
{
|
||||
List<String> theClause = getCorrectClause(paramName, null);
|
||||
assertNotNull(theClause);
|
||||
assertFalse("Null passed in so nothing in the "+paramName, theClause.size() > 0);
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getCorrectClause(paramName, ",,,");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getCorrectClause(paramName, "(,,,");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getCorrectClause(paramName, "(,,,)");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getCorrectClause(paramName, "x/,z");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getCorrectClause(paramName, "/x'n,/z");
|
||||
fail("Should throw an InvalidSelectException");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getCorrectClause(paramName, "/foo/0");
|
||||
fail("Should throw an InvalidSelectException. Legal identifiers must start with a letter not zero");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getCorrectClause(paramName, "/");
|
||||
fail("Should throw an InvalidSelectException. No identifier specified.");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
theClause = getCorrectClause(paramName, "path, isLink");
|
||||
fail("Should throw an InvalidSelectException. No identifier specified.");
|
||||
}
|
||||
catch (InvalidSelectException error)
|
||||
{
|
||||
//this is correct
|
||||
}
|
||||
|
||||
theClause = getCorrectClause(paramName, "king/kong");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("king/kong",theClause.get(0));
|
||||
|
||||
theClause = getCorrectClause(paramName, "x,y");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 2);
|
||||
assertEquals("x",theClause.get(0));
|
||||
assertEquals("y",theClause.get(1));
|
||||
|
||||
theClause = getCorrectClause(paramName, "x,/z");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 2);
|
||||
assertEquals("x",theClause.get(0));
|
||||
assertEquals("/z",theClause.get(1));
|
||||
|
||||
theClause = getCorrectClause(paramName, "/b");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("/b",theClause.get(0));
|
||||
|
||||
theClause = getCorrectClause(paramName, "/be,/he");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 2);
|
||||
assertEquals("/be",theClause.get(0));
|
||||
assertEquals("/he",theClause.get(1));
|
||||
|
||||
theClause = getCorrectClause(paramName, "/king/kong");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("/king/kong",theClause.get(0));
|
||||
|
||||
theClause = getCorrectClause(paramName, "/name,/person/age");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 2);
|
||||
assertEquals("/name",theClause.get(0));
|
||||
assertEquals("/person/age",theClause.get(1));
|
||||
|
||||
theClause = getCorrectClause(paramName, "/foo");
|
||||
assertTrue("has a valid select",theClause.size() == 1);
|
||||
assertEquals("/foo",theClause.get(0));
|
||||
|
||||
theClause = getCorrectClause(paramName, "/foo/anArray/x");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("/foo/anArray/x",theClause.get(0));
|
||||
|
||||
theClause = getCorrectClause(paramName, "/foo/anArray/x,/person/age,/eggs/bacon/sausage,/p");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 4);
|
||||
assertEquals("/foo/anArray/x",theClause.get(0));
|
||||
assertEquals("/person/age",theClause.get(1));
|
||||
assertEquals("/eggs/bacon/sausage",theClause.get(2));
|
||||
assertEquals("/p",theClause.get(3));
|
||||
|
||||
theClause = getCorrectClause(paramName, "/foo/_bar ");
|
||||
assertTrue("has a valid "+paramName, theClause.size() == 1);
|
||||
assertEquals("/foo/_bar",theClause.get(0));
|
||||
}
|
||||
|
||||
private List<String> getCorrectClause(String paramName, String paramValue)
|
||||
{
|
||||
if (paramName.equalsIgnoreCase("include"))
|
||||
{
|
||||
return getIncludeClause(paramValue);
|
||||
}
|
||||
else if (paramName.equalsIgnoreCase("select"))
|
||||
{
|
||||
return getSelectClause(paramValue);
|
||||
}
|
||||
|
||||
fail("Unexpected clause: "+paramName);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRelationFilterTest()
|
||||
{
|
||||
Map<String, BeanPropertiesFilter> theFilter = getRelationFilter(null);
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Null passed in so nothing to filter.",theFilter.isEmpty());
|
||||
|
||||
theFilter = getRelationFilter("bob");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a single relationship", theFilter.size() == 1);
|
||||
assertTrue("Must be a single relationship called bob", theFilter.containsKey("bob"));
|
||||
BeanPropertiesFilter aFilter = theFilter.get("bob");
|
||||
assertTrue("No bean properties specified so need a BeanPropertiesFilter.ALLOW_ALL class", BeanPropertiesFilter.AllProperties.class.equals(aFilter.getClass()));
|
||||
|
||||
theFilter = getRelationFilter("bob,hope");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a two relationships", theFilter.size() == 2);
|
||||
assertTrue("Must have hope.", theFilter.containsKey("hope"));
|
||||
aFilter = theFilter.get("hope");
|
||||
assertTrue("No bean properties specified so need a BeanPropertiesFilter.ALLOW_ALL class", BeanPropertiesFilter.AllProperties.class.equals(aFilter.getClass()));
|
||||
|
||||
theFilter = getRelationFilter("bob(name),hope");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a two relationships", theFilter.size() == 2);
|
||||
assertTrue("Must have bob.", theFilter.containsKey("bob"));
|
||||
aFilter = theFilter.get("bob");
|
||||
assertTrue("Bean properties specified so must be an BeanPropertiesFilter class", BeanPropertiesFilter.class.equals(aFilter.getClass()));
|
||||
|
||||
theFilter = getRelationFilter("bob,hope(age,name)");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a two relationships", theFilter.size() == 2);
|
||||
aFilter = theFilter.get("bob");
|
||||
assertTrue("No bean properties specified so need a BeanPropertiesFilter.ALLOW_ALL class", BeanPropertiesFilter.AllProperties.class.equals(aFilter.getClass()));
|
||||
aFilter = theFilter.get("hope");
|
||||
assertTrue("Bean properties specified so must be an BeanPropertiesFilter class", BeanPropertiesFilter.class.equals(aFilter.getClass()));
|
||||
|
||||
|
||||
theFilter = getRelationFilter("bob(name,age),nohope,hope(height,width)");
|
||||
assertNotNull(theFilter);
|
||||
assertTrue("Must be a three relationships", theFilter.size() == 3);
|
||||
aFilter = theFilter.get("bob");
|
||||
assertTrue("Bean properties specified so must be an BeanPropertiesFilter class", BeanPropertiesFilter.class.equals(aFilter.getClass()));
|
||||
aFilter = theFilter.get("nohope");
|
||||
assertTrue("No bean properties specified so need a ReturnAllBeanProperties class", BeanPropertiesFilter.AllProperties.class.equals(aFilter.getClass()));
|
||||
aFilter = theFilter.get("hope");
|
||||
assertTrue("Bean properties specified so must be an BeanPropertiesFilter class", BeanPropertiesFilter.class.equals(aFilter.getClass()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void findPagingTest()
|
||||
{
|
||||
WebScriptRequest request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("34");
|
||||
when(request.getParameter("maxItems")).thenReturn("50");
|
||||
|
||||
Paging pagin = findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue(pagin.getSkipCount() == 34);
|
||||
assertTrue(pagin.getMaxItems() == 50);
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn(null);
|
||||
when(request.getParameter("maxItems")).thenReturn(null);
|
||||
pagin = findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue(pagin.getSkipCount() == Paging.DEFAULT_SKIP_COUNT);
|
||||
assertTrue(pagin.getMaxItems() == Paging.DEFAULT_MAX_ITEMS);
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("55");
|
||||
pagin = findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue(pagin.getSkipCount() == 55);
|
||||
assertTrue(pagin.getMaxItems() == Paging.DEFAULT_MAX_ITEMS);
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn(null);
|
||||
when(request.getParameter("maxItems")).thenReturn("45");
|
||||
pagin = findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue(pagin.getMaxItems() == 45);
|
||||
assertTrue(pagin.getSkipCount() == Paging.DEFAULT_SKIP_COUNT);
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("apple");
|
||||
when(request.getParameter("maxItems")).thenReturn("pear");
|
||||
try
|
||||
{
|
||||
pagin = findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("0");
|
||||
when(request.getParameter("maxItems")).thenReturn("0");
|
||||
try
|
||||
{
|
||||
pagin = findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
//Test Case cloud-2198
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("0");
|
||||
when(request.getParameter("maxItems")).thenReturn("a");
|
||||
try
|
||||
{
|
||||
pagin = findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("s");
|
||||
when(request.getParameter("maxItems")).thenReturn("5");
|
||||
try
|
||||
{
|
||||
pagin = findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("0");
|
||||
when(request.getParameter("maxItems")).thenReturn("-2");
|
||||
try
|
||||
{
|
||||
pagin = findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("skipCount")).thenReturn("-3");
|
||||
when(request.getParameter("maxItems")).thenReturn("5");
|
||||
try
|
||||
{
|
||||
pagin = findPaging(request);
|
||||
fail("Should not get here.");
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
{
|
||||
assertNotNull(iae); // Must throw this exceptions
|
||||
}
|
||||
|
||||
request = mock(WebScriptRequest.class);
|
||||
when(request.getParameter("maxItems")).thenReturn("5");
|
||||
pagin = findPaging(request);
|
||||
assertNotNull(pagin);
|
||||
assertTrue("skip count defaults to 0", pagin.getSkipCount() == Paging.DEFAULT_SKIP_COUNT);
|
||||
|
||||
//End of Test Case cloud-2198
|
||||
}
|
||||
|
||||
@Test
|
||||
public void paramsTest()
|
||||
{
|
||||
Map<String,List<String>> mockParams = new HashMap<String,List<String>>();
|
||||
mockParams.put("age", Arrays.asList("23","45"));
|
||||
mockParams.put("name", Arrays.asList("fred"));
|
||||
WebScriptRequest request = mockRequest(mockParams);
|
||||
Map<String, String[]> params = getRequestParameters(request);
|
||||
assertNotNull(params);
|
||||
Params paramObj = ParamsExtender.valueOf(params);
|
||||
assertNotNull(paramObj);
|
||||
String aValue = paramObj.getParameter("age");
|
||||
assertEquals("23", aValue);
|
||||
|
||||
aValue = paramObj.getParameter("name");
|
||||
assertEquals("fred", aValue);
|
||||
|
||||
}
|
||||
|
||||
private WebScriptRequest mockRequest(final Map<String,List<String>> params)
|
||||
{
|
||||
final String[] paramNames = params.keySet().toArray(new String[]{});
|
||||
WebScriptRequest request = mock(WebScriptRequest.class);
|
||||
when(request.getParameterNames()).thenReturn(paramNames);
|
||||
when(request.getParameterValues(anyString())).thenAnswer(new Answer<String[]>() {
|
||||
@Override
|
||||
public String[] answer(InvocationOnMock invocation) throws Throwable {
|
||||
Object[] args = invocation.getArguments();
|
||||
return params.get((String) args[0]).toArray(new String[]{});
|
||||
}
|
||||
});
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
@@ -43,7 +43,7 @@ import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params.RecognizedParams;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.Query;
|
||||
import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper;
|
||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
|
||||
import org.alfresco.rest.workflow.api.Processes;
|
||||
import org.alfresco.rest.workflow.api.impl.ProcessesImpl;
|
||||
import org.alfresco.rest.workflow.api.model.ProcessInfo;
|
||||
@@ -67,7 +67,7 @@ import junit.framework.TestCase;
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class ProcessesImplTest extends TestCase
|
||||
public class ProcessesImplTest extends TestCase implements RecognizedParamsExtractor
|
||||
{
|
||||
private static final String[] CONFIG_LOCATIONS = new String[ApplicationContextHelper.CONFIG_LOCATIONS.length + 2];
|
||||
static
|
||||
@@ -224,7 +224,7 @@ public class ProcessesImplTest extends TestCase
|
||||
|
||||
private CollectionWithPagingInfo<ProcessInfo> queryMatchesProcesses(String matchesString)
|
||||
{
|
||||
Query query = ResourceWebScriptHelper.getWhereClause(String.format(QUERY_WORKFLOWDESCRIPTION_MATCHES, matchesString));
|
||||
Query query = getWhereClause(String.format(QUERY_WORKFLOWDESCRIPTION_MATCHES, matchesString));
|
||||
Parameters parameters = Params.valueOf(new RecognizedParams(null, Paging.valueOf(0, ACTIVE_WORKFLOWS_INITIAL_AMOUNT), null, null, null, null, query, null, false), null, null, null);
|
||||
|
||||
return processes.getProcesses(parameters);
|
||||
@@ -232,7 +232,7 @@ public class ProcessesImplTest extends TestCase
|
||||
|
||||
private CollectionWithPagingInfo<ProcessInfo> queryActiveProcessesAndAssertResult(int skipCount, int maxItems)
|
||||
{
|
||||
Query query = ResourceWebScriptHelper.getWhereClause(QUERY_STATUS_ACTIVE);
|
||||
Query query = getWhereClause(QUERY_STATUS_ACTIVE);
|
||||
Parameters parameters = Params.valueOf(new RecognizedParams(null, Paging.valueOf(skipCount, maxItems), null, null, null, null, query, null, false), null, null, null);
|
||||
|
||||
CollectionWithPagingInfo<ProcessInfo> result = processes.getProcesses(parameters);
|
||||
|
Reference in New Issue
Block a user