Repository: incubator-juneau
Updated Branches:
  refs/heads/master 321f6bdee -> d6fe4ff9d


Support for more REST method parameter types.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/d6fe4ff9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/d6fe4ff9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/d6fe4ff9

Branch: refs/heads/master
Commit: d6fe4ff9d96f070b4b0b93ad740b2ab7afdcfba2
Parents: 321f6bd
Author: JamesBognar <[email protected]>
Authored: Sun May 7 17:16:00 2017 -0400
Committer: JamesBognar <[email protected]>
Committed: Sun May 7 17:16:00 2017 -0400

----------------------------------------------------------------------
 .../org/apache/juneau/internal/ClassUtils.java  |  13 ++
 .../java/org/apache/juneau/rest/CallMethod.java | 218 +++++++------------
 .../java/org/apache/juneau/rest/RestParam.java  |  22 +-
 3 files changed, 106 insertions(+), 147 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d6fe4ff9/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java 
b/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java
index 39bf16b..1f2788b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java
@@ -145,6 +145,19 @@ public final class ClassUtils {
        }
 
        /**
+        * Returns <jk>true</jk> if <code>parent</code> is a parent class or 
the same as <code>child</code>.
+        *
+        * @param parent The parent class.
+        * @param child The child class.
+        * @return <jk>true</jk> if <code>parent</code> is a parent class or 
the same as <code>child</code>.
+        */
+       public static boolean isParentClass(Class<?> parent, Type child) {
+               if (child instanceof Class)
+                       return isParentClass(parent, (Class<?>)child);
+               return false;
+       }
+
+       /**
         * Comparator for use with {@link TreeMap TreeMaps} with {@link Class} 
keys.
         */
        public final static class ClassComparator implements 
Comparator<Class<?>>, Serializable {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d6fe4ff9/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 df39005..afc7a1e 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
@@ -14,8 +14,6 @@ package org.apache.juneau.rest;
 
 import static javax.servlet.http.HttpServletResponse.*;
 import static org.apache.juneau.dto.swagger.SwaggerBuilder.*;
-import static org.apache.juneau.internal.ClassUtils.*;
-import static org.apache.juneau.rest.CallMethod.ParamType.*;
 import static org.apache.juneau.rest.RestContext.*;
 import static org.apache.juneau.rest.annotation.Inherit.*;
 import static org.apache.juneau.serializer.SerializerContext.*;
@@ -32,7 +30,6 @@ import org.apache.juneau.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.encoders.*;
 import org.apache.juneau.html.*;
-import org.apache.juneau.http.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
@@ -310,104 +307,76 @@ class CallMethod implements Comparable<CallMethod>  {
         */
        private static class MethodParam {
 
-               private final ParamType paramType;
-               private final Type type;
-               private final String name;
-               private final boolean multiPart, plainParams;
                private final int attrIdx;
+               private final RestParam param;
 
                private MethodParam(Type type, Method method, Annotation[] 
annotations, boolean methodPlainParams, UrlPathPattern pathPattern, int 
attrIdx) throws ServletException {
-                       this.type = type;
 
-                       ParamType _paramType = null;
+                       RestParam _param = null;
                        String _name = "";
-                       boolean _multiPart = false, _plainParams = false;
 
                        boolean isClass = type instanceof Class;
-                       if (isClass && isParentClass(HttpServletRequest.class, 
(Class<?>)type))
-                               _paramType = REQ;
-                       else if (isClass && 
isParentClass(HttpServletResponse.class, (Class<?>)type))
-                               _paramType = RES;
-                       else if (isClass && isParentClass(Accept.class, 
(Class<?>)type))
-                               _paramType = ACCEPT;
-                       else if (isClass && isParentClass(AcceptEncoding.class, 
(Class<?>)type))
-                               _paramType = ACCEPTENCODING;
-                       else if (isClass && isParentClass(ContentType.class, 
(Class<?>)type))
-                               _paramType = CONTENTTYPE;
-                       else for (Annotation a : annotations) {
-                               if (a instanceof Path) {
-                                       Path a2 = (Path)a;
-                                       _paramType = PATH;
-                                       _name = a2.value();
-                               } else if (a instanceof Header) {
-                                       Header h = (Header)a;
-                                       _paramType = HEADER;
-                                       _name = h.value();
-                               } else if (a instanceof FormData) {
-                                       FormData p = (FormData)a;
-                                       if (p.multipart())
-                                               assertCollection(type, method);
-                                       _paramType = FORMDATA;
-                                       _multiPart = p.multipart();
-                                       _plainParams = 
p.format().equals("INHERIT") ? methodPlainParams : p.format().equals("PLAIN");
-                                       _name = p.value();
-                               } else if (a instanceof Query) {
-                                       Query p = (Query)a;
-                                       if (p.multipart())
-                                               assertCollection(type, method);
-                                       _paramType = QUERY;
-                                       _multiPart = p.multipart();
-                                       _plainParams = 
p.format().equals("INHERIT") ? methodPlainParams : p.format().equals("PLAIN");
-                                       _name = p.value();
-                               } else if (a instanceof HasFormData) {
-                                       HasFormData p = (HasFormData)a;
-                                       _paramType = HASFORMDATA;
-                                       _name = p.value();
-                               } else if (a instanceof HasQuery) {
-                                       HasQuery p = (HasQuery)a;
-                                       _paramType = HASQUERY;
-                                       _name = p.value();
-                               } else if (a instanceof Body) {
-                                       _paramType = BODY;
-                               } else if (a instanceof 
org.apache.juneau.rest.annotation.Method) {
-                                       _paramType = METHOD;
-                                       if (type != String.class)
-                                               throw new 
ServletException("@Method parameters must be of type String");
-                               } else if (a instanceof PathRemainder) {
-                                       _paramType = PATHREMAINDER;
-                                       if (type != String.class)
-                                               throw new 
ServletException("@PathRemainder parameters must be of type String");
-                               } else if (a instanceof Properties) {
-                                       _paramType = PROPS;
-                                       _name = "PROPERTIES";
-                               } else if (a instanceof Messages) {
-                                       _paramType = MESSAGES;
-                                       _name = "MESSAGES";
+                       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 (_paramType == null)
-                               _paramType = PATH;
-
-                       if (_paramType == PATH && _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];
+
+                       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.paramType = _paramType;
-                       this.name = _name;
-                       this.multiPart = _multiPart;
-                       this.plainParams = _plainParams;
+                       this.param = _param;
                        this.attrIdx = attrIdx;
                }
 
@@ -421,56 +390,19 @@ class CallMethod implements Comparable<CallMethod>  {
                }
 
                private Object getValue(RestRequest req, RestResponse res) 
throws Exception {
-                       BeanSession session = req.getBeanSession();
-                       switch(paramType) {
-                               case REQ:        return req;
-                               case RES:        return res;
-                               case PATH:       return 
req.getPathParams().get(name, type);
-                               case BODY:       return 
req.getBody().asType(type);
-                               case HEADER:     return 
req.getHeaders().get(name, type);
-                               case METHOD:     return req.getMethod();
-                               case FORMDATA: {
-                                       if (multiPart)
-                                               return 
req.getFormData().getAll(name, type);
-                                       if (plainParams)
-                                               return 
session.convertToType(req.getFormData(name), session.getClassMeta(type));
-                                       return req.getFormData().get(name, 
type);
-                               }
-                               case QUERY: {
-                                       if (multiPart)
-                                               return 
req.getQuery().getAll(name, type);
-                                       if (plainParams)
-                                               return 
session.convertToType(req.getQuery(name), session.getClassMeta(type));
-                                       return req.getQuery().get(name, type);
-                               }
-                               case HASFORMDATA:   return 
session.convertToType(req.getFormData().containsKey(name), 
session.getClassMeta(type));
-                               case HASQUERY:      return 
session.convertToType(req.getQuery().containsKey(name), 
session.getClassMeta(type));
-                               case PATHREMAINDER: return 
req.getPathRemainder();
-                               case PROPS:         return res.getProperties();
-                               case MESSAGES:      return 
req.getResourceBundle();
-                               case ACCEPT:        return 
req.getHeaders().getAccept();
-                               case ACCEPTENCODING:return 
req.getHeaders().getAcceptEncoding();
-                               case CONTENTTYPE:   return 
req.getHeaders().getContentType();
-                               default:            return null;
-                       }
+                       return param.resolve(req, res);
                }
-       }
 
-       static enum ParamType {
-               REQ, RES, PATH, BODY, HEADER, METHOD, FORMDATA, QUERY, 
HASFORMDATA, HASQUERY, PATHREMAINDER, PROPS, MESSAGES, ACCEPT, ACCEPTENCODING, 
CONTENTTYPE;
-
-               private String getSwaggerParameterType() {
-                       switch(this) {
-                               case PATH: return "path";
-                               case HEADER:
-                               case ACCEPT:
-                               case ACCEPTENCODING:
-                               case CONTENTTYPE: return "header";
-                               case FORMDATA: return "formData";
-                               case QUERY: return "query";
-                               case BODY: return "body";
-                               default: return null;
-                       }
+               private RestParamType getParamType() {
+                       return param.getParamType();
+               }
+
+               private String getName() {
+                       return param.getName();
+               }
+
+               private Type getType() {
+                       return param.getType();
                }
        }
 
@@ -702,12 +634,12 @@ class CallMethod implements Comparable<CallMethod>  {
 
                // Finally, look for parameters defined on method.
                for (CallMethod.MethodParam mp : this.params) {
-                       String in = mp.paramType.getSwaggerParameterType();
-                       if (in != null) {
-                               String k2 = in + '.' + ("body".equals(in) ? 
null : mp.name);
+                       RestParamType in = mp.getParamType();
+                       if (in != RestParamType.OTHER) {
+                               String k2 = in.toString() + '.' + (in == 
RestParamType.BODY ? null : mp.getName());
                                ParameterInfo p = m.get(k2);
                                if (p == null) {
-                                       p = parameterInfoStrict(in, mp.name);
+                                       p = parameterInfoStrict(in.toString(), 
mp.getName());
                                        m.put(k2, p);
                                }
                        }
@@ -874,7 +806,7 @@ class CallMethod implements Comparable<CallMethod>  {
                        } catch (Exception e) {
                                throw new RestException(SC_BAD_REQUEST,
                                        "Invalid data conversion.  Could not 
convert {0} ''{1}'' to type ''{2}'' on method ''{3}.{4}''.",
-                                       params[i].paramType.name(), 
params[i].name, params[i].type, method.getDeclaringClass().getName(), 
method.getName()
+                                       params[i].getParamType().name(), 
params[i].getName(), params[i].getType(), method.getDeclaringClass().getName(), 
method.getName()
                                ).initCause(e);
                        }
                }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d6fe4ff9/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 a900c14..c6e176e 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
@@ -174,6 +174,14 @@ public abstract class RestParam {
                return name;
        }
 
+       /**
+        * Returns the parameter class type.
+        * @return the parameter class type.
+        */
+       public Type getType() {
+               return type;
+       }
+
        
//-------------------------------------------------------------------------------------------------------------------
        // Request / Response retrievers
        
//-------------------------------------------------------------------------------------------------------------------
@@ -233,7 +241,7 @@ public abstract class RestParam {
        static final class AcceptHeader extends RestParam {
 
                protected AcceptHeader() {
-                       super(HEADER, "Accept-Header", AcceptHeader.class);
+                       super(HEADER, "Accept-Header", Accept.class);
                }
 
                @Override /* RestParam */
@@ -620,8 +628,10 @@ public abstract class RestParam {
 
        static final class MethodObject extends RestParam {
 
-               protected MethodObject() {
+               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 */
@@ -698,8 +708,10 @@ public abstract class RestParam {
 
        static final class PathRemainderObject extends RestParam {
 
-               protected PathRemainderObject() {
+               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 */
@@ -710,8 +722,10 @@ public abstract class RestParam {
 
        static final class PropsObject extends RestParam {
 
-               protected PropsObject() {
+               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 */

Reply via email to