diff --git a/source/java/org/alfresco/rest/framework/tools/RecognizedParamsExtractor.java b/source/java/org/alfresco/rest/framework/tools/RecognizedParamsExtractor.java index 96461246f5..c9cd7f76ab 100644 --- a/source/java/org/alfresco/rest/framework/tools/RecognizedParamsExtractor.java +++ b/source/java/org/alfresco/rest/framework/tools/RecognizedParamsExtractor.java @@ -23,6 +23,7 @@ * along with Alfresco. If not, see . * #L% */ + package org.alfresco.rest.framework.tools; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; @@ -74,16 +75,18 @@ public interface RecognizedParamsExtractor 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 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); + public static final List 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() { + 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 */ @@ -112,39 +115,28 @@ public interface RecognizedParamsExtractor BeanPropertiesFilter filter = getFilter((fields != null ? fields : properties), includedFields); - return new Params.RecognizedParams(requestParams, paging, filter, relationFilter, includedFields, selectFields, whereQuery, sorting, includeSource); + 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 - * + * 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 - * + * select=abc/blah * However the following will not return "abc/blah" if used with fields filtering, eg. - * - * select=abc/blah&fields=id,name,ghi - * + * 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 + * select=abc&fields=id,name,ghi * * @param filterParams * @param selectList @@ -178,9 +170,9 @@ public interface RecognizedParamsExtractor return BeanPropertiesFilter.ALLOW_ALL; } - /** * Takes the "select" parameter and turns it into a List property names + * * @param selectParam String * @return bean property names potentially using JSON Pointer syntax */ @@ -193,6 +185,7 @@ public interface RecognizedParamsExtractor /** * Takes the "include" parameter and turns it into a List property names + * * @param includeParam String * @return bean property names potentially using JSON Pointer syntax */ @@ -204,44 +197,48 @@ public interface RecognizedParamsExtractor /** * Gets the clause specificed in paramName + * * @param param * @param paramName * @return bean property names potentially using JSON Pointer syntax */ default List getClause(String param, String paramName) { - if (param == null) return Collections.emptyList(); + 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 children = (List) selectedPropsTree.getChildren(); - if (children!= null && !children.isEmpty()) - { - List properties = new ArrayList(children.size()); - for (Tree child : children) { - properties.add(child.getText()); - } - return properties; - } - } + 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 children = (List) selectedPropsTree.getChildren(); + if (children != null && !children.isEmpty()) + { + List properties = new ArrayList(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); - } + rpeLogger().debug("Unhandled Error parsing the " + paramName + " clause: " + re); + } catch (RecognitionException e) { - rpeLogger().debug("Error parsing the \"+paramName+\" clause: "+param); - } + rpeLogger().debug("Error parsing the \"+paramName+\" clause: " + param); + } catch (InvalidQueryException iqe) { throw new InvalidSelectException(paramName, iqe.getQueryParam()); @@ -249,29 +246,36 @@ public interface RecognizedParamsExtractor //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; + if (whereParam == null) + return QueryImpl.EMPTY; - try { + try + { CommonTree whereTree = WhereCompiler.compileWhereClause(whereParam); if (whereTree instanceof CommonErrorNode) { - rpeLogger().debug("Error parsing the WHERE clause "+whereTree); + 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); + } + 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); @@ -282,6 +286,7 @@ public interface RecognizedParamsExtractor * 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. */ @@ -308,15 +313,16 @@ public interface RecognizedParamsExtractor } else { - rpeLogger().debug("Invalid sort order definition ("+sortDef+"). Valid values are "+SortColumn.ASCENDING+" or "+SortColumn.DESCENDING+"."); + 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); + // logger.debug("Filtering using the following properties: " + filteredProperties); + // BeanPropertiesFilter filter = new BeanPropertiesFilter(filteredProperties); return sortedColumns; } return Collections.emptyList(); @@ -356,10 +362,8 @@ public interface RecognizedParamsExtractor 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 @@ -367,7 +371,7 @@ public interface RecognizedParamsExtractor * * @param filterParams String * @return BeanPropertyFilter - if no parameter then returns a new - * ReturnAllBeanProperties class + * ReturnAllBeanProperties class */ default BeanPropertiesFilter getFilter(String filterParams) { @@ -383,7 +387,7 @@ public interface RecognizedParamsExtractor * * @param filterParams String * @return BeanPropertiesFilter - if no parameter then returns a new - * ReturnAllBeanProperties class + * ReturnAllBeanProperties class */ default Map getRelationFilter(String filterParams) { @@ -414,7 +418,6 @@ public interface RecognizedParamsExtractor return Collections.emptyMap(); } - /** * Finds all request parameters that aren't already know about (eg. not paging or filter params) * and returns them for use. @@ -424,10 +427,10 @@ public interface RecognizedParamsExtractor */ default Map getRequestParameters(WebScriptRequest req) { - if (req!= null) + if (req != null) { String[] paramNames = req.getParameterNames(); - if (paramNames!= null) + if (paramNames != null) { Map requestParameteters = new HashMap(paramNames.length); diff --git a/source/java/org/alfresco/rest/framework/tools/RequestReader.java b/source/java/org/alfresco/rest/framework/tools/RequestReader.java index a87c524c28..9f8e07c49d 100644 --- a/source/java/org/alfresco/rest/framework/tools/RequestReader.java +++ b/source/java/org/alfresco/rest/framework/tools/RequestReader.java @@ -23,6 +23,7 @@ * along with Alfresco. If not, see . * #L% */ + package org.alfresco.rest.framework.tools; import org.alfresco.rest.framework.core.exceptions.ApiException; @@ -47,8 +48,8 @@ public interface RequestReader /** * Extracts the body contents from the request * - * @param req the request - * @param jsonHelper Jackson Helper + * @param req the request + * @param jsonHelper Jackson Helper * @param requiredType the type to return * @return the Object in the required type */ @@ -74,8 +75,8 @@ public interface RequestReader /** * 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 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 */ @@ -93,10 +94,9 @@ public interface RequestReader } } - default Log rrLogger() { + default Log rrLogger() + { return LogFactory.getLog(this.getClass()); } - - } diff --git a/source/java/org/alfresco/rest/framework/tools/ResponseWriter.java b/source/java/org/alfresco/rest/framework/tools/ResponseWriter.java index 8dbb264900..c2d27b598b 100644 --- a/source/java/org/alfresco/rest/framework/tools/ResponseWriter.java +++ b/source/java/org/alfresco/rest/framework/tools/ResponseWriter.java @@ -23,6 +23,7 @@ * along with Alfresco. If not, see . * #L% */ + package org.alfresco.rest.framework.tools; import org.alfresco.rest.framework.Api; @@ -66,7 +67,7 @@ public interface ResponseWriter { String UTF8 = "UTF-8"; - ContentInfo DEFAULT_JSON_CONTENT = new ContentInfoImpl(Format.JSON.mimetype(),UTF8, 0, null); + ContentInfo DEFAULT_JSON_CONTENT = new ContentInfoImpl(Format.JSON.mimetype(), UTF8, 0, null); Cache CACHE_NEVER = new Cache(new Description.RequiredCache() { @Override @@ -90,13 +91,15 @@ public interface ResponseWriter final WithResponse DEFAULT_SUCCESS = new WithResponse(Status.STATUS_OK, DEFAULT_JSON_CONTENT, CACHE_NEVER); - default Log resWriterLogger() { + default Log resWriterLogger() + { return LogFactory.getLog(this.getClass()); } /** * Sets the response headers with any information we know about the content - * @param res WebScriptResponse + * + * @param res WebScriptResponse * @param contentInfo Content Information */ default void setContentInfoOnResponse(WebScriptResponse res, ContentInfo contentInfo) @@ -134,7 +137,6 @@ public interface ResponseWriter /** * 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. * @@ -144,17 +146,18 @@ public interface ResponseWriter * @param contentInfo * @param headers */ - default void setResponse(final WebScriptResponse res, int status, Cache cache, ContentInfo contentInfo, Map> headers) + default void setResponse(final WebScriptResponse res, int status, Cache cache, ContentInfo contentInfo, Map> headers) { res.setStatus(status); if (cache != null) res.setCache(cache); setContentInfoOnResponse(res,contentInfo); if (headers != null && !headers.isEmpty()) { - for (Map.Entry> header:headers.entrySet()) + for (Map.Entry> header : headers.entrySet()) { - for (int i=0; i < header.getValue().size(); i++) { - if (i==0) + 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)); @@ -171,6 +174,7 @@ public interface ResponseWriter /** * Sets the response using the WithResponse object + * * @param res * @param withResponse */ @@ -181,29 +185,27 @@ public interface ResponseWriter /** * Renders a JSON error response + * * @param errorResponse The error - * @param res web script response + * @param res web script response * @throws IOException */ - default void renderErrorResponse(final ErrorResponse errorResponse, final WebScriptResponse res, final JacksonHelper jsonHelper) 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()); + 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); + final ErrorResponse errorToWrite = new ErrorResponse(errorResponse.getErrorKey(), errorResponse.getStatusCode(), + errorResponse.getBriefSummary(), stackMessage, logId, errorResponse.getAdditionalState(), DefaultExceptionResolver.ERROR_URL); setContentInfoOnResponse(res, DEFAULT_JSON_CONTENT); @@ -216,7 +218,7 @@ public interface ResponseWriter @SuppressWarnings("unchecked") @Override public void writeContents(JsonGenerator generator, ObjectMapper objectMapper) - throws JsonGenerationException, JsonMappingException, IOException + throws JsonGenerationException, JsonMappingException, IOException { JSONObject obj = new JSONObject(); obj.put("error", errorToWrite); @@ -225,32 +227,32 @@ public interface ResponseWriter }); } - /** * 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 { + 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 res WebScriptResponse * @param toSerialize result of an execution * @throws IOException */ - default void renderJsonResponse(final WebScriptResponse res, final Object toSerialize, final JacksonHelper jsonHelper) - 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 + throws JsonGenerationException, JsonMappingException, IOException { objectMapper.writeValue(generator, toSerialize); }