Added: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuard.java
==============================================================================
--- 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuard.java
 (added)
+++ 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuard.java
 Fri Sep  8 23:25:34 2017
@@ -0,0 +1,101 @@
+// 
***************************************************************************************************************************
+// * 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 javax.servlet.http.HttpServletResponse.*;
+
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * REST method guard.
+ *
+ * <h5 class='section'>Description:</h5>
+ *
+ * Implements a guard mechanism for REST method calls that allows requests to 
be rejected before invocation of the REST
+ * method.
+ * For example, guards can be used to ensure that only administrators can call 
certain methods.
+ *
+ * <p>
+ * Guards are applied to REST methods declaratively through the {@link 
RestResource#guards()} or
+ * {@link RestMethod#guards()} annotations.
+ *
+ * <p>
+ * If multiple guards are specified, ALL guards must pass in order for the 
request to proceed.
+ *
+ * <h6 class='topic'>How to implement</h6>
+ *
+ * Typically, guards will be used for permissions checking on the user making 
the request, but it can also be used for
+ * other purposes like pre-call validation of a request.
+ *
+ * <p>
+ * Implementers should simply throw a {@link RestException} from the {@link 
#guard(RestRequest, RestResponse)}
+ * method to abort processing on the current request.
+ *
+ * <p>
+ * Guards must implement a no-args constructor.
+ *
+ * <h6 class='topic'>Example usage:</h6>
+ * <p class='bcode'>
+ *     <jk>public</jk> MyResource <jk>extends</jk> RestServlet {
+ *
+ *             <jc>// Delete method with guard that only allows Billy to call 
it.</jc>
+ *             <ja>@RestMethod</ja>(name=<js>"DELETE"</js>, 
guards=BillyGuard.<jk>class</jk>)
+ *             <jk>public</jk> doDelete(RestRequest req, RestResponse res) 
<jk>throws</jk> Exception {...}
+ *     }
+ * </p>
+ *
+ * <h6 class='topic'>Example implementation:</h6>
+ * <p class='bcode'>
+ *     <jc>// Define a guard that only lets Billy make a request</jc>
+ *     <jk>public</jk> BillyGuard <jk>extends</jk> RestGuard {
+ *
+ *             <ja>@Override</ja>
+ *             <jk>public boolean</jk> isRequestAllowed(RestRequest req) {
+ *                     return 
req.getUserPrincipal().getName().contains(<js>"Billy"</js>);
+ *             }
+ *     }
+ * </p>
+ */
+public abstract class RestGuard {
+
+       /**
+        * Checks the current HTTP request and throws a {@link RestException} 
if the guard does not permit the request.
+        *
+        * <p>
+        * By default, throws an <jsf>SC_FORBIDDEN</jsf> exception if {@link 
#isRequestAllowed(RestRequest)} returns
+        * <jk>false</jk>.
+        *
+        * <p>
+        * Subclasses are free to override this method to tailor the behavior 
of how to handle unauthorized requests.
+        *
+        * @param req The servlet request.
+        * @param res The servlet response.
+        * @throws RestException Thrown to abort processing on current request.
+        * @return
+        *      <jk>true</jk> if request can proceed.
+        *      Specify <jk>false</jk> if you're doing something like a 
redirection to a login page.
+        */
+       public boolean guard(RestRequest req, RestResponse res) throws 
RestException {
+               if (! isRequestAllowed(req))
+                       throw new RestException(SC_FORBIDDEN, "Access denied by 
guard");
+               return true;
+       }
+
+       /**
+        * Returns <jk>true</jk> if the specified request can pass through this 
guard.
+        *
+        * @param req The servlet request.
+        * @return <jk>true</jk> if the specified request can pass through this 
guard.
+        */
+       public abstract boolean isRequestAllowed(RestRequest req);
+}

Propchange: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuard.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestInfoProvider.java
==============================================================================
--- 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestInfoProvider.java
 (added)
+++ 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestInfoProvider.java
 Fri Sep  8 23:25:34 2017
@@ -0,0 +1,572 @@
+// 
***************************************************************************************************************************
+// * 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 javax.servlet.http.HttpServletResponse.*;
+import static org.apache.juneau.dto.swagger.SwaggerBuilder.*;
+import static org.apache.juneau.internal.ReflectionUtils.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import org.apache.juneau.dto.swagger.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.svl.*;
+
+/**
+ * Class that provides documentation and other related information about a 
REST resource.
+ *
+ * <p>
+ * Subclasses can override these methods to tailor how HTTP REST resources are 
documented.
+ * Subclasses MUST implement a public constructor that takes in a {@link 
RestContext} object.
+ *
+ * <p>
+ * RestInfoProviders are associated with servlets/resources in one of the 
following ways:
+ * <ul>
+ *     <li>The {@link RestResource#infoProvider @RestResource.infoProvider()} 
annotation.
+ *     <li>The {@link RestConfig#setInfoProvider(Class)}/{@link 
RestConfig#setInfoProvider(RestInfoProvider)} methods.
+ * </ul>
+ */
+@SuppressWarnings("hiding")
+public class RestInfoProvider {
+
+       private final RestContext context;
+       private final String
+               siteName,
+               title,
+               description,
+               termsOfService,
+               contact,
+               license,
+               version,
+               tags,
+               externalDocs;
+       private final ConcurrentHashMap<Locale,Swagger> swaggers = new 
ConcurrentHashMap<Locale,Swagger>();
+
+       /**
+        * Constructor.
+        *
+        * @param context The resource context.
+        */
+       public RestInfoProvider(RestContext context) {
+               this.context = context;
+
+               Builder b = new Builder(context);
+               this.siteName = b.siteName;
+               this.title = b.title;
+               this.description = b.description;
+               this.termsOfService = b.termsOfService;
+               this.contact = b.contact;
+               this.license = b.license;
+               this.version = b.version;
+               this.tags = b.tags;
+               this.externalDocs = b.externalDocs;
+       }
+
+       private static class Builder {
+               private String
+                       siteName,
+                       title,
+                       description,
+                       termsOfService,
+                       contact,
+                       license,
+                       version,
+                       tags,
+                       externalDocs;
+
+               Builder(RestContext context) {
+
+                       LinkedHashMap<Class<?>,RestResource> 
restResourceAnnotationsParentFirst = 
findAnnotationsMapParentFirst(RestResource.class, 
context.getResource().getClass());
+
+                       for (RestResource r : 
restResourceAnnotationsParentFirst.values()) {
+                               if (! r.siteName().isEmpty())
+                                       siteName = r.siteName();
+                               if (! r.title().isEmpty())
+                                       title = r.title();
+                               if (! r.description().isEmpty())
+                                       description = r.description();
+                               ResourceSwagger sr = r.swagger();
+                               if (! sr.termsOfService().isEmpty())
+                                       termsOfService = sr.termsOfService();
+                               if (! sr.contact().isEmpty())
+                                       contact = sr.contact();
+                               if (! sr.license().isEmpty())
+                                       license = sr.license();
+                               if (! sr.version().isEmpty())
+                                       version = sr.version();
+                               if (! sr.tags().isEmpty())
+                                       tags = sr.tags();
+                               if (! sr.externalDocs().isEmpty())
+                                       externalDocs = sr.externalDocs();
+                       }
+               }
+       }
+
+       /**
+        * Returns the localized swagger for this REST resource.
+        *
+        * @param req The incoming HTTP request.
+        * @return A new Swagger instance.
+        * @throws RestException
+        */
+       protected Swagger getSwagger(RestRequest req) throws RestException {
+               try {
+                       // If a file is defined, use that.
+                       Swagger s = req.getSwaggerFromFile();
+                       if (s != null)
+                               return s;
+
+                       s = swagger(
+                               info(getTitle(req), getVersion(req))
+                                       .contact(getContact(req))
+                                       .license(getLicense(req))
+                                       .description(getDescription(req))
+                                       .termsOfService(getTermsOfService(req))
+                               )
+                               .consumes(context.getSupportedAcceptTypes())
+                               .produces(context.getSupportedContentTypes())
+                               .tags(getTags(req))
+                               .externalDocs(getExternalDocs(req));
+
+                       for (CallMethod sm : context.getCallMethods().values()) 
{
+                               if (sm.isRequestAllowed(req)) {
+                                       Operation o = 
sm.getSwaggerOperation(req);
+                                       s.path(
+                                               sm.getPathPattern(),
+                                               
sm.getHttpMethod().toLowerCase(),
+                                               o
+                                       );
+                               }
+                       }
+                       return s;
+               } catch (RestException e) {
+                       throw e;
+               } catch (Exception e) {
+                       throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
+               }
+       }
+
+       /**
+        * Returns the localized Swagger from the file system.
+        *
+        * <p>
+        * Looks for a file called <js>"{ServletClass}_{locale}.json"</js> in 
the same package as this servlet and returns
+        * it as a parsed {@link Swagger} object.
+        *
+        * <p>
+        * Returned objects are cached for later quick-lookup.
+        *
+        * @param locale The locale of the swagger.
+        * @return The parsed swagger object, or <jk>null</jk> if the swagger 
file could not be found.
+        * @throws RestException
+        */
+       protected Swagger getSwaggerFromFile(Locale locale) throws 
RestException {
+               Swagger s = swaggers.get(locale);
+               if (s == null) {
+                       try {
+                               s = context.getResource(Swagger.class, 
MediaType.JSON, getClass().getSimpleName() + ".json", locale);
+                               swaggers.putIfAbsent(locale, s == null ? 
Swagger.NULL : s);
+                       } catch (Exception e) {
+                               throw new 
RestException(SC_INTERNAL_SERVER_ERROR, e);
+                       }
+               }
+               return s == Swagger.NULL ? null : s;
+       }
+
+       /**
+        * Returns the localized summary of the specified java method on this 
servlet.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own summary.
+        *
+        * <p>
+        * The default implementation returns the summary from the following 
locations (whichever matches first):
+        * <ol>
+        *      <li>{@link RestMethod#summary() @RestMethod.summary()} 
annotation on the method.
+        *      <li><ck>[ClassName].[javaMethodName].summary</ck> property in 
resource bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>[javaMethodName].summary</ck> property in resource 
bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        * </ol>
+        *
+        * @param javaMethodName The name of the Java method whose description 
we're retrieving.
+        * @param req The current request.
+        * @return The localized summary of the method, or a blank string if no 
summary was found.
+        */
+       public String getMethodSummary(String javaMethodName, RestRequest req) {
+               CallMethod m = context.getCallMethods().get(javaMethodName);
+               if (m != null)
+                       return m.getSummary(req);
+               return "";
+       }
+
+       /**
+        * Returns the localized description of the specified java method on 
this servlet.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own description.
+        *
+        * <p>
+        * The default implementation returns the description from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link RestMethod#description() @RestMethod.description()} 
annotation on the method.
+        *      <li><ck>[ClassName].[javaMethodName].description</ck> property 
in resource bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>[javaMethodName].description</ck> property in resource 
bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        * </ol>
+        *
+        * @param javaMethodName The name of the Java method whose description 
we're retrieving.
+        * @param req The current request.
+        * @return The localized description of the method, or a blank string 
if no description was found.
+        */
+       protected String getMethodDescription(String javaMethodName, 
RestRequest req) {
+               CallMethod m = context.getCallMethods().get(javaMethodName);
+               if (m != null)
+                       return m.getDescription(req);
+               return "";
+       }
+
+       /**
+        * Returns the localized site name of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own site name.
+        *
+        * <p>
+        * The default implementation returns the description from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link RestResource#siteName() @RestResource.siteName()} 
annotation on this class, and then any parent classes.
+        *      <li><ck>[ClassName].siteName</ck> property in resource bundle 
identified by
+        *              {@link RestResource#messages() 
@ResourceBundle.messages()} annotation for this class, then any parent
+        *              classes.
+        *      <li><ck>siteName</ck> in resource bundle identified by {@link 
RestResource#messages() @RestResource.messages()}
+        *              annotation for this class, then any parent classes.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return The localized description of this REST resource, or 
<jk>null</jk> if no resource description was found.
+        */
+       public String getSiteName(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               if (this.siteName != null)
+                       return vr.resolve(this.siteName);
+               String siteName = 
context.getMessages().findFirstString(req.getLocale(), "siteName");
+               if (siteName != null)
+                       return vr.resolve(siteName);
+               return null;
+       }
+
+       /**
+        * Returns the localized title of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own title.
+        *
+        * <p>
+        * The default implementation returns the description from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link RestResource#title() @RestResource.title()} 
annotation on this class, and then any parent classes.
+        *      <li><ck>[ClassName].title</ck> property in resource bundle 
identified by
+        *              {@link RestResource#messages() 
@ResourceBundle.messages()} annotation for this class, then any parent
+        *              classes.
+        *      <li><ck>title</ck> in resource bundle identified by {@link 
RestResource#messages() @RestResource.messages()}
+        *              annotation for this class, then any parent classes.
+        *      <li><ck>/info/title</ck> entry in swagger file.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return The localized description of this REST resource, or 
<jk>null</jk> if no resource description was found.
+        */
+       public String getTitle(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               if (this.title != null)
+                       return vr.resolve(this.title);
+               String title = 
context.getMessages().findFirstString(req.getLocale(), "title");
+               if (title != null)
+                       return vr.resolve(title);
+               Swagger s = req.getSwaggerFromFile();
+               if (s != null && s.getInfo() != null)
+                       return s.getInfo().getTitle();
+               return null;
+       }
+
+       /**
+        * Returns the localized description of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own description.
+        *
+        * <p>
+        * The default implementation returns the description from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link RestResource#description() 
@RestResource.description()} annotation on this class, and then any
+        *              parent classes.
+        *      <li><ck>[ClassName].description</ck> property in resource 
bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>description</ck> property in resource bundle identified 
by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>/info/description</ck> entry in swagger file.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return The localized description of this REST resource, or 
<jk>null</jk> if no resource description was found.
+        */
+       public String getDescription(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               if (this.description != null)
+                       return vr.resolve(this.description);
+               String description = 
context.getMessages().findFirstString(req.getLocale(), "description");
+               if (description != null)
+                       return vr.resolve(description);
+               Swagger s = req.getSwaggerFromFile();
+               if (s != null && s.getInfo() != null)
+                       return s.getInfo().getDescription();
+               return null;
+       }
+
+       /**
+        * Returns the localized contact information of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own contact 
information.
+        *
+        * <p>
+        * The default implementation returns the contact information from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link ResourceSwagger#contact() 
@ResourceSwagger.contact()} annotation on this class, and then any parent
+        *              classes.
+        *      <li><ck>[ClassName].contact</ck> property in resource bundle 
identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>contact</ck> property in resource bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>/info/contact</ck> entry in swagger file.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return
+        *      The localized contact information of this REST resource, or 
<jk>null</jk> if no contact information was found.
+        */
+       public Contact getContact(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               JsonParser jp = JsonParser.DEFAULT;
+               try {
+                       if (this.contact != null)
+                               return jp.parse(vr.resolve(this.contact), 
Contact.class);
+                       String contact = 
context.getMessages().findFirstString(req.getLocale(), "contact");
+                       if (contact != null)
+                               return jp.parse(vr.resolve(contact), 
Contact.class);
+                       Swagger s = req.getSwaggerFromFile();
+                       if (s != null && s.getInfo() != null)
+                               return s.getInfo().getContact();
+                       return null;
+               } catch (ParseException e) {
+                       throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
+               }
+       }
+
+       /**
+        * Returns the localized license information of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own license 
information.
+        *
+        * <p>
+        * The default implementation returns the license information from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link ResourceSwagger#license() 
@ResourceSwagger.license()} annotation on this class, and then any parent
+        *              classes.
+        *      <li><ck>[ClassName].license</ck> property in resource bundle 
identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>license</ck> property in resource bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>/info/license</ck> entry in swagger file.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return
+        *      The localized contact information of this REST resource, or 
<jk>null</jk> if no contact information was found.
+        */
+       public License getLicense(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               JsonParser jp = JsonParser.DEFAULT;
+               try {
+                       if (this.license != null)
+                               return jp.parse(vr.resolve(this.license), 
License.class);
+                       String license = 
context.getMessages().findFirstString(req.getLocale(), "license");
+                       if (license != null)
+                               return jp.parse(vr.resolve(license), 
License.class);
+                       Swagger s = req.getSwaggerFromFile();
+                       if (s != null && s.getInfo() != null)
+                               return s.getInfo().getLicense();
+                       return null;
+               } catch (ParseException e) {
+                       throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
+               }
+       }
+
+       /**
+        * Returns the terms-of-service information of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own 
terms-of-service information.
+        *
+        * <p>
+        * The default implementation returns the terms-of-service information 
from the following locations (whichever
+        * matches first):
+        * <ol>
+        *      <li>{@link ResourceSwagger#termsOfService() 
@ResourceSwagger.termsOfService()} annotation on this class, and
+        *              then any parent classes.
+        *      <li><ck>[ClassName].termsOfService</ck> property in resource 
bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>termsOfService</ck> property in resource bundle 
identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>/info/termsOfService</ck> entry in swagger file.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return
+        *      The localized contact information of this REST resource, or 
<jk>null</jk> if no contact information was found.
+        */
+       public String getTermsOfService(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               if (this.termsOfService != null)
+                       return vr.resolve(this.termsOfService);
+               String termsOfService = 
context.getMessages().findFirstString(req.getLocale(), "termsOfService");
+               if (termsOfService != null)
+                       return vr.resolve(termsOfService);
+               Swagger s = req.getSwaggerFromFile();
+               if (s != null && s.getInfo() != null)
+                       return s.getInfo().getTermsOfService();
+               return null;
+       }
+
+       /**
+        * Returns the version information of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own version 
information.
+        *
+        * <p>
+        * The default implementation returns the version information from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link ResourceSwagger#version() 
@ResourceSwagger.version()} annotation on this class, and then any parent
+        *              classes.
+        *      <li><ck>[ClassName].version</ck> property in resource bundle 
identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>version</ck> property in resource bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>/info/version</ck> entry in swagger file.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return
+        *      The localized contact information of this REST resource, or 
<jk>null</jk> if no contact information was found.
+        */
+       public String getVersion(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               if (this.version != null)
+                       return vr.resolve(this.version);
+               String version = 
context.getMessages().findFirstString(req.getLocale(), "version");
+               if (version != null)
+                       return vr.resolve(version);
+               Swagger s = req.getSwaggerFromFile();
+               if (s != null && s.getInfo() != null)
+                       return s.getInfo().getVersion();
+               return null;
+       }
+
+       /**
+        * Returns the version information of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own version 
information.
+        *
+        * <p>
+        * The default implementation returns the version information from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link ResourceSwagger#version() 
@ResourceSwagger.version()} annotation on this class, and then any parent
+        *              classes.
+        *      <li><ck>[ClassName].version</ck> property in resource bundle 
identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>version</ck> property in resource bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>/info/version</ck> entry in swagger file.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return
+        *      The localized contact information of this REST resource, or 
<jk>null</jk> if no contact information was found.
+        */
+       public List<Tag> getTags(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               JsonParser jp = JsonParser.DEFAULT;
+               try {
+                       if (this.tags != null)
+                               return jp.parse(vr.resolve(this.tags), 
ArrayList.class, Tag.class);
+                       String tags = 
context.getMessages().findFirstString(req.getLocale(), "tags");
+                       if (tags != null)
+                               return jp.parse(vr.resolve(tags), 
ArrayList.class, Tag.class);
+                       Swagger s = req.getSwaggerFromFile();
+                       if (s != null)
+                               return s.getTags();
+                       return null;
+               } catch (Exception e) {
+                       throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
+               }
+       }
+
+       /**
+        * Returns the version information of this REST resource.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own version 
information.
+        *
+        * <p>
+        * The default implementation returns the version information from the 
following locations (whichever matches first):
+        * <ol>
+        *      <li>{@link ResourceSwagger#version() 
@ResourceSwagger.version()} annotation on this class, and then any parent
+        *              classes.
+        *      <li><ck>[ClassName].version</ck> property in resource bundle 
identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>version</ck> property in resource bundle identified by
+        *              {@link RestResource#messages() 
@RestResource.messages()} annotation for this class, then any parent classes.
+        *      <li><ck>/info/version</ck> entry in swagger file.
+        * </ol>
+        *
+        * @param req The current request.
+        * @return
+        *      The localized contact information of this REST resource, or 
<jk>null</jk> if no contact information was found.
+        */
+       public ExternalDocumentation getExternalDocs(RestRequest req) {
+               VarResolverSession vr = req.getVarResolverSession();
+               JsonParser jp = JsonParser.DEFAULT;
+               try {
+                       if (this.externalDocs != null)
+                               return jp.parse(vr.resolve(this.externalDocs), 
ExternalDocumentation.class);
+                       String externalDocs = 
context.getMessages().findFirstString(req.getLocale(), "externalDocs");
+                       if (externalDocs != null)
+                               return jp.parse(vr.resolve(externalDocs), 
ExternalDocumentation.class);
+                       Swagger s = req.getSwaggerFromFile();
+                       if (s != null)
+                               return s.getExternalDocs();
+                       return null;
+               } catch (Exception e) {
+                       throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
+               }
+       }
+}

Propchange: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestInfoProvider.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestLogger.java
==============================================================================
--- 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestLogger.java
 (added)
+++ 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestLogger.java
 Fri Sep  8 23:25:34 2017
@@ -0,0 +1,257 @@
+// 
***************************************************************************************************************************
+// * 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 javax.servlet.http.HttpServletResponse.*;
+import static org.apache.juneau.internal.StringUtils.*;
+
+import java.text.*;
+import java.util.logging.*;
+
+import javax.servlet.http.*;
+
+import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * Logging utility class.
+ *
+ * <p>
+ * Subclasses can override these methods to tailor logging of HTTP requests.
+ * Subclasses MUST implement a no-arg public constructor.
+ *
+ * <p>
+ * RestLoggers are associated with servlets/resources in one of the following 
ways:
+ * <ul>
+ *     <li>The {@link RestResource#logger @RestResource.logger()} annotation.
+ *     <li>The {@link RestConfig#setLogger(Class)}/{@link 
RestConfig#setLogger(RestLogger)} methods.
+ * </ul>
+ */
+public abstract class RestLogger {
+
+       /**
+        * Returns the Java logger used for logging.
+        *
+        * <p>
+        * Subclasses can provide their own logger.
+        * The default implementation returns the logger created using 
<code>Logger.getLogger(getClass())</code>.
+        *
+        * @return The logger used for logging.
+        */
+       protected abstract Logger getLogger();
+
+       /**
+        * Log a message to the logger.
+        *
+        * <p>
+        * Subclasses can override this method if they wish to log messages 
using a library other than Java Logging
+        * (e.g. Apache Commons Logging).
+        *
+        * @param level The log level.
+        * @param cause The cause.
+        * @param msg The message to log.
+        * @param args Optional {@link MessageFormat}-style arguments.
+        */
+       protected abstract void log(Level level, Throwable cause, String msg, 
Object...args);
+
+       /**
+        * Log a message.
+        *
+        * <p>
+        * Equivalent to calling <code>log(level, <jk>null</jk>, msg, 
args);</code>
+        *
+        * @param level The log level.
+        * @param msg The message to log.
+        * @param args Optional {@link MessageFormat}-style arguments.
+        */
+       protected void log(Level level, String msg, Object...args) {
+               log(level, null, msg, args);
+       }
+
+       /**
+        * Same as {@link #log(Level, String, Object...)} excepts runs the 
arguments through {@link JsonSerializer#DEFAULT_LAX_READABLE}.
+        *
+        * <p>
+        * Serialization of arguments do not occur if message is not logged, so 
it's safe to use this method from within
+        * debug log statements.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bcode'>
+        *      logObjects(<jsf>DEBUG</jsf>, <js>"Pojo contents:\n{0}"</js>, 
myPojo);
+        * </p>
+        *
+        * @param level The log level.
+        * @param msg The message to log.
+        * @param args Optional {@link MessageFormat}-style arguments.
+        */
+       protected void logObjects(Level level, String msg, Object...args) {
+               for (int i = 0; i < args.length; i++)
+                       args[i] = 
JsonSerializer.DEFAULT_LAX_READABLE.toStringObject(args[i]);
+               log(level, null, msg, args);
+       }
+
+       /**
+        * Callback method for logging errors during HTTP requests.
+        *
+        * <p>
+        * Typically, subclasses will override this method and log errors 
themselves.
+        *
+        * <p>
+        * The default implementation simply logs errors to the 
<code>RestServlet</code> logger.
+        *
+        * <p>
+        * Here's a typical implementation showing how stack trace hashing can 
be used to reduce log file sizes...
+        * <p class='bcode'>
+        *      <jk>protected void</jk> onError(HttpServletRequest req, 
HttpServletResponse res, RestException e, <jk>boolean</jk> noTrace) {
+        *              String qs = req.getQueryString();
+        *              String msg = <js>"HTTP "</js> + req.getMethod() + <js>" 
"</js> + e.getStatus() + <js>" "</js> + req.getRequestURI() + (qs == 
<jk>null</jk> ? <js>""</js> : <js>"?"</js> + qs);
+        *              <jk>int</jk> c = e.getOccurrence();
+        *
+        *              <jc>// REST_useStackTraceHashes is disabled, so we have 
to log the exception every time.</jc>
+        *              <jk>if</jk> (c == 0)
+        *                      myLogger.log(Level.<jsf>WARNING</jsf>, 
<jsm>format</jsm>(<js>"[%s] %s"</js>, e.getStatus(), msg), e);
+        *
+        *              <jc>// This is the first time we've countered this 
error, so log a stack trace
+        *              // unless ?noTrace was passed in as a URL 
parameter.</jc>
+        *              <jk>else if</jk> (c == 1 &amp;&amp; ! noTrace)
+        *                      myLogger.log(Level.<jsf>WARNING</jsf>, 
<jsm>format</jsm>(<js>"[%h.%s.%s] %s"</js>, e.hashCode(), e.getStatus(), c, 
msg), e);
+        *
+        *              <jc>// This error occurred before.
+        *              // Only log the message, not the stack trace.</jc>
+        *              <jk>else</jk>
+        *                      myLogger.log(Level.<jsf>WARNING</jsf>, 
<jsm>format</jsm>(<js>"[%h.%s.%s] %s, %s"</js>, e.hashCode(), e.getStatus(), c, 
msg, e.getLocalizedMessage()));
+        *      }
+        * </p>
+        *
+        * @param req The servlet request object.
+        * @param res The servlet response object.
+        * @param e Exception indicating what error occurred.
+        */
+       protected void onError(HttpServletRequest req, HttpServletResponse res, 
RestException e) {
+               if (shouldLog(req, res, e)) {
+                       String qs = req.getQueryString();
+                       String msg = "HTTP " + req.getMethod() + " " + 
e.getStatus() + " " + req.getRequestURI() + (qs == null ? "" : "?" + qs);
+                       int c = e.getOccurrence();
+                       if (shouldLogStackTrace(req, res, e)) {
+                               msg = '[' + Integer.toHexString(e.hashCode()) + 
'.' + e.getStatus() + '.' + c + "] " + msg;
+                               log(Level.WARNING, e, msg);
+                       } else {
+                               msg = '[' + Integer.toHexString(e.hashCode()) + 
'.' + e.getStatus() + '.' + c + "] " + msg + ", " + e.getLocalizedMessage();
+                               log(Level.WARNING, msg);
+                       }
+               }
+       }
+
+       /**
+        * Returns <jk>true</jk> if the specified exception should be logged.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own logic for 
determining when exceptions are logged.
+        *
+        * <p>
+        * The default implementation will return <jk>false</jk> if 
<js>"noTrace=true"</js> is passed in the query string
+        * or <code>No-Trace: true</code> is specified in the header.
+        *
+        * @param req The HTTP request.
+        * @param res The HTTP response.
+        * @param e The exception.
+        * @return <jk>true</jk> if exception should be logged.
+        */
+       protected boolean shouldLog(HttpServletRequest req, HttpServletResponse 
res, RestException e) {
+               if (isNoTrace(req) && ! isDebug(req))
+                       return false;
+               return true;
+       }
+
+       /**
+        * Returns <jk>true</jk> if a stack trace should be logged for this 
exception.
+        *
+        * <p>
+        * Subclasses can override this method to provide their own logic for 
determining when stack traces are logged.
+        *
+        * <p>
+        * The default implementation will only log a stack trace if {@link 
RestException#getOccurrence()} returns
+        * <code>1</code> and the exception is not one of the following:
+        * <ul>
+        *      <li>{@link HttpServletResponse#SC_UNAUTHORIZED}
+        *      <li>{@link HttpServletResponse#SC_FORBIDDEN}
+        *      <li>{@link HttpServletResponse#SC_NOT_FOUND}
+        * </ul>
+        *
+        * @param req The HTTP request.
+        * @param res The HTTP response.
+        * @param e The exception.
+        * @return <jk>true</jk> if stack trace should be logged.
+        */
+       protected boolean shouldLogStackTrace(HttpServletRequest req, 
HttpServletResponse res, RestException e) {
+               if (e.getOccurrence() == 1) {
+                       switch (e.getStatus()) {
+                               case SC_UNAUTHORIZED:
+                               case SC_FORBIDDEN:
+                               case SC_NOT_FOUND:  return false;
+                               default:            return true;
+                       }
+               }
+               return false;
+       }
+
+       private static boolean isNoTrace(HttpServletRequest req) {
+               return "true".equals(req.getHeader("No-Trace")) || 
(req.getQueryString() != null && req.getQueryString().contains("noTrace=true"));
+       }
+
+       private static boolean isDebug(HttpServletRequest req) {
+               return "true".equals(req.getHeader("Debug"));
+       }
+
+       /**
+        * NO-OP logger.
+        *
+        * <p>
+        * Disables all logging.
+        *
+        * @author James Bognar ([email protected])
+        */
+       public static class NoOp extends RestLogger {
+
+               @Override /* RestLogger */
+               protected Logger getLogger() {
+                       return null;
+               }
+
+               @Override /* RestLogger */
+               protected void log(Level level, Throwable cause, String msg, 
Object...args) {}
+       }
+
+       /**
+        * Default logger.
+        *
+        * <p>
+        * Logs all messages to the logger returned by 
<code>Logger.<jsm>getLogger</jsm>(getClass().getName())</code>
+        */
+       public static class Normal extends RestLogger {
+
+               private final JuneauLogger logger = 
JuneauLogger.getLogger(getClass());
+
+               @Override /* RestLogger */
+               protected Logger getLogger() {
+                       return logger;
+               }
+
+               @Override /* RestLogger */
+               protected void log(Level level, Throwable cause, String msg, 
Object...args) {
+                       msg = format(msg, args);
+                       getLogger().log(level, msg, cause);
+               }
+       }
+}

Propchange: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestLogger.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcher.java
==============================================================================
--- 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcher.java
 (added)
+++ 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcher.java
 Fri Sep  8 23:25:34 2017
@@ -0,0 +1,79 @@
+// 
***************************************************************************************************************************
+// * 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 org.apache.juneau.rest.annotation.*;
+
+/**
+ * Class used for defining method-level matchers using the {@link 
RestMethod#matchers()} annotation.
+ *
+ * <p>
+ * Matchers are used to allow multiple Java methods to handle requests 
assigned to the same URL path pattern, but
+ * differing based on some request attribute, such as a specific header value.
+ * For example, matchers can be used to provide two different methods for 
handling requests from two different client
+ * versions.
+ *
+ * <p>
+ * Java methods with matchers associated with them are always attempted before 
Java methods without matchers.
+ * This allows a 'default' method to be defined to handle requests where no 
matchers match.
+ *
+ * <p>
+ * When multiple matchers are specified on a method, only one matcher is 
required to match.
+ * This is opposite from the {@link RestMethod#guards()} annotation, where all 
guards are required to match in order to
+ * execute the method.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ *     <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
+ *
+ *             <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/foo"</js>, 
matchers=IsDNT.<jk>class</jk>)
+ *             <jk>public</jk> Object doGetWithDNT() {
+ *                     <jc>// Handle request with Do-Not-Track specified</jc>
+ *             }
+ *
+ *             <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/foo"</js>)
+ *             <jk>public</jk> Object doGetWithoutDNT() {
+ *                     <jc>// Handle request without Do-Not-Track 
specified</jc>
+ *             }
+ *     }
+ *
+ *     <jk>public class</jk> IsDNT <jk>extends</jk> RestMatcher {
+ *             <ja>@Override</ja>
+ *             <jk>public boolean</jk> matches(RestRequest req) {
+ *                     <jk>return</jk> 
req.getHeader(<jk>int</jk>.<jk>class</jk>, <js>"DNT"</js>, 0) == 1;
+ *             }
+ *     }
+ * </p>
+ */
+public abstract class RestMatcher {
+
+       /**
+        * Returns <jk>true</jk> if the specified request matches this matcher.
+        *
+        * @param req The servlet request.
+        * @return <jk>true</jk> if the specified request matches this matcher.
+        */
+       public abstract boolean matches(RestRequest req);
+
+       /**
+        * Returns <jk>true</jk> if this matcher is required to match in order 
for the method to be invoked.
+        *
+        * <p>
+        * If <jk>false</jk>, then only one of the matchers must match.
+        *
+        * @return <jk>true</jk> if this matcher is required to match in order 
for the method to be invoked.
+        */
+       public boolean mustMatch() {
+               return false;
+       }
+}

Propchange: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcher.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherReflecting.java
==============================================================================
--- 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherReflecting.java
 (added)
+++ 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherReflecting.java
 Fri Sep  8 23:25:34 2017
@@ -0,0 +1,33 @@
+// 
***************************************************************************************************************************
+// * 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 java.lang.reflect.*;
+
+/**
+ * Subclass of {@link RestMatcher} that gives access to the servlet/resource 
and Java method it's applied to.
+ *
+ * <p>
+ * Essentially the same as {@link RestMatcher} except has a constructor where 
the Java method is passed in so that you
+ * can access annotations defined on it to tailor the behavior of the matcher.
+ */
+public abstract class RestMatcherReflecting extends RestMatcher {
+
+       /**
+        * Constructor.
+        *
+        * @param resource The REST servlet.
+        * @param javaMethod The Java method that this rest matcher is defined 
on.
+        */
+       protected RestMatcherReflecting(Object resource, Method javaMethod) {}
+}

Propchange: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherReflecting.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParam.java
==============================================================================
--- 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParam.java
 (added)
+++ 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParam.java
 Fri Sep  8 23:25:34 2017
@@ -0,0 +1,97 @@
+// 
***************************************************************************************************************************
+// * 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 java.lang.reflect.*;
+
+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 {
+
+       final RestParamType paramType;
+       final String name;
+       final Type type;
+
+       /**
+        * Constructor.
+        *
+        * @param paramType The Swagger parameter type.
+        * @param name
+        *      The parameter name.
+        *      Can be <jk>null</jk> if parameter doesn't have a name (e.g. the 
request body).
+        * @param type The object type to convert the parameter to.
+        */
+       protected RestParam(RestParamType paramType, String name, Type type) {
+               this.paramType = paramType;
+               this.name = name;
+               this.type = type;
+       }
+
+       /**
+        * Resolves the parameter object.
+        *
+        * @param req The rest request.
+        * @param res The rest response.
+        * @return The resolved object.
+        * @throws Exception
+        */
+       public abstract Object resolve(RestRequest req, RestResponse res) 
throws Exception;
+
+       /**
+        * Returns the parameter class type that this parameter resolver is 
meant for.
+        *
+        * @return The parameter class type, or <jk>null</jk> if the type 
passed in isn't an instance of {@link Class}.
+        */
+       protected Class<?> forClass() {
+               if (type instanceof Class)
+                       return (Class<?>)type;
+               return null;
+       }
+
+       /**
+        * Returns the swagger parameter type for this parameter as shown in 
the Swagger doc.
+        *
+        * @return the swagger parameter type for this parameter.
+        */
+       protected RestParamType getParamType() {
+               return paramType;
+       }
+
+       /**
+        * Returns the parameter name for this parameter as shown in the 
Swagger doc.
+        *
+        * @return the parameter name for this parameter.
+        */
+       protected String getName() {
+               return name;
+       }
+
+       /**
+        * Returns the parameter class type.
+        *
+        * @return the parameter class type.
+        */
+       public Type getType() {
+               return type;
+       }
+}

Propchange: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParam.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
==============================================================================
--- 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
 (added)
+++ 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
 Fri Sep  8 23:25:34 2017
@@ -0,0 +1,971 @@
+// 
***************************************************************************************************************************
+// * 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.internal.StringUtils.*;
+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,
+                       RequestQueryObject.class,
+                       RequestFormDataObject.class,
+                       HttpMethodObject.class,
+                       LoggerObject.class,
+                       JuneauLoggerObject.class,
+                       RestContextObject.class,
+                       ParserObject.class,
+                       LocaleObject.class,
+                       SwaggerObject.class,
+                       RequestPathMatchObject.class,
+                       RequestBodyObject.class,
+                       ConfigFileObject.class,
+                       UriContextObject.class,
+                       UriResolverObject.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.getPathMatch().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, firstNonEmpty(a.name(), 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, firstNonEmpty(a.name(), 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().getString(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, firstNonEmpty(a.name(), 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().getString(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, firstNonEmpty(a.name(), 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, firstNonEmpty(a.name(), 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.getPathMatch().getRemainder();
+               }
+       }
+
+       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 RequestQueryObject extends RestParam {
+
+               protected RequestQueryObject() {
+                       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 RequestPathMatchObject extends RestParam {
+
+               protected RequestPathMatchObject() {
+                       super(OTHER, null, RequestPathMatch.class);
+               }
+
+               @Override /* RestParam */
+               public Object resolve(RestRequest req, RestResponse res) throws 
Exception {
+                       return req.getPathMatch();
+               }
+       }
+
+       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();
+               }
+       }
+
+       static final class UriContextObject extends RestParam {
+
+               protected UriContextObject() {
+                       super(OTHER, null, UriContext.class);
+               }
+
+               @Override /* RestParam */
+               public Object resolve(RestRequest req, RestResponse res) throws 
Exception {
+                       return req.getUriContext();
+               }
+       }
+
+       static final class UriResolverObject extends RestParam {
+
+               protected UriResolverObject() {
+                       super(OTHER, null, UriResolver.class);
+               }
+
+               @Override /* RestParam */
+               public Object resolve(RestRequest req, RestResponse res) throws 
Exception {
+                       return req.getUriResolver();
+               }
+       }
+
+       private static boolean isCollection(Type t) {
+               return 
BeanContext.DEFAULT.getClassMeta(t).isCollectionOrArray();
+       }
+}

Propchange: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java
==============================================================================
--- 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java
 (added)
+++ 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java
 Fri Sep  8 23:25:34 2017
@@ -0,0 +1,48 @@
+// 
***************************************************************************************************************************
+// * 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;
+
+/**
+ * Represents the possible parameter types as defined by the Swagger 2.0 
specification.
+ */
+public enum RestParamType {
+
+       /** Path variable */
+       PATH("path"),
+
+       /** Header value */
+       HEADER("header"),
+
+       /** Form data entry */
+       FORMDATA("formData"),
+
+       /** Query parameter */
+       QUERY("query"),
+
+       /** Request body */
+       BODY("body"),
+
+       /** Not a standard Swagger-defined field */
+       OTHER("other");
+
+       private final String value;
+
+       private RestParamType(String value) {
+               this.value = value;
+       }
+
+       @Override /* Object */
+       public String toString() {
+               return value;
+       }
+}

Propchange: 
release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain


Reply via email to