Add support for custom REST method parameter resolvers. Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/c9797b77 Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/c9797b77 Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/c9797b77
Branch: refs/heads/master Commit: c9797b7756a14929d4095c028d7174a8d0f694e6 Parents: d6fe4ff Author: JamesBognar <[email protected]> Authored: Mon May 8 10:50:58 2017 -0400 Committer: JamesBognar <[email protected]> Committed: Mon May 8 10:50:58 2017 -0400 ---------------------------------------------------------------------- juneau-core/src/main/javadoc/overview.html | 156 ++- .../org/apache/juneau/microservice/package.html | 4 +- .../java/org/apache/juneau/rest/CallMethod.java | 124 +-- .../java/org/apache/juneau/rest/RestConfig.java | 17 +- .../org/apache/juneau/rest/RestContext.java | 92 ++ .../java/org/apache/juneau/rest/RestParam.java | 914 +----------------- .../apache/juneau/rest/RestParamDefaults.java | 944 +++++++++++++++++++ .../juneau/rest/annotation/RestResource.java | 32 + .../java/org/apache/juneau/rest/package.html | 106 ++- 9 files changed, 1286 insertions(+), 1103 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-core/src/main/javadoc/overview.html ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html index 44ef436..ae07cf3 100644 --- a/juneau-core/src/main/javadoc/overview.html +++ b/juneau-core/src/main/javadoc/overview.html @@ -3101,9 +3101,10 @@ <li class='m'><l>doGetExample2()</l> <br>Identical to <l>doGetExample1()</l> but shows how to use the {@link org.apache.juneau.rest.RestRequest} and {@link org.apache.juneau.rest.RestResponse} objects: <ul> - <li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Class)} - <li class='m'>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Class)} - <li class='m'>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Class)} + <li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathParams()} + <li class='m'>{@link org.apache.juneau.rest.RestRequest#getQuery()} + <li class='m'>{@link org.apache.juneau.rest.RestRequest#getFormData()} + <li class='m'>{@link org.apache.juneau.rest.RestRequest#getHeaders()} <li class='m'>{@link org.apache.juneau.rest.RestRequest#getMethod()} <li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathRemainder()} </ul> @@ -5934,6 +5935,69 @@ <li>{@link org.apache.juneau.rest.RequestFormData} <li>{@link org.apache.juneau.rest.RequestPathParams} </ul> + <li>The unannotated parameter types that can be passed in through REST Java methods has been significantly expanded. + <br>For reference, the previous supported types were: + <ul> + <li>{@link org.apache.juneau.rest.RestRequest} - The request object. + <li>{@link javax.servlet.http.HttpServletRequest} - The superclass of <code>RestRequest</code>. + <li>{@link org.apache.juneau.rest.RestResponse} - The response object. + <li>{@link javax.servlet.http.HttpServletResponse} - The superclass of <code>RestResponse</code>. + </ul> + The new supported types are: + <ul> + <li>{@link org.apache.juneau.http.Accept} + <li>{@link org.apache.juneau.http.AcceptCharset} + <li>{@link org.apache.juneau.http.AcceptEncoding} + <li>{@link org.apache.juneau.http.AcceptLanguage} + <li>{@link org.apache.juneau.http.Authorization} + <li>{@link org.apache.juneau.http.CacheControl} + <li>{@link org.apache.juneau.http.Connection} + <li>{@link org.apache.juneau.http.ContentLength} + <li>{@link org.apache.juneau.http.ContentType} + <li>{@link org.apache.juneau.http.Date} + <li>{@link org.apache.juneau.http.Expect} + <li>{@link org.apache.juneau.http.From} + <li>{@link org.apache.juneau.http.Host} + <li>{@link org.apache.juneau.http.IfMatch} + <li>{@link org.apache.juneau.http.IfModifiedSince} + <li>{@link org.apache.juneau.http.IfNoneMatch} + <li>{@link org.apache.juneau.http.IfRange} + <li>{@link org.apache.juneau.http.IfUnmodifiedSince} + <li>{@link org.apache.juneau.http.MaxForwards} + <li>{@link org.apache.juneau.http.Pragma} + <li>{@link org.apache.juneau.http.ProxyAuthorization} + <li>{@link org.apache.juneau.http.Range} + <li>{@link org.apache.juneau.http.Referer} + <li>{@link org.apache.juneau.http.TE} + <li>{@link org.apache.juneau.http.UserAgent} + <li>{@link org.apache.juneau.http.Upgrade} + <li>{@link org.apache.juneau.http.Via} + <li>{@link org.apache.juneau.http.Warning} + <li>{@link java.util.TimeZone} + <li>{@link java.io.InputStream} + <li>{@link javax.servlet.ServletInputStream} + <li>{@link java.io.Reader} + <li>{@link java.io.OutputStream} + <li>{@link javax.servlet.ServletOutputStream} + <li>{@link java.io.Writer} + <li>{@link java.util.ResourceBundle} - Client-localized resource bundle. + <li>{@link org.apache.juneau.utils.MessageBundle} - A resource bundle with additional features. + <li>{@link java.util.Locale} - Client locale. + <li>{@link org.apache.juneau.rest.RequestHeaders} - API for accessing request headers. + <li>{@link org.apache.juneau.rest.RequestQuery} - API for accessing request query parameters. + <li>{@link org.apache.juneau.rest.RequestFormData} - API for accessing request form data. + <li>{@link org.apache.juneau.rest.RequestPathParams} - API for accessing path variables. + <li>{@link org.apache.juneau.rest.RequestBody} - API for accessing request body. + <li>{@link org.apache.juneau.http.HttpMethod} - The method name matched (when using <code><ja>@RestMethod</ja>(name=<js>"*"</js>)</code>) + <li>{@link java.util.logging.Logger} - The logger to use for logging. + <li>{@link org.apache.juneau.internal.JuneauLogger} - Logger with additional features. + <li>{@link org.apache.juneau.rest.RestContext} - The resource read-only context. + <li>{@link org.apache.juneau.parser.Parser} - The parser matching the request content type. + <li>{@link org.apache.juneau.dto.swagger.Swagger} - The auto-generated Swagger doc. + <li>{@link org.apache.juneau.ini.ConfigFile} - The external config file for the resource. + </ul> + <li>A new annotation {@link org.apache.juneau.rest.annotation.RestResource#paramResolvers() @RestResource.paramResolvers()} + that allows you to define your own custom Java method parameter resolvers. </ul> <h6 class='topic'>org.apache.juneau.rest.client</h6> @@ -6448,28 +6512,28 @@ <h6 class='topic'>org.apache.juneau.rest</h6> <ul class='spaced-list'> <li>{@link org.apache.juneau.rest.RestRequest} now passes locale and timezone to serializers/parsers/transforms. - <li>New {@link org.apache.juneau.rest.RestRequest#getTimeZone()} method. + <li><code><del>RestRequest.getTimeZone()</del></code> method. <li>Standardized the following methods in {@link org.apache.juneau.rest.RestRequest} to remove dependency on <code>ClassMeta</code> objects and eliminate the need for casts: <ul> - <li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Class) getHeader(String,Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Object,Class) getHeader(String)} - <li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Type,Type...)} - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Object,Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Type,Type...)} - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Object,Type,Type...)} - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Type,Type...)} - <li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Object,Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameters(String,Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Type,Type...)} - <li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameters(String,Type,Type...)} - <li>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Type,Type...)} - <li>{@link org.apache.juneau.rest.RestRequest#getBody(Class)} - <li>{@link org.apache.juneau.rest.RestRequest#getBody(Type,Type...)} + <li><code><del>RestRequest.getHeader(String,Class)</del></code> + <li><code><del>RestRequest.getHeader(String,Object,Class)</del></code> + <li><code><del>RestRequest.getHeader(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getQueryParameter(String,Class)</del></code> + <li><code><del>RestRequest.getQueryParameter(String,Object,Class)</del></code> + <li><code><del>RestRequest.getQueryParameter(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getQueryParameter(String,Object,Type,Type...)</del></code> + <li><code><del>RestRequest.getQueryParameters(String,Class)</del></code> + <li><code><del>RestRequest.getQueryParameters(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getFormDataParameter(String,Class)</del></code> + <li><code><del>RestRequest.getFormDataParameter(String,Object,Class)</del></code> + <li><code><del>RestRequest.getFormDataParameters(String,Class)</del></code> + <li><code><del>RestRequest.getFormDataParameter(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getFormDataParameters(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getPathParameter(String,Class)</del></code> + <li><code><del>RestRequest.getPathParameter(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getBody(Class)</del></code> + <li><code><del>RestRequest.getBody(Type,Type...)</del></code> </ul> <li>New methods on {@link org.apache.juneau.rest.client.NameValuePairs} <li>Fixed issue where whitespace was not added to UON/URL-Encoding output when <code>&plainText=true</code> specified. @@ -7365,8 +7429,8 @@ <ul> <li>Added new methods: <ul> - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameterMap()} - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameterNames()} + <li><code><del>RestRequest.getQueryParameterMap()</del></code> + <li><code><del>RestRequest.getQueryParameterNames()</del></code> <li>{@link org.apache.juneau.rest.RestRequest#getPathInfoUndecoded()} <li>{@link org.apache.juneau.rest.RestRequest#getPathRemainderUndecoded()} <li>{@link org.apache.juneau.rest.RestRequest#getTrimmedRequestURI()} @@ -7515,24 +7579,24 @@ <ul class='spaced-list'> <li>New methods in {@link org.apache.juneau.rest.client.RestCall}: <ol> -<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Object,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Type,Type...)} -<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Object,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Type,Type...)} -<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Object,Type,Type...)} -<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Type,Type...)} -<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Object,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameters(String,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Type,Type...)} -<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameters(String,Type,Type...)} -<li>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Type,Type...)} -<li>{@link org.apache.juneau.rest.RestRequest#getBody(Class)} -<li>{@link org.apache.juneau.rest.RestRequest#getBody(Type,Type...)} + <li><code><del>RestRequest.getHeader(String,Class)</del></code> + <li><code><del>RestRequest.getHeader(String,Object,Class)</del></code> + <li><code><del>RestRequest.getHeader(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getQueryParameter(String,Class)</del></code> + <li><code><del>RestRequest.getQueryParameter(String,Object,Class)</del></code> + <li><code><del>RestRequest.getQueryParameter(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getQueryParameter(String,Object,Type,Type...)</del></code> + <li><code><del>RestRequest.getQueryParameters(String,Class)</del></code> + <li><code><del>RestRequest.getQueryParameters(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getFormDataParameter(String,Class)</del></code> + <li><code><del>RestRequest.getFormDataParameter(String,Object,Class)</del></code> + <li><code><del>RestRequest.getFormDataParameters(String,Class)</del></code> + <li><code><del>RestRequest.getFormDataParameter(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getFormDataParameters(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getPathParameter(String,Class)</del></code> + <li><code><del>RestRequest.getPathParameter(String,Type,Type...)</del></code> + <li><code><del>RestRequest.getBody(Class)</del></code> + <li><code><del>RestRequest.getBody(Type,Type...)</del></code> </ol> </li> </ul> @@ -7572,8 +7636,8 @@ explicitely specify which HTTP methods can be used in the <code>&method</code> parameter. <li>New methods added to {@link org.apache.juneau.rest.RestRequest}: <ul> - <li>{@link org.apache.juneau.rest.RestRequest#getParser()} - <li>{@link org.apache.juneau.rest.RestRequest#getReaderParser()} + <li><code><del>RestRequest.getParser()</del></code> + <li><code><del>RestRequest.getReaderParser()</del></code> </ul> </ul> </div> @@ -7697,7 +7761,7 @@ <li>New methods on {@link org.apache.juneau.rest.RestRequest} for handling multi-part parameters: <ul> <li><del><code>RestRequest.getParameters(String,Class)</code></del> - <li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Class)} + <li><code><del>RestRequest#getQueryParameters(String,Class)</del></code> </ul> </li> <li>Fixed Jetty issue in {@link org.apache.juneau.rest.RestResponse#setHeader(String,String)} where setting @@ -7757,7 +7821,7 @@ <li>Fixed major issue that prevented parsing URL-Encoded form posts into POJOs. Calling <del><code>HttpServlet.getParameter(String)</code></del> was forcing the underlying servlet code to process the HTTP body itself, preventing the <code>UrlEncodingSerializer</code> class from being able to parse the content. Updated code no longer inadvertantly calls this method. - <li>New {@link org.apache.juneau.rest.RestRequest#getQueryParameter(String)}, {@link org.apache.juneau.rest.RestRequest#hasQueryParameter(String)}, and {@link org.apache.juneau.rest.RestRequest#hasAnyQueryParameters(String[])} + <li>New <code><del>RestRequest.getQueryParameter(String)</del></code>, <code><del>RestRequest.hasQueryParameter(String)</del></code>, and <code><del>RestRequest.hasAnyQueryParameters(String[])</del></code> methods that only look for parameters in the URL query string to prevent loading and parsing of URL-Encoded form posts. <li>New <del><code>@QParam</code></del> and <del><code>@HasQParam</code></del> annotations for accessing query parameters from the URL query string. <li><code>&plainText</code> parameter can now specify a false value. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html ---------------------------------------------------------------------- diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html b/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html index 614e64a..2595771 100755 --- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html +++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html @@ -652,14 +652,14 @@ <ul> <li><l>$R{attribute.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getAttribute(String)} converted to a string. <li><l>$R{contextPath}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getContextPath()}. - <li><l>$R{formData.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String)}. + <li><l>$R{formData.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getFormData(String)}. <li><l>$R{header.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getHeader(String)}. <li><l>$R{method}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethod()}. <li><l>$R{methodSummary}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethodSummary()}. <li><l>$R{methodDescription}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethodDescription()}. <li><l>$R{path.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getPathParameter(String)}. <li><l>$R{pathInfo}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getPathInfo()}. - <li><l>$R{query.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getQueryParameter(String)}. + <li><l>$R{query.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getQuery(String)}. <li><l>$R{requestParentURI}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getRequestParentURI()}. <li><l>$R{requestURI}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getRequestURI()}. <li><l>$R{servletDescription}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getServletDescription()}. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java index afc7a1e..4fe77de 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java @@ -18,12 +18,10 @@ import static org.apache.juneau.rest.RestContext.*; import static org.apache.juneau.rest.annotation.Inherit.*; import static org.apache.juneau.serializer.SerializerContext.*; -import java.lang.annotation.*; import java.lang.reflect.*; import java.lang.reflect.Method; import java.util.*; -import javax.servlet.*; import javax.servlet.http.*; import org.apache.juneau.*; @@ -34,7 +32,6 @@ import org.apache.juneau.internal.*; import org.apache.juneau.json.*; import org.apache.juneau.parser.*; import org.apache.juneau.rest.annotation.*; -import org.apache.juneau.rest.annotation.Properties; import org.apache.juneau.serializer.*; import org.apache.juneau.svl.*; import org.apache.juneau.urlencoding.*; @@ -47,7 +44,7 @@ class CallMethod implements Comparable<CallMethod> { private final java.lang.reflect.Method method; private final String httpMethod; private final UrlPathPattern pathPattern; - private final CallMethod.MethodParam[] params; + private final RestParam[] params; private final RestGuard[] guards; private final RestMatcher[] optionalMatchers; private final RestMatcher[] requiredMatchers; @@ -103,7 +100,7 @@ class CallMethod implements Comparable<CallMethod> { private static class Builder { private String httpMethod, defaultCharset, description, tags, summary, externalDocs, pageTitle, pageText, pageLinks; private UrlPathPattern pathPattern; - private CallMethod.MethodParam[] params; + private RestParam[] params; private RestGuard[] guards; private RestMatcher[] optionalMatchers, requiredMatchers; private RestConverter[] converters; @@ -276,14 +273,7 @@ class CallMethod implements Comparable<CallMethod> { pathPattern = new UrlPathPattern(p); - int attrIdx = 0; - Type[] pt = method.getGenericParameterTypes(); - Annotation[][] pa = method.getParameterAnnotations(); - params = new CallMethod.MethodParam[pt.length]; - for (int i = 0; i < params.length; i++) { - params[i] = new CallMethod.MethodParam(pt[i], method, pa[i], plainParams, pathPattern, attrIdx); - attrIdx = params[i].attrIdx; - } + params = context.findParams(method, plainParams, pathPattern); if (sgb != null) serializers = sgb.build(); @@ -303,110 +293,6 @@ class CallMethod implements Comparable<CallMethod> { } /** - * Represents a single parameter in the Java method. - */ - private static class MethodParam { - - private final int attrIdx; - private final RestParam param; - - private MethodParam(Type type, Method method, Annotation[] annotations, boolean methodPlainParams, UrlPathPattern pathPattern, int attrIdx) throws ServletException { - - RestParam _param = null; - String _name = ""; - - boolean isClass = type instanceof Class; - if (isClass) - _param = RestParam.STANDARD_RESOLVERS.get(type); - - if (_param == null) { - for (Annotation a : annotations) { - if (a instanceof Path) { - Path a2 = (Path)a; - _name = a2.value(); - } else if (a instanceof Header) { - _param = new RestParam.HeaderObject(((Header)a).value(), type); - } else if (a instanceof FormData) { - FormData p = (FormData)a; - if (p.multipart()) - assertCollection(type, method); - boolean plainParams = p.format().equals("INHERIT") ? methodPlainParams : p.format().equals("PLAIN"); - _param = new RestParam.FormDataObject(p.value(), type, p.multipart(), plainParams); - } else if (a instanceof Query) { - Query p = (Query)a; - if (p.multipart()) - assertCollection(type, method); - boolean plainParams = p.format().equals("INHERIT") ? methodPlainParams : p.format().equals("PLAIN"); - _param = new RestParam.QueryObject(p.value(), type, p.multipart(), plainParams); - } else if (a instanceof HasFormData) { - _param = new RestParam.HasFormDataObject(((HasFormData)a).value(), type); - } else if (a instanceof HasQuery) { - _param = new RestParam.HasQueryObject(((HasQuery)a).value(), type); - } else if (a instanceof Body) { - _param = new RestParam.BodyObject(type); - } else if (a instanceof org.apache.juneau.rest.annotation.Method) { - _param = new RestParam.MethodObject(type); - } else if (a instanceof PathRemainder) { - _param = new RestParam.PathRemainderObject(type); - } else if (a instanceof Properties) { - _param = new RestParam.PropsObject(type); - } else if (a instanceof Messages) { - _param = new RestParam.MessageBundleObject(); - } - } - } - - if (_param == null) { - - if (_name.isEmpty()) { - int idx = attrIdx++; - String[] vars = pathPattern.getVars(); - if (vars.length <= idx) - throw new RestServletException("Number of attribute parameters in method ''{0}'' exceeds the number of URL pattern variables.", method.getName()); - - // Check for {#} variables. - String idxs = String.valueOf(idx); - for (int i = 0; i < vars.length; i++) - if (StringUtils.isNumeric(vars[i]) && vars[i].equals(idxs)) - _name = vars[i]; - - if (_name.isEmpty()) - _name = pathPattern.getVars()[idx]; - } - _param = new RestParam.PathParameterObject(_name, type); - } - - this.param = _param; - this.attrIdx = attrIdx; - } - - /** - * Throws an exception if the specified type isn't an array or collection. - */ - private static void assertCollection(Type t, Method m) throws ServletException { - ClassMeta<?> cm = BeanContext.DEFAULT.getClassMeta(t); - if (! cm.isCollectionOrArray()) - throw new ServletException("Use of multipart flag on parameter that's not an array or Collection on method" + m); - } - - private Object getValue(RestRequest req, RestResponse res) throws Exception { - return param.resolve(req, res); - } - - private RestParamType getParamType() { - return param.getParamType(); - } - - private String getName() { - return param.getName(); - } - - private Type getType() { - return param.getType(); - } - } - - /** * Returns <jk>true</jk> if this Java method has any guards or matchers. */ boolean hasGuardsOrMatchers() { @@ -633,7 +519,7 @@ class CallMethod implements Comparable<CallMethod> { } // Finally, look for parameters defined on method. - for (CallMethod.MethodParam mp : this.params) { + for (RestParam mp : this.params) { RestParamType in = mp.getParamType(); if (in != RestParamType.OTHER) { String k2 = in.toString() + '.' + (in == RestParamType.BODY ? null : mp.getName()); @@ -800,7 +686,7 @@ class CallMethod implements Comparable<CallMethod> { Object[] args = new Object[params.length]; for (int i = 0; i < params.length; i++) { try { - args[i] = params[i].getValue(req, res); + args[i] = params[i].resolve(req, res); } catch (RestException e) { throw e; } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java index 2a33a34..a04c95e 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java @@ -85,7 +85,8 @@ public class RestConfig implements ServletConfig { List<Class<?>> beanFilters = new ArrayList<Class<?>>(), - pojoSwaps = new ArrayList<Class<?>>(); + pojoSwaps = new ArrayList<Class<?>>(), + paramResolvers = new ArrayList<Class<?>>(); SerializerGroupBuilder serializers = new SerializerGroupBuilder(); ParserGroupBuilder parsers = new ParserGroupBuilder(); EncoderGroupBuilder encoders = new EncoderGroupBuilder().append(IdentityEncoder.INSTANCE); @@ -184,6 +185,7 @@ public class RestConfig implements ServletConfig { addChildResources(r.children()); addBeanFilters(r.beanFilters()); addPojoSwaps(r.pojoSwaps()); + addParamResolvers(r.paramResolvers()); if (! r.stylesheet().isEmpty()) setStyleSheet(c, r.stylesheet()); if (! r.favicon().isEmpty()) @@ -362,6 +364,19 @@ public class RestConfig implements ServletConfig { } /** + * Adds class-level parameter resolvers to this resource. + * <p> + * This is the programmatic equivalent to the {@link RestResource#paramResolvers() @RestResource.paramResolvers()} annotation. + * + * @param paramResolvers The parameter resolvers to add to this config. + * @return This object (for method chaining). + */ + public RestConfig addParamResolvers(Class<? extends RestParam>...paramResolvers) { + this.paramResolvers.addAll(Arrays.asList(paramResolvers)); + return this; + } + + /** * Adds class-level serializers to this resource. * <p> * This is the programmatic equivalent to the {@link RestResource#serializers() @RestResource.serializers()} annotation. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java index 54a3fa0..258ff01 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java @@ -16,6 +16,7 @@ import static javax.servlet.http.HttpServletResponse.*; import static org.apache.juneau.internal.StringUtils.*; import java.io.*; +import java.lang.annotation.*; import java.lang.reflect.*; import java.lang.reflect.Method; import java.util.*; @@ -33,6 +34,7 @@ import org.apache.juneau.internal.*; import org.apache.juneau.json.*; import org.apache.juneau.parser.*; import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.rest.annotation.Properties; import org.apache.juneau.rest.vars.*; import org.apache.juneau.serializer.*; import org.apache.juneau.svl.*; @@ -300,6 +302,7 @@ public final class RestContext extends Context { private final Class<?>[] beanFilters, pojoSwaps; + private final Map<Class<?>,RestParam> paramResolvers; private final SerializerGroup serializers; private final ParserGroup parsers; private final UrlEncodingSerializer urlEncodingSerializer; @@ -366,6 +369,7 @@ public final class RestContext extends Context { this.properties = b.properties; this.beanFilters = b.beanFilters; this.pojoSwaps = b.pojoSwaps; + this.paramResolvers = Collections.unmodifiableMap(b.paramResolvers); this.serializers = b.serializers; this.parsers = b.parsers; this.urlEncodingSerializer = b.urlEncodingSerializer; @@ -557,6 +561,7 @@ public final class RestContext extends Context { ObjectMap properties; Class<?>[] beanFilters; Class<?>[] pojoSwaps; + Map<Class<?>,RestParam> paramResolvers = new HashMap<Class<?>,RestParam>(); SerializerGroup serializers; ParserGroup parsers; UrlEncodingSerializer urlEncodingSerializer; @@ -609,6 +614,12 @@ public final class RestContext extends Context { Collections.reverse(sc.pojoSwaps); beanFilters = ArrayUtils.toObjectArray(sc.beanFilters, Class.class); pojoSwaps = ArrayUtils.toObjectArray(sc.pojoSwaps, Class.class); + + for (Class<?> c : sc.paramResolvers) { + RestParam rp = (RestParam)c.newInstance(); + paramResolvers.put(rp.forClass(), rp); + } + clientVersionHeader = sc.clientVersionHeader; // Find resource resource bundle location. @@ -1254,6 +1265,87 @@ public final class RestContext extends Context { } /** + * Finds the {@link RestParam} instances to handle resolving objects on the calls to the specified Java method. + * + * @param method The Java method being called. + * @param methodPlainParams Whether plain-params setting is specified. + * @param pathPattern The parsed URL path pattern. + * @return The array of resolvers. + * @throws ServletException If an annotation usage error was detected. + */ + protected RestParam[] findParams(Method method, boolean methodPlainParams, UrlPathPattern pathPattern) throws ServletException { + + Type[] pt = method.getGenericParameterTypes(); + Annotation[][] pa = method.getParameterAnnotations(); + RestParam[] rp = new RestParam[pt.length]; + int attrIndex = 0; + + for (int i = 0; i < pt.length; i++) { + + Type t = pt[i]; + if (t instanceof Class) { + Class<?> c = (Class<?>)t; + rp[i] = paramResolvers.get(c); + if (rp[i] == null) + rp[i] = RestParamDefaults.STANDARD_RESOLVERS.get(c); + } + + if (rp[i] == null) { + for (Annotation a : pa[i]) { + if (a instanceof Header) + rp[i] = new RestParamDefaults.HeaderObject((Header)a, t); + else if (a instanceof FormData) + rp[i] = new RestParamDefaults.FormDataObject(method, (FormData)a, t, methodPlainParams); + else if (a instanceof Query) + rp[i] = new RestParamDefaults.QueryObject(method, (Query)a, t, methodPlainParams); + else if (a instanceof HasFormData) + rp[i] = new RestParamDefaults.HasFormDataObject(method, (HasFormData)a, t); + else if (a instanceof HasQuery) + rp[i] = new RestParamDefaults.HasQueryObject(method, (HasQuery)a, t); + else if (a instanceof Body) + rp[i] = new RestParamDefaults.BodyObject(t); + else if (a instanceof org.apache.juneau.rest.annotation.Method) + rp[i] = new RestParamDefaults.MethodObject(method, t); + else if (a instanceof PathRemainder) + rp[i] = new RestParamDefaults.PathRemainderObject(method, t); + else if (a instanceof Properties) + rp[i] = new RestParamDefaults.PropsObject(method, t); + else if (a instanceof Messages) + rp[i] = new RestParamDefaults.MessageBundleObject(); + } + } + + if (rp[i] == null) { + Path p = null; + for (Annotation a : pa[i]) + if (a instanceof Path) + p = (Path)a; + + String name = (p == null ? "" : p.value()); + + if (name.isEmpty()) { + int idx = attrIndex++; + String[] vars = pathPattern.getVars(); + if (vars.length <= idx) + throw new RestServletException("Number of attribute parameters in method ''{0}'' exceeds the number of URL pattern variables.", method.getName()); + + // Check for {#} variables. + String idxs = String.valueOf(idx); + for (int j = 0; j < vars.length; j++) + if (StringUtils.isNumeric(vars[j]) && vars[j].equals(idxs)) + name = vars[j]; + + if (name.isEmpty()) + name = pathPattern.getVars()[idx]; + } + rp[i] = new RestParamDefaults.PathParameterObject(name, t); + } + } + + return rp; + } + + /** * Returns the URL-encoding parser associated with this resource. * @return The URL-encoding parser associated with this resource. Never <jk>null</jk>. */ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java index c6e176e..4e834b4 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java @@ -12,114 +12,20 @@ // *************************************************************************************************************************** package org.apache.juneau.rest; -import static org.apache.juneau.rest.RestParamType.*; - -import java.io.*; import java.lang.reflect.*; -import java.util.*; -import java.util.logging.*; - -import javax.servlet.*; -import javax.servlet.http.*; -import org.apache.juneau.*; -import org.apache.juneau.dto.swagger.*; -import org.apache.juneau.http.*; -import org.apache.juneau.http.Date; -import org.apache.juneau.ini.*; -import org.apache.juneau.internal.*; -import org.apache.juneau.parser.*; -import org.apache.juneau.utils.*; +import org.apache.juneau.rest.annotation.*; /** * REST java method parameter resolver. + * <p> + * Used to resolve instances of classes being passed to Java REST methods. + * <p> + * This class is associated with REST classes via the {@link RestResource#paramResolvers()} annotation and + * {@link RestConfig#addParamResolvers(Class...)} method. */ public abstract class RestParam { - /** - * Standard set of method parameter resolvers. - */ - public static final Map<Class<?>,RestParam> STANDARD_RESOLVERS; - - static { - Map<Class<?>,RestParam> m = new HashMap<Class<?>,RestParam>(); - - @SuppressWarnings("rawtypes") - Class[] r = new Class[] { - - // Standard top-level objects - HttpServletRequestObject.class, - RestRequestObject.class, - HttpServletResponseObject.class, - RestResponseObject.class, - - // Headers - AcceptHeader.class, - AcceptCharsetHeader.class, - AcceptEncodingHeader.class, - AcceptLanguageHeader.class, - AuthorizationHeader.class, - CacheControlHeader.class, - ConnectionHeader.class, - ContentLengthHeader.class, - ContentTypeHeader.class, - DateHeader.class, - ExpectHeader.class, - FromHeader.class, - HostHeader.class, - IfMatchHeader.class, - IfModifiedSinceHeader.class, - IfNoneMatchHeader.class, - IfRangeHeader.class, - IfUnmodifiedSinceHeader.class, - MaxForwardsHeader.class, - PragmaHeader.class, - ProxyAuthorizationHeader.class, - RangeHeader.class, - RefererHeader.class, - TEHeader.class, - UserAgentHeader.class, - UpgradeHeader.class, - ViaHeader.class, - WarningHeader.class, - TimeZoneHeader.class, - - // Other objects - ResourceBundleObject.class, - MessageBundleObject.class, - InputStreamObject.class, - ServletInputStreamObject.class, - ReaderObject.class, - OutputStreamObject.class, - ServletOutputStreamObject.class, - WriterObject.class, - RequestHeadersObject.class, - RequestQueryParamsObject.class, - RequestFormDataObject.class, - HttpMethodObject.class, - LoggerObject.class, - JuneauLoggerObject.class, - RestContextObject.class, - ParserObject.class, - LocaleObject.class, - SwaggerObject.class, - RequestPathParamsObject.class, - RequestBodyObject.class, - ConfigFileObject.class, - }; - - for (Class<?> c : r) { - try { - RestParam mpr = (RestParam)c.newInstance(); - m.put(mpr.forClass(), mpr); - } catch (Exception e) { - e.printStackTrace(); - } - } - - STANDARD_RESOLVERS = Collections.unmodifiableMap(m); - } - final RestParamType paramType; final String name; final Type type; @@ -181,812 +87,4 @@ public abstract class RestParam { public Type getType() { return type; } - - //------------------------------------------------------------------------------------------------------------------- - // Request / Response retrievers - //------------------------------------------------------------------------------------------------------------------- - - static final class HttpServletRequestObject extends RestParam { - - protected HttpServletRequestObject() { - super(OTHER, null, HttpServletRequest.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) { - return req; - } - } - - static final class HttpServletResponseObject extends RestParam { - - protected HttpServletResponseObject() { - super(OTHER, null, HttpServletResponse.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) { - return res; - } - } - - static final class RestRequestObject extends RestParam { - - protected RestRequestObject() { - super(OTHER, null, RestRequest.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) { - return req; - } - } - - static final class RestResponseObject extends RestParam { - - protected RestResponseObject() { - super(OTHER, null, RestResponse.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) { - return res; - } - } - - //------------------------------------------------------------------------------------------------------------------- - // Header retrievers - //------------------------------------------------------------------------------------------------------------------- - - static final class AcceptHeader extends RestParam { - - protected AcceptHeader() { - super(HEADER, "Accept-Header", Accept.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getAccept(); - } - } - - static final class AcceptCharsetHeader extends RestParam { - - protected AcceptCharsetHeader() { - super(HEADER, "Accept-Charset", AcceptCharset.class); - } - - @Override /* RestParam */ - public AcceptCharset resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getAcceptCharset(); - } - } - - static final class AcceptEncodingHeader extends RestParam { - - protected AcceptEncodingHeader() { - super(HEADER, "Accept-Encoding", AcceptEncoding.class); - } - - @Override - public AcceptEncoding resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getAcceptEncoding(); - } - } - - static final class AcceptLanguageHeader extends RestParam { - - protected AcceptLanguageHeader() { - super(HEADER, "Accept-Language", AcceptLanguage.class); - } - - @Override - public AcceptLanguage resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getAcceptLanguage(); - } - } - - static final class AuthorizationHeader extends RestParam { - - protected AuthorizationHeader() { - super(HEADER, "Authorization", Authorization.class); - } - - @Override - public Authorization resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getAuthorization(); - } - } - - static final class CacheControlHeader extends RestParam { - - protected CacheControlHeader() { - super(HEADER, "Cache-Control", CacheControl.class); - } - - @Override - public CacheControl resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getCacheControl(); - } - } - - static final class ConnectionHeader extends RestParam { - - protected ConnectionHeader() { - super(HEADER, "Connection", Connection.class); - } - - @Override - public Connection resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getConnection(); - } - } - - static final class ContentLengthHeader extends RestParam { - - protected ContentLengthHeader() { - super(HEADER, "Content-Length", ContentLength.class); - } - - @Override - public ContentLength resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getContentLength(); - } - } - - static final class ContentTypeHeader extends RestParam { - - protected ContentTypeHeader() { - super(HEADER, "Content-Type", ContentType.class); - } - - @Override - public ContentType resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getContentType(); - } - } - - static final class DateHeader extends RestParam { - - protected DateHeader() { - super(HEADER, "Date", Date.class); - } - - @Override - public Date resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getDate(); - } - } - - static final class ExpectHeader extends RestParam { - - protected ExpectHeader() { - super(HEADER, "Expect", Expect.class); - } - - @Override - public Expect resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getExpect(); - } - } - - static final class FromHeader extends RestParam { - - protected FromHeader() { - super(HEADER, "From", From.class); - } - - @Override - public From resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getFrom(); - } - } - - static final class HostHeader extends RestParam { - - protected HostHeader() { - super(HEADER, "Host", Host.class); - } - - @Override - public Host resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getHost(); - } - } - - static final class IfMatchHeader extends RestParam { - - protected IfMatchHeader() { - super(HEADER, "If-Match", IfMatch.class); - } - - @Override - public IfMatch resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getIfMatch(); - } - } - - static final class IfModifiedSinceHeader extends RestParam { - - protected IfModifiedSinceHeader() { - super(HEADER, "If-Modified-Since", IfModifiedSince.class); - } - - @Override - public IfModifiedSince resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getIfModifiedSince(); - } - } - - static final class IfNoneMatchHeader extends RestParam { - - protected IfNoneMatchHeader() { - super(HEADER, "If-None-Match", IfNoneMatch.class); - } - - @Override - public IfNoneMatch resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getIfNoneMatch(); - } - } - - static final class IfRangeHeader extends RestParam { - - protected IfRangeHeader() { - super(HEADER, "If-Range", IfRange.class); - } - - @Override - public IfRange resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getIfRange(); - } - } - - static final class IfUnmodifiedSinceHeader extends RestParam { - - protected IfUnmodifiedSinceHeader() { - super(HEADER, "If-Unmodified-Since", IfUnmodifiedSince.class); - } - - @Override - public IfUnmodifiedSince resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getIfUnmodifiedSince(); - } - } - - static final class MaxForwardsHeader extends RestParam { - - protected MaxForwardsHeader() { - super(HEADER, "Max-Forwards", MaxForwards.class); - } - - @Override - public MaxForwards resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getMaxForwards(); - } - } - - static final class PragmaHeader extends RestParam { - - protected PragmaHeader() { - super(HEADER, "Pragma", Pragma.class); - } - - @Override - public Pragma resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getPragma(); - } - } - - static final class ProxyAuthorizationHeader extends RestParam { - - protected ProxyAuthorizationHeader() { - super(HEADER, "Proxy-Authorization", ProxyAuthorization.class); - } - - @Override - public ProxyAuthorization resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getProxyAuthorization(); - } - } - - static final class RangeHeader extends RestParam { - - protected RangeHeader() { - super(HEADER, "Range", Range.class); - } - - @Override - public Range resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getRange(); - } - } - - static final class RefererHeader extends RestParam { - - protected RefererHeader() { - super(HEADER, "Referer", Referer.class); - } - - @Override - public Referer resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getReferer(); - } - } - - static final class TEHeader extends RestParam { - - protected TEHeader() { - super(HEADER, "TE", TE.class); - } - - @Override - public TE resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getTE(); - } - } - - static final class UserAgentHeader extends RestParam { - - protected UserAgentHeader() { - super(HEADER, "User-Agent", UserAgent.class); - } - - @Override - public UserAgent resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getUserAgent(); - } - } - - static final class UpgradeHeader extends RestParam { - - protected UpgradeHeader() { - super(HEADER, "Upgrade", Upgrade.class); - } - - @Override - public Upgrade resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getUpgrade(); - } - } - - static final class ViaHeader extends RestParam { - - protected ViaHeader() { - super(HEADER, "Via", Via.class); - } - - @Override - public Via resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getVia(); - } - } - - static final class WarningHeader extends RestParam { - - protected WarningHeader() { - super(HEADER, "Warning", Warning.class); - } - - @Override - public Warning resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getWarning(); - } - } - - static final class TimeZoneHeader extends RestParam { - - protected TimeZoneHeader() { - super(HEADER, "Time-Zone", TimeZone.class); - } - - @Override - public TimeZone resolve(RestRequest req, RestResponse res) { - return req.getHeaders().getTimeZone(); - } - } - - //------------------------------------------------------------------------------------------------------------------- - // Annotated retrievers - //------------------------------------------------------------------------------------------------------------------- - - static final class PathParameterObject extends RestParam { - - protected PathParameterObject(String name, Type type) { - super(PATH, name, type); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getPathParams().get(name, type); - } - } - - static final class BodyObject extends RestParam { - - protected BodyObject(Type type) { - super(BODY, null, type); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getBody().asType(type); - } - } - - static final class HeaderObject extends RestParam { - - protected HeaderObject(String name, Type type) { - super(HEADER, name, type); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getHeaders().get(name, type); - } - } - - static final class MethodObject extends RestParam { - - protected MethodObject(Type type) throws ServletException { - super(OTHER, null, null); - if (type != String.class) - throw new ServletException("@Method parameters must be of type String"); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getMethod(); - } - } - - static final class FormDataObject extends RestParam { - private final boolean multiPart, plainParams; - - protected FormDataObject(String name, Type type, boolean multiPart, boolean plainParams) { - super(FORMDATA, name, type); - this.multiPart = multiPart; - this.plainParams = plainParams; - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - BeanSession bs = req.getBeanSession(); - if (multiPart) - return req.getFormData().getAll(name, type); - if (plainParams) - return bs.convertToType(req.getFormData(name), bs.getClassMeta(type)); - return req.getFormData().get(name, type); - } - } - - static final class QueryObject extends RestParam { - private final boolean multiPart, plainParams; - - protected QueryObject(String name, Type type, boolean multiPart, boolean plainParams) { - super(QUERY, name, type); - this.multiPart = multiPart; - this.plainParams = plainParams; - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - BeanSession bs = req.getBeanSession(); - if (multiPart) - return req.getQuery().getAll(name, type); - if (plainParams) - return bs.convertToType(req.getQuery(name), bs.getClassMeta(type)); - return req.getQuery().get(name, type); - } - } - - static final class HasFormDataObject extends RestParam { - - protected HasFormDataObject(String name, Type type) { - super(FORMDATA, name, type); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - BeanSession bs = req.getBeanSession(); - return bs.convertToType(req.getFormData().containsKey(name), bs.getClassMeta(type)); - } - } - - static final class HasQueryObject extends RestParam { - - protected HasQueryObject(String name, Type type) { - super(QUERY, name, type); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - BeanSession bs = req.getBeanSession(); - return bs.convertToType(req.getQuery().containsKey(name), bs.getClassMeta(type)); - } - } - - static final class PathRemainderObject extends RestParam { - - protected PathRemainderObject(Type type) throws ServletException { - super(OTHER, null, null); - if (type != String.class) - throw new ServletException("@PathRemainder parameters must be of type String"); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getPathRemainder(); - } - } - - static final class PropsObject extends RestParam { - - protected PropsObject(Type type) throws ServletException { - super(OTHER, null, null); - if (! ClassUtils.isParentClass(LinkedHashMap.class, type)) - throw new ServletException("@PathRemainder parameters must be of type String"); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getProperties(); - } - } - - //------------------------------------------------------------------------------------------------------------------- - // Other retrievers - //------------------------------------------------------------------------------------------------------------------- - - static final class ResourceBundleObject extends RestParam { - - protected ResourceBundleObject() { - super(OTHER, null, ResourceBundle.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getResourceBundle(); - } - } - - static final class MessageBundleObject extends RestParam { - - protected MessageBundleObject() { - super(OTHER, null, MessageBundle.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getResourceBundle(); - } - } - - static final class InputStreamObject extends RestParam { - - protected InputStreamObject() { - super(OTHER, null, InputStream.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getInputStream(); - } - } - - static final class ServletInputStreamObject extends RestParam { - - protected ServletInputStreamObject() { - super(OTHER, null, ServletInputStream.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getInputStream(); - } - } - - static final class ReaderObject extends RestParam { - - protected ReaderObject() { - super(OTHER, null, Reader.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getReader(); - } - } - - static final class OutputStreamObject extends RestParam { - - protected OutputStreamObject() { - super(OTHER, null, OutputStream.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return res.getOutputStream(); - } - } - - static final class ServletOutputStreamObject extends RestParam { - - protected ServletOutputStreamObject() { - super(OTHER, null, ServletOutputStream.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return res.getOutputStream(); - } - } - - static final class WriterObject extends RestParam { - - protected WriterObject() { - super(OTHER, null, Writer.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return res.getWriter(); - } - } - - static final class RequestHeadersObject extends RestParam { - - protected RequestHeadersObject() { - super(OTHER, null, RequestHeaders.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getHeaders(); - } - } - - static final class RequestQueryParamsObject extends RestParam { - - protected RequestQueryParamsObject() { - super(OTHER, null, RequestQuery.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getQuery(); - } - } - - static final class RequestFormDataObject extends RestParam { - - protected RequestFormDataObject() { - super(OTHER, null, RequestFormData.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getFormData(); - } - } - - static final class HttpMethodObject extends RestParam { - - protected HttpMethodObject() { - super(OTHER, null, HttpMethod.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getHttpMethod(); - } - } - - static final class LoggerObject extends RestParam { - - protected LoggerObject() { - super(OTHER, null, Logger.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getContext().getLogger().getLogger(); - } - } - - static final class JuneauLoggerObject extends RestParam { - - protected JuneauLoggerObject() { - super(OTHER, null, JuneauLogger.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getContext().getLogger().getLogger(); - } - } - - static final class RestContextObject extends RestParam { - - protected RestContextObject() { - super(OTHER, null, RestContext.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getContext(); - } - } - - static final class ParserObject extends RestParam { - - protected ParserObject() { - super(OTHER, null, Parser.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getBody().getParser(); - } - } - - static final class LocaleObject extends RestParam { - - protected LocaleObject() { - super(OTHER, null, Locale.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getLocale(); - } - } - - static final class SwaggerObject extends RestParam { - - protected SwaggerObject() { - super(OTHER, null, Swagger.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getSwagger(); - } - } - - static final class RequestPathParamsObject extends RestParam { - - protected RequestPathParamsObject() { - super(OTHER, null, RequestPathParams.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getPathParams(); - } - } - - static final class RequestBodyObject extends RestParam { - - protected RequestBodyObject() { - super(BODY, null, RequestBody.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getBody(); - } - } - - static final class ConfigFileObject extends RestParam { - - protected ConfigFileObject() { - super(OTHER, null, ConfigFile.class); - } - - @Override /* RestParam */ - public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getConfigFile(); - } - } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java new file mode 100644 index 0000000..dc29cc6 --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java @@ -0,0 +1,944 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest; + +import static org.apache.juneau.rest.RestParamType.*; + +import java.io.*; +import java.lang.reflect.*; +import java.lang.reflect.Method; +import java.util.*; +import java.util.logging.*; + +import javax.servlet.*; +import javax.servlet.http.*; + +import org.apache.juneau.*; +import org.apache.juneau.dto.swagger.*; +import org.apache.juneau.http.*; +import org.apache.juneau.http.Date; +import org.apache.juneau.ini.*; +import org.apache.juneau.internal.*; +import org.apache.juneau.parser.*; +import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.utils.*; + +/** + * Default REST method parameter resolvers. + */ +class RestParamDefaults { + + /** + * Standard set of method parameter resolvers. + */ + static final Map<Class<?>,RestParam> STANDARD_RESOLVERS; + + static { + Map<Class<?>,RestParam> m = new HashMap<Class<?>,RestParam>(); + + @SuppressWarnings("rawtypes") + Class[] r = new Class[] { + + // Standard top-level objects + HttpServletRequestObject.class, + RestRequestObject.class, + HttpServletResponseObject.class, + RestResponseObject.class, + + // Headers + AcceptHeader.class, + AcceptCharsetHeader.class, + AcceptEncodingHeader.class, + AcceptLanguageHeader.class, + AuthorizationHeader.class, + CacheControlHeader.class, + ConnectionHeader.class, + ContentLengthHeader.class, + ContentTypeHeader.class, + DateHeader.class, + ExpectHeader.class, + FromHeader.class, + HostHeader.class, + IfMatchHeader.class, + IfModifiedSinceHeader.class, + IfNoneMatchHeader.class, + IfRangeHeader.class, + IfUnmodifiedSinceHeader.class, + MaxForwardsHeader.class, + PragmaHeader.class, + ProxyAuthorizationHeader.class, + RangeHeader.class, + RefererHeader.class, + TEHeader.class, + UserAgentHeader.class, + UpgradeHeader.class, + ViaHeader.class, + WarningHeader.class, + TimeZoneHeader.class, + + // Other objects + ResourceBundleObject.class, + MessageBundleObject.class, + InputStreamObject.class, + ServletInputStreamObject.class, + ReaderObject.class, + OutputStreamObject.class, + ServletOutputStreamObject.class, + WriterObject.class, + RequestHeadersObject.class, + RequestQueryParamsObject.class, + RequestFormDataObject.class, + HttpMethodObject.class, + LoggerObject.class, + JuneauLoggerObject.class, + RestContextObject.class, + ParserObject.class, + LocaleObject.class, + SwaggerObject.class, + RequestPathParamsObject.class, + RequestBodyObject.class, + ConfigFileObject.class, + }; + + for (Class<?> c : r) { + try { + RestParam mpr = (RestParam)c.newInstance(); + m.put(mpr.forClass(), mpr); + } catch (Exception e) { + e.printStackTrace(); + } + } + + STANDARD_RESOLVERS = Collections.unmodifiableMap(m); + } + + //------------------------------------------------------------------------------------------------------------------- + // Request / Response retrievers + //------------------------------------------------------------------------------------------------------------------- + + static final class HttpServletRequestObject extends RestParam { + + protected HttpServletRequestObject() { + super(OTHER, null, HttpServletRequest.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return req; + } + } + + static final class HttpServletResponseObject extends RestParam { + + protected HttpServletResponseObject() { + super(OTHER, null, HttpServletResponse.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return res; + } + } + + static final class RestRequestObject extends RestParam { + + protected RestRequestObject() { + super(OTHER, null, RestRequest.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return req; + } + } + + static final class RestResponseObject extends RestParam { + + protected RestResponseObject() { + super(OTHER, null, RestResponse.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return res; + } + } + + //------------------------------------------------------------------------------------------------------------------- + // Header retrievers + //------------------------------------------------------------------------------------------------------------------- + + static final class AcceptHeader extends RestParam { + + protected AcceptHeader() { + super(HEADER, "Accept-Header", Accept.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAccept(); + } + } + + static final class AcceptCharsetHeader extends RestParam { + + protected AcceptCharsetHeader() { + super(HEADER, "Accept-Charset", AcceptCharset.class); + } + + @Override /* RestParam */ + public AcceptCharset resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAcceptCharset(); + } + } + + static final class AcceptEncodingHeader extends RestParam { + + protected AcceptEncodingHeader() { + super(HEADER, "Accept-Encoding", AcceptEncoding.class); + } + + @Override + public AcceptEncoding resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAcceptEncoding(); + } + } + + static final class AcceptLanguageHeader extends RestParam { + + protected AcceptLanguageHeader() { + super(HEADER, "Accept-Language", AcceptLanguage.class); + } + + @Override + public AcceptLanguage resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAcceptLanguage(); + } + } + + static final class AuthorizationHeader extends RestParam { + + protected AuthorizationHeader() { + super(HEADER, "Authorization", Authorization.class); + } + + @Override + public Authorization resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAuthorization(); + } + } + + static final class CacheControlHeader extends RestParam { + + protected CacheControlHeader() { + super(HEADER, "Cache-Control", CacheControl.class); + } + + @Override + public CacheControl resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getCacheControl(); + } + } + + static final class ConnectionHeader extends RestParam { + + protected ConnectionHeader() { + super(HEADER, "Connection", Connection.class); + } + + @Override + public Connection resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getConnection(); + } + } + + static final class ContentLengthHeader extends RestParam { + + protected ContentLengthHeader() { + super(HEADER, "Content-Length", ContentLength.class); + } + + @Override + public ContentLength resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getContentLength(); + } + } + + static final class ContentTypeHeader extends RestParam { + + protected ContentTypeHeader() { + super(HEADER, "Content-Type", ContentType.class); + } + + @Override + public ContentType resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getContentType(); + } + } + + static final class DateHeader extends RestParam { + + protected DateHeader() { + super(HEADER, "Date", Date.class); + } + + @Override + public Date resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getDate(); + } + } + + static final class ExpectHeader extends RestParam { + + protected ExpectHeader() { + super(HEADER, "Expect", Expect.class); + } + + @Override + public Expect resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getExpect(); + } + } + + static final class FromHeader extends RestParam { + + protected FromHeader() { + super(HEADER, "From", From.class); + } + + @Override + public From resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getFrom(); + } + } + + static final class HostHeader extends RestParam { + + protected HostHeader() { + super(HEADER, "Host", Host.class); + } + + @Override + public Host resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getHost(); + } + } + + static final class IfMatchHeader extends RestParam { + + protected IfMatchHeader() { + super(HEADER, "If-Match", IfMatch.class); + } + + @Override + public IfMatch resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfMatch(); + } + } + + static final class IfModifiedSinceHeader extends RestParam { + + protected IfModifiedSinceHeader() { + super(HEADER, "If-Modified-Since", IfModifiedSince.class); + } + + @Override + public IfModifiedSince resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfModifiedSince(); + } + } + + static final class IfNoneMatchHeader extends RestParam { + + protected IfNoneMatchHeader() { + super(HEADER, "If-None-Match", IfNoneMatch.class); + } + + @Override + public IfNoneMatch resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfNoneMatch(); + } + } + + static final class IfRangeHeader extends RestParam { + + protected IfRangeHeader() { + super(HEADER, "If-Range", IfRange.class); + } + + @Override + public IfRange resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfRange(); + } + } + + static final class IfUnmodifiedSinceHeader extends RestParam { + + protected IfUnmodifiedSinceHeader() { + super(HEADER, "If-Unmodified-Since", IfUnmodifiedSince.class); + } + + @Override + public IfUnmodifiedSince resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfUnmodifiedSince(); + } + } + + static final class MaxForwardsHeader extends RestParam { + + protected MaxForwardsHeader() { + super(HEADER, "Max-Forwards", MaxForwards.class); + } + + @Override + public MaxForwards resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getMaxForwards(); + } + } + + static final class PragmaHeader extends RestParam { + + protected PragmaHeader() { + super(HEADER, "Pragma", Pragma.class); + } + + @Override + public Pragma resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getPragma(); + } + } + + static final class ProxyAuthorizationHeader extends RestParam { + + protected ProxyAuthorizationHeader() { + super(HEADER, "Proxy-Authorization", ProxyAuthorization.class); + } + + @Override + public ProxyAuthorization resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getProxyAuthorization(); + } + } + + static final class RangeHeader extends RestParam { + + protected RangeHeader() { + super(HEADER, "Range", Range.class); + } + + @Override + public Range resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getRange(); + } + } + + static final class RefererHeader extends RestParam { + + protected RefererHeader() { + super(HEADER, "Referer", Referer.class); + } + + @Override + public Referer resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getReferer(); + } + } + + static final class TEHeader extends RestParam { + + protected TEHeader() { + super(HEADER, "TE", TE.class); + } + + @Override + public TE resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getTE(); + } + } + + static final class UserAgentHeader extends RestParam { + + protected UserAgentHeader() { + super(HEADER, "User-Agent", UserAgent.class); + } + + @Override + public UserAgent resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getUserAgent(); + } + } + + static final class UpgradeHeader extends RestParam { + + protected UpgradeHeader() { + super(HEADER, "Upgrade", Upgrade.class); + } + + @Override + public Upgrade resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getUpgrade(); + } + } + + static final class ViaHeader extends RestParam { + + protected ViaHeader() { + super(HEADER, "Via", Via.class); + } + + @Override + public Via resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getVia(); + } + } + + static final class WarningHeader extends RestParam { + + protected WarningHeader() { + super(HEADER, "Warning", Warning.class); + } + + @Override + public Warning resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getWarning(); + } + } + + static final class TimeZoneHeader extends RestParam { + + protected TimeZoneHeader() { + super(HEADER, "Time-Zone", TimeZone.class); + } + + @Override + public TimeZone resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getTimeZone(); + } + } + + //------------------------------------------------------------------------------------------------------------------- + // Annotated retrievers + //------------------------------------------------------------------------------------------------------------------- + + static final class PathParameterObject extends RestParam { + + protected PathParameterObject(String name, Type type) { + super(PATH, name, type); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getPathParams().get(name, type); + } + } + + static final class BodyObject extends RestParam { + + protected BodyObject(Type type) { + super(BODY, null, type); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getBody().asType(type); + } + } + + static final class HeaderObject extends RestParam { + + protected HeaderObject(Header a, Type type) { + super(HEADER, a.value(), type); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getHeaders().get(name, type); + } + } + + static final class MethodObject extends RestParam { + + protected MethodObject(Method method, Type type) throws ServletException { + super(OTHER, null, null); + if (type != String.class) + throw new RestServletException("Use of @Method annotation on parameter that is not a String on method ''{0}''", method); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getMethod(); + } + } + + static final class FormDataObject extends RestParam { + private final boolean multiPart, plainParams; + + protected FormDataObject(Method method, FormData a, Type type, boolean methodPlainParams) throws ServletException { + super(FORMDATA, a.value(), type); + if (a.multipart() && ! isCollection(type)) + throw new RestServletException("Use of multipart flag on @FormData parameter that's not an array or Collection on method ''{0}''", method); + this.multiPart = a.multipart(); + this.plainParams = a.format().equals("INHERIT") ? methodPlainParams : a.format().equals("PLAIN"); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + BeanSession bs = req.getBeanSession(); + if (multiPart) + return req.getFormData().getAll(name, type); + if (plainParams) + return bs.convertToType(req.getFormData(name), bs.getClassMeta(type)); + return req.getFormData().get(name, type); + } + } + + static final class QueryObject extends RestParam { + private final boolean multiPart, plainParams; + + protected QueryObject(Method method, Query a, Type type, boolean methodPlainParams) throws ServletException { + super(QUERY, a.value(), type); + if (a.multipart() && ! isCollection(type)) + throw new RestServletException("Use of multipart flag on @Query parameter that's not an array or Collection on method ''{0}''", method); + this.multiPart = a.multipart(); + this.plainParams = a.format().equals("INHERIT") ? methodPlainParams : a.format().equals("PLAIN"); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + BeanSession bs = req.getBeanSession(); + if (multiPart) + return req.getQuery().getAll(name, type); + if (plainParams) + return bs.convertToType(req.getQuery(name), bs.getClassMeta(type)); + return req.getQuery().get(name, type); + } + } + + static final class HasFormDataObject extends RestParam { + + protected HasFormDataObject(Method method, HasFormData a, Type type) throws ServletException { + super(FORMDATA, a.value(), type); + if (type != Boolean.class && type != boolean.class) + throw new RestServletException("Use of @HasForm annotation on parameter that is not a boolean on method ''{0}''", method); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + BeanSession bs = req.getBeanSession(); + return bs.convertToType(req.getFormData().containsKey(name), bs.getClassMeta(type)); + } + } + + static final class HasQueryObject extends RestParam { + + protected HasQueryObject(Method method, HasQuery a, Type type) throws ServletException { + super(QUERY, a.value(), type); + if (type != Boolean.class && type != boolean.class) + throw new RestServletException("Use of @HasQuery annotation on parameter that is not a boolean on method ''{0}''", method); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + BeanSession bs = req.getBeanSession(); + return bs.convertToType(req.getQuery().containsKey(name), bs.getClassMeta(type)); + } + } + + static final class PathRemainderObject extends RestParam { + + protected PathRemainderObject(Method method, Type type) throws ServletException { + super(OTHER, null, null); + if (type != String.class) + throw new RestServletException("Use of @PathRemainder annotation on parameter that is not a String on method ''{0}''", method); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getPathRemainder(); + } + } + + static final class PropsObject extends RestParam { + + protected PropsObject(Method method, Type type) throws ServletException { + super(OTHER, null, null); + if (type != ObjectMap.class) + throw new RestServletException("Use of @Properties annotation on parameter that is not an ObjectMap on method ''{0}''", method); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getProperties(); + } + } + + //------------------------------------------------------------------------------------------------------------------- + // Other retrievers + //------------------------------------------------------------------------------------------------------------------- + + static final class ResourceBundleObject extends RestParam { + + protected ResourceBundleObject() { + super(OTHER, null, ResourceBundle.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getResourceBundle(); + } + } + + static final class MessageBundleObject extends RestParam { + + protected MessageBundleObject() { + super(OTHER, null, MessageBundle.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getResourceBundle(); + } + } + + static final class InputStreamObject extends RestParam { + + protected InputStreamObject() { + super(OTHER, null, InputStream.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getInputStream(); + } + } + + static final class ServletInputStreamObject extends RestParam { + + protected ServletInputStreamObject() { + super(OTHER, null, ServletInputStream.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getInputStream(); + } + } + + static final class ReaderObject extends RestParam { + + protected ReaderObject() { + super(OTHER, null, Reader.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getReader(); + } + } + + static final class OutputStreamObject extends RestParam { + + protected OutputStreamObject() { + super(OTHER, null, OutputStream.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return res.getOutputStream(); + } + } + + static final class ServletOutputStreamObject extends RestParam { + + protected ServletOutputStreamObject() { + super(OTHER, null, ServletOutputStream.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return res.getOutputStream(); + } + } + + static final class WriterObject extends RestParam { + + protected WriterObject() { + super(OTHER, null, Writer.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return res.getWriter(); + } + } + + static final class RequestHeadersObject extends RestParam { + + protected RequestHeadersObject() { + super(OTHER, null, RequestHeaders.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getHeaders(); + } + } + + static final class RequestQueryParamsObject extends RestParam { + + protected RequestQueryParamsObject() { + super(OTHER, null, RequestQuery.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getQuery(); + } + } + + static final class RequestFormDataObject extends RestParam { + + protected RequestFormDataObject() { + super(OTHER, null, RequestFormData.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getFormData(); + } + } + + static final class HttpMethodObject extends RestParam { + + protected HttpMethodObject() { + super(OTHER, null, HttpMethod.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getHttpMethod(); + } + } + + static final class LoggerObject extends RestParam { + + protected LoggerObject() { + super(OTHER, null, Logger.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getContext().getLogger().getLogger(); + } + } + + static final class JuneauLoggerObject extends RestParam { + + protected JuneauLoggerObject() { + super(OTHER, null, JuneauLogger.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getContext().getLogger().getLogger(); + } + } + + static final class RestContextObject extends RestParam { + + protected RestContextObject() { + super(OTHER, null, RestContext.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getContext(); + } + } + + static final class ParserObject extends RestParam { + + protected ParserObject() { + super(OTHER, null, Parser.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getBody().getParser(); + } + } + + static final class LocaleObject extends RestParam { + + protected LocaleObject() { + super(OTHER, null, Locale.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getLocale(); + } + } + + static final class SwaggerObject extends RestParam { + + protected SwaggerObject() { + super(OTHER, null, Swagger.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getSwagger(); + } + } + + static final class RequestPathParamsObject extends RestParam { + + protected RequestPathParamsObject() { + super(OTHER, null, RequestPathParams.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getPathParams(); + } + } + + static final class RequestBodyObject extends RestParam { + + protected RequestBodyObject() { + super(BODY, null, RequestBody.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getBody(); + } + } + + static final class ConfigFileObject extends RestParam { + + protected ConfigFileObject() { + super(OTHER, null, ConfigFile.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getConfigFile(); + } + } + + private static boolean isCollection(Type t) { + return BeanContext.DEFAULT.getClassMeta(t).isCollectionOrArray(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java index 6f0c323..fee53d0 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java @@ -128,6 +128,38 @@ public @interface RestResource { Class<?>[] pojoSwaps() default {}; /** + * Class-level Java method parameter resolvers. + * <p> + * By default, the Juneau framework will automatically Java method parameters of various types (e.g. + * <code>RestRequest</code>, <code>Accept</code>, <code>Reader</code>). + * This annotation allows you to provide your own resolvers for your own class types that you want resolved. + * <p> + * For example, if you want to pass in instances of <code>MySpecialObject</code> to your Java method, define + * the following resolver: + * <p class='bcode'> + * <jk>public class</jk> MyRestParam <jk>extends</jk> RestParam { + * + * <jc>// Must have no-arg constructor!</jc> + * <jk>public</jk> MyRestParam() { + * <jc>// First two parameters help with Swagger doc generation.</jc> + * <jk>super</jk>(<jsf>QUERY</jsf>, <js>"myparam"</js>, MySpecialObject.<jk>class</jk>); + * } + * + * <jc>// The method that creates our object. + * // In this case, we're taking in a query parameter and converting it to our object.</jc> + * <jk>public</jk> Object resolve(RestRequest req, RestResponse res) <jk>throws</jk> Exception { + * <jk>return new</jk> MySpecialObject(req.getQuery().get(<js>"myparam"</js>)); + * } + * } + * </p> + * <p> + * <b>Note:</b>{@link RestParam} classes must have no-arg constructors. + * <p> + * The programmatic equivalent to this annotation is the {@link RestConfig#addParamResolvers(Class...)} method. + */ + Class<? extends RestParam>[] paramResolvers() default {}; + + /** * Class-level properties. * <p> * Shortcut for specifying class-level properties on this servlet to the objects returned by the following methods:
