This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 33779c5  REST refactoring.
33779c5 is described below

commit 33779c545059f85d691a77548bfffd203ca12e55
Author: JamesBognar <james.bog...@salesforce.com>
AuthorDate: Tue Feb 9 09:17:56 2021 -0500

    REST refactoring.
---
 .../java/org/apache/juneau/http/HeaderList.java    |  27 ++
 .../org/apache/juneau/http/NamedAttributeList.java |  16 +-
 .../juneau/rest/BasicSwaggerProviderSession.java   |   6 +-
 .../org/apache/juneau/rest/RequestAttributes.java  |   4 +-
 .../org/apache/juneau/rest/RequestFormData.java    |   2 +-
 .../org/apache/juneau/rest/RequestHeaders.java     |   2 +-
 .../java/org/apache/juneau/rest/RequestQuery.java  |   2 +-
 .../main/java/org/apache/juneau/rest/RestCall.java |   4 +-
 .../java/org/apache/juneau/rest/RestChildren.java  |   2 +-
 .../java/org/apache/juneau/rest/RestContext.java   |  79 ++--
 .../org/apache/juneau/rest/RestContextBuilder.java |   6 +-
 .../apache/juneau/rest/RestOperationContext.java   | 449 +++++++++++----------
 .../juneau/rest/RestOperationContextBuilder.java   |   2 +-
 .../java/org/apache/juneau/rest/RestRequest.java   |  39 +-
 .../java/org/apache/juneau/rest/RestResponse.java  |  18 +-
 .../java/org/apache/juneau/rest/RestServlet.java   |   2 +-
 .../juneau/rest/RrpcRestOperationContext.java      |   4 +-
 17 files changed, 385 insertions(+), 279 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderList.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderList.java
index 68a07f2..d74b387 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderList.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderList.java
@@ -74,6 +74,33 @@ public class HeaderList extends AList<Header> {
        }
 
        /**
+        * Appends or replaces the header values in this list.
+        *
+        * <p>
+        * If the header already exists in this list, it will be replaced with 
the new value.
+        * Otherwise it will be appended to the end of this list.
+        *
+        * @param values The values to append or replace in this list.
+        * @return This object (for method chaining).
+        */
+       public HeaderList appendUnique(Collection<Header> values) {
+               for (Header h : values) {
+                       boolean replaced = false;
+                       for (ListIterator<Header> li = listIterator(); 
li.hasNext();) {
+                               Header h2 = li.next();
+                               if (h2.getName().equalsIgnoreCase(h.getName())) 
{
+                                       li.set(h);
+                                       replaced = true;
+                                       break;
+                               }
+                       }
+                       if (! replaced)
+                               add(h);
+               }
+               return this;
+       }
+
+       /**
         * Returns the contents of this list as a {@link Header} array.
         *
         * @return The contents of this list as a {@link Header} array.
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/NamedAttributeList.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/NamedAttributeList.java
index e548652..9426125 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/NamedAttributeList.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/NamedAttributeList.java
@@ -55,7 +55,7 @@ public class NamedAttributeList extends AList<NamedAttribute> 
{
         * @param values The values to append or replace in this list.
         * @return This object (for method chaining).
         */
-       public NamedAttributeList appendUnique(NamedAttribute...values) {
+       public NamedAttributeList appendUnique(List<NamedAttribute> values) {
                for (NamedAttribute h : values) {
                        boolean replaced = false;
                        for (ListIterator<NamedAttribute> li = listIterator(); 
li.hasNext();) {
@@ -73,6 +73,20 @@ public class NamedAttributeList extends 
AList<NamedAttribute> {
        }
 
        /**
+        * Appends or replaces the named attribute values in this list.
+        *
+        * <p>
+        * If the named attribute already exists in this list, it will be 
replaced with the new value.
+        * Otherwise it will be appended to the end of this list.
+        *
+        * @param values The values to append or replace in this list.
+        * @return This object (for method chaining).
+        */
+       public NamedAttributeList appendUnique(NamedAttribute...values) {
+               return appendUnique(Arrays.asList(values));
+       }
+
+       /**
         * Returns the contents of this list as a {@link NamedAttribute} array.
         *
         * @return The contents of this list as a {@link NamedAttribute} array.
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicSwaggerProviderSession.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicSwaggerProviderSession.java
index 8262337..04fb4f9 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicSwaggerProviderSession.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicSwaggerProviderSession.java
@@ -210,7 +210,7 @@ public class BasicSwaggerProviderSession {
 
                        BeanSession bs = sm.createBeanSession();
 
-                       Method m = sm.method;
+                       Method m = sm.getJavaMethod();
                        MethodInfo mi = MethodInfo.of(m);
                        RestOp rm = mi.getLastAnnotation(RestOp.class);
                        String mn = m.getName();
@@ -504,13 +504,13 @@ public class BasicSwaggerProviderSession {
                                op.put("responses", new TreeMap<>(responses));
 
                        if (! op.containsKey("consumes")) {
-                               List<MediaType> mConsumes = 
sm.supportedContentTypes;
+                               List<MediaType> mConsumes = 
sm.getSupportedContentTypes();
                                if (! mConsumes.equals(consumes))
                                        op.put("consumes", mConsumes);
                        }
 
                        if (! op.containsKey("produces")) {
-                               List<MediaType> mProduces = 
sm.supportedAcceptTypes;
+                               List<MediaType> mProduces = 
sm.getSupportedAcceptTypes();
                                if (! mProduces.equals(produces))
                                        op.put("produces", mProduces);
                        }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttributes.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttributes.java
index 0e5f862..2421b7e 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttributes.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttributes.java
@@ -48,11 +48,11 @@ public class RequestAttributes extends OMap {
 
        /**
         * Adds values to these attributes if they're not already set.
-        * 
+        *
         * @param pairs The attributes to add.
         * @return This object (for method chaining).
         */
-       public RequestAttributes addDefault(NamedAttribute...pairs) {
+       public RequestAttributes addDefault(List<NamedAttribute> pairs) {
                for (NamedAttribute p : pairs) {
                        String key = p.getName();
                        Object value = p.getValue();
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
index c92a9ee..cc8e107 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
@@ -99,7 +99,7 @@ public class RequestFormData extends 
LinkedHashMap<String,String[]> {
         *      <br>Can be <jk>null</jk>.
         * @return This object (for method chaining).
         */
-       public RequestFormData addDefault(NameValuePair...pairs) {
+       public RequestFormData addDefault(Collection<NameValuePair> pairs) {
                for (NameValuePair p : pairs) {
                        String key = p.getName();
                        Object value = p.getValue();
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
index 979122b..0d46806 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
@@ -99,7 +99,7 @@ public class RequestHeaders extends TreeMap<String,String[]> {
         *      <br>Can be <jk>null</jk>.
         * @return This object (for method chaining).
         */
-       public RequestHeaders addDefault(Header...pairs) {
+       public RequestHeaders addDefault(List<Header> pairs) {
                for (Header p : pairs) {
                        String key = p.getName();
                        Object value = p.getValue();
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQuery.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQuery.java
index 1f55775..18adc18 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQuery.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQuery.java
@@ -103,7 +103,7 @@ public final class RequestQuery extends 
LinkedHashMap<String,String[]> {
         *      <br>Can be <jk>null</jk>.
         * @return This object (for method chaining).
         */
-       public RequestQuery addDefault(NameValuePair...pairs) {
+       public RequestQuery addDefault(Collection<NameValuePair> pairs) {
                for (NameValuePair p : pairs) {
                        String key = p.getName();
                        Object value = p.getValue();
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
index e787bdb..019a03e 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
@@ -60,7 +60,7 @@ public class RestCall {
        public RestCall(Object resource, RestContext context, 
HttpServletRequest req, HttpServletResponse res) {
                this.context = context;
                this.resource = resource;
-               beanFactory = BeanFactory.of(context.rootBeanFactory, resource);
+               beanFactory = BeanFactory.of(context.getRootBeanFactory(), 
resource);
                beanFactory.addBean(RestContext.class, context);
                request(req).response(res);
        }
@@ -322,7 +322,7 @@ public class RestCall {
         * @return The java method of this call, or <jk>null</jk> if it hasn't 
been determined yet.
         */
        public Method getJavaMethod() {
-               return opContext == null ? null : opContext.method;
+               return opContext == null ? null : opContext.getJavaMethod();
        }
 
        /**
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
index ca054de..d8987e0 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
@@ -65,7 +65,7 @@ public class RestChildren {
                String pi = call.getPathInfoUndecoded();
                if ((! children.isEmpty()) && pi != null && ! pi.equals("/")) {
                        for (RestContext rc : children.values()) {
-                               UrlPathMatcher upp = rc.pathMatcher;
+                               UrlPathMatcher upp = rc.getPathMatcher();
                                UrlPathMatch uppm = 
upp.match(call.getUrlPath());
                                if (uppm != null) {
                                        return 
Optional.of(RestChildMatch.create(uppm, rc));
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 50c7526..dd70620 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -20,7 +20,6 @@ import static org.apache.juneau.rest.HttpRuntimeException.*;
 import static org.apache.juneau.rest.logging.RestLoggingDetail.*;
 import static java.util.Collections.*;
 import static java.util.logging.Level.*;
-import static java.util.Arrays.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -3347,7 +3346,7 @@ public class RestContext extends BeanContext {
        private final Supplier<?> resource;
        private final Class<?> resourceClass;
 
-       final RestContextBuilder builder;
+       private final RestContextBuilder builder;
        private final boolean
                allowBodyParam,
                renderResponseStackTraces;
@@ -3355,8 +3354,8 @@ public class RestContext extends BeanContext {
                clientVersionHeader,
                uriAuthority,
                uriContext;
-       final String path, fullPath;
-       final UrlPathMatcher pathMatcher;
+       private final String path, fullPath;
+       private final UrlPathMatcher pathMatcher;
 
        private final Set<String> allowedMethodParams, allowedHeaderParams, 
allowedMethodHeaders;
 
@@ -3369,9 +3368,9 @@ public class RestContext extends BeanContext {
        private final List<MediaType>
                consumes,
                produces;
-       final org.apache.http.Header[] defaultRequestHeaders, 
defaultResponseHeaders;
-       final NamedAttribute[] defaultRequestAttributes;
-       private final ResponseHandler[] responseHandlers;
+       private final List<org.apache.http.Header> defaultRequestHeaders, 
defaultResponseHeaders;
+       private final List<NamedAttribute> defaultRequestAttributes;
+       private final List<ResponseHandler> responseHandlers;
        private final Messages messages;
        private final Config config;
        private final VarResolver varResolver;
@@ -3381,7 +3380,7 @@ public class RestContext extends BeanContext {
        private final SwaggerProvider swaggerProvider;
        private final HttpException initException;
        private final RestContext parentContext;
-       final BeanFactory rootBeanFactory;
+       private final BeanFactory rootBeanFactory;
        private final BeanFactory beanFactory;
        private final UriResolution uriResolution;
        private final UriRelativity uriRelativity;
@@ -3494,8 +3493,7 @@ public class RestContext extends BeanContext {
                        config = builder.config.resolving(vr.createSession());
                        bf.addBean(Config.class, config);
 
-                       responseHandlers = createResponseHandlers(r, cp, 
bf).asArray();
-                       bf.addBean(ResponseHandler[].class, responseHandlers);
+                       responseHandlers = 
unmodifiableList(createResponseHandlers(r, cp, bf));
 
                        callLogger = createCallLogger(r, cp, bf, l, ts);
                        bf.addBean(RestLogger.class, callLogger);
@@ -3521,9 +3519,9 @@ public class RestContext extends BeanContext {
                        staticFiles = createStaticFiles(r, cp, bf);
                        bf.addBean(StaticFiles.class, staticFiles);
 
-                       defaultRequestHeaders = createDefaultRequestHeaders(r, 
cp, bf).asArray();
-                       defaultResponseHeaders = 
createDefaultResponseHeaders(r, cp, bf).asArray();
-                       defaultRequestAttributes = 
createDefaultRequestAttributes(r, cp, bf).asArray();
+                       defaultRequestHeaders = 
unmodifiableList(createDefaultRequestHeaders(r, cp, bf));
+                       defaultResponseHeaders = 
unmodifiableList(createDefaultResponseHeaders(r, cp, bf));
+                       defaultRequestAttributes = 
unmodifiableList(createDefaultRequestAttributes(r, cp, bf));
 
                        opParams = createRestOperationParams(r, cp, 
bf).asArray();
                        hookMethodParams = createHookMethodParams(r, cp, 
bf).asArray();
@@ -3542,8 +3540,8 @@ public class RestContext extends BeanContext {
 
                        debugEnablement = createDebugEnablement(r, cp, bf);
 
-                       consumes = cp.getList(REST_consumes, 
MediaType.class).orElse(parsers.getSupportedMediaTypes());
-                       produces = cp.getList(REST_produces, 
MediaType.class).orElse(serializers.getSupportedMediaTypes());
+                       consumes = unmodifiableList(cp.getList(REST_consumes, 
MediaType.class).orElse(parsers.getSupportedMediaTypes()));
+                       produces = unmodifiableList(cp.getList(REST_produces, 
MediaType.class).orElse(serializers.getSupportedMediaTypes()));
 
                        fullPath = (builder.parentContext == null ? "" : 
(builder.parentContext.fullPath + '/')) + builder.getPath();
                        path = builder.getPath();
@@ -6127,7 +6125,7 @@ public class RestContext extends BeanContext {
         *
         * @return
         *      The header names allowed to be passed as URL parameters.
-        *      <br>The set is case-insensitive ordered.
+        *      <br>The set is case-insensitive ordered and unmodifiable.
         */
        public Set<String> getAllowedHeaderParams() {
                return allowedHeaderParams;
@@ -6142,7 +6140,7 @@ public class RestContext extends BeanContext {
         *
         * @return
         *      The method names allowed to be passed as <c>X-Method</c> 
headers.
-        *      <br>The set is case-insensitive ordered.
+        *      <br>The set is case-insensitive ordered and unmodifiable.
         */
        public Set<String> getAllowedMethodHeaders() {
                return allowedMethodHeaders;
@@ -6157,7 +6155,7 @@ public class RestContext extends BeanContext {
         *
         * @return
         *      The method names allowed to be passed as <c>method</c> URL 
parameters.
-        *      <br>The set is case-insensitive ordered.
+        *      <br>The set is case-insensitive ordered and unmodifiable.
         */
        public Set<String> getAllowedMethodParams() {
                return allowedMethodParams;
@@ -6280,7 +6278,7 @@ public class RestContext extends BeanContext {
         * </ul>
         *
         * @return
-        *      The supported <c>Accept</c> header values for this resource.
+        *      An unmodifiable list of supported <c>Accept</c> header values 
for this resource.
         *      <br>Never <jk>null</jk>.
         */
        public List<MediaType> getProduces() {
@@ -6296,7 +6294,7 @@ public class RestContext extends BeanContext {
         * </ul>
         *
         * @return
-        *      The supported <c>Content-Type</c> header values for this 
resource.
+        *      An unmodifiable list of supported <c>Content-Type</c> header 
values for this resource.
         *      <br>Never <jk>null</jk>.
         */
        public List<MediaType> getConsumes() {
@@ -6311,11 +6309,11 @@ public class RestContext extends BeanContext {
         * </ul>
         *
         * @return
-        *      The default request headers for this resource.
+        *      The default request headers for this resource in an 
unmodifiable list.
         *      <br>Never <jk>null</jk>.
         */
        public List<org.apache.http.Header> getDefaultRequestHeaders() {
-               return unmodifiableList(asList(defaultRequestHeaders));
+               return defaultRequestHeaders;
        }
 
        /**
@@ -6326,11 +6324,11 @@ public class RestContext extends BeanContext {
         * </ul>
         *
         * @return
-        *      The default request headers for this resource.
+        *      The default request headers for this resource in an 
unmodifiable list.
         *      <br>Never <jk>null</jk>.
         */
        public List<NamedAttribute> getDefaultRequestAttributes() {
-               return unmodifiableList(asList(defaultRequestAttributes));
+               return defaultRequestAttributes;
        }
 
        /**
@@ -6341,11 +6339,11 @@ public class RestContext extends BeanContext {
         * </ul>
         *
         * @return
-        *      The default response headers for this resource.
+        *      The default response headers for this resource in an 
unmodifiable list.
         *      <br>Never <jk>null</jk>.
         */
        public List<org.apache.http.Header> getDefaultResponseHeaders() {
-               return unmodifiableList(asList(defaultResponseHeaders));
+               return defaultResponseHeaders;
        }
 
        /**
@@ -6359,7 +6357,7 @@ public class RestContext extends BeanContext {
         *      The response handlers associated with this resource.
         *      <br>Never <jk>null</jk>.
         */
-       protected ResponseHandler[] getResponseHandlers() {
+       protected List<ResponseHandler> getResponseHandlers() {
                return responseHandlers;
        }
 
@@ -6475,6 +6473,33 @@ public class RestContext extends BeanContext {
        }
 
        /**
+        * Returns the builder that created this context.
+        *
+        * @return The builder that created this context.
+        */
+       public ServletConfig getBuilder() {
+               return builder;
+       }
+
+       /**
+        * Returns the path matcher for this context.
+        *
+        * @return The path matcher for this context.
+        */
+       public UrlPathMatcher getPathMatcher() {
+               return pathMatcher;
+       }
+
+       /**
+        * Returns the root bean factory for this context.
+        *
+        * @return The root bean factory for this context.
+        */
+       public BeanFactory getRootBeanFactory() {
+               return rootBeanFactory;
+       }
+
+       /**
         * Returns the swagger for the REST resource.
         *
         * @param locale The locale of the swagger to return.
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
index 128ef3e..df0e49a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
@@ -213,13 +213,13 @@ public class RestContextBuilder extends 
BeanContextBuilder implements ServletCon
                if (resource.isPresent()) {
                        Object r = resource.get();
                        x = BeanFactory
-                               .of(parentContext.isPresent() ? 
parentContext.get().rootBeanFactory : null, r)
+                               .of(parentContext.isPresent() ? 
parentContext.get().getRootBeanFactory() : null, r)
                                .beanCreateMethodFinder(BeanFactory.class, 
resource)
                                .find("createBeanFactory")
                                .run();
                }
                if (x == null && parentContext.isPresent()) {
-                       x = parentContext.get().rootBeanFactory;
+                       x = parentContext.get().getRootBeanFactory();
                }
                return BeanFactory.of(x, resource.orElse(null));
        }
@@ -2656,7 +2656,7 @@ public class RestContextBuilder extends 
BeanContextBuilder implements ServletCon
 
        @Override /* ServletConfig */
        public ServletContext getServletContext() {
-               return inner != null ? inner.getServletContext() : 
parentContext != null ? parentContext.builder.getServletContext() : null;
+               return inner != null ? inner.getServletContext() : 
parentContext != null ? parentContext.getBuilder().getServletContext() : null;
        }
 
        @Override /* ServletConfig */
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
index 5d9c206..5987389 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
@@ -20,12 +20,12 @@ import static org.apache.juneau.httppart.HttpPartType.*;
 import static org.apache.juneau.rest.RestContext.*;
 import static org.apache.juneau.rest.util.RestUtils.*;
 import static org.apache.juneau.rest.HttpRuntimeException.*;
+import static java.util.Collections.*;
 
 import java.lang.annotation.*;
 import java.lang.reflect.Method;
 import java.util.*;
 import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
 import java.util.function.*;
 
 import javax.servlet.*;
@@ -55,7 +55,6 @@ import org.apache.juneau.rest.guards.*;
 import org.apache.juneau.rest.logging.*;
 import org.apache.juneau.rest.util.*;
 import org.apache.juneau.serializer.*;
-import org.apache.juneau.svl.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -674,40 +673,37 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
 
        private final String httpMethod;
        private final UrlPathMatcher[] pathMatchers;
-       final RestOperationParam[] opParams;
+       private final RestOperationParam[] opParams;
        private final RestGuard[] guards;
        private final RestMatcher[] optionalMatchers;
        private final RestMatcher[] requiredMatchers;
        private final RestConverter[] converters;
        private final Integer priority;
        private final RestContext context;
-       final Method method;
-       final MethodInvoker methodInvoker;
-       final MethodInfo mi;
-       final SerializerGroup serializers;
-       final ParserGroup parsers;
-       final EncoderGroup encoders;
-       final HttpPartSerializer partSerializer;
-       final HttpPartParser partParser;
-       final JsonSchemaGenerator jsonSchemaGenerator;
-       final org.apache.http.Header[] defaultRequestHeaders, 
defaultResponseHeaders;
-       final NameValuePair[] defaultRequestQuery, defaultRequestFormData;
-       final NamedAttribute[] defaultRequestAttributes;
-       final String defaultCharset;
-       final long maxInput;
-       final List<MediaType>
+       private final Method method;
+       private final MethodInvoker methodInvoker;
+       private final MethodInfo mi;
+       private final SerializerGroup serializers;
+       private final ParserGroup parsers;
+       private final EncoderGroup encoders;
+       private final HttpPartSerializer partSerializer;
+       private final HttpPartParser partParser;
+       private final JsonSchemaGenerator jsonSchemaGenerator;
+       private final List<org.apache.http.Header> defaultRequestHeaders, 
defaultResponseHeaders;
+       private final List<NameValuePair> defaultRequestQuery, 
defaultRequestFormData;
+       private final List<NamedAttribute> defaultRequestAttributes;
+       private final String defaultCharset;
+       private final long maxInput;
+       private final List<MediaType>
                supportedAcceptTypes,
                supportedContentTypes;
-       final RestLogger callLogger;
+       private final RestLogger callLogger;
 
-       final Map<Class<?>,ResponseBeanMeta> responseBeanMetas = new 
ConcurrentHashMap<>();
-       final Map<Class<?>,ResponsePartMeta> headerPartMetas = new 
ConcurrentHashMap<>();
-       final Map<Class<?>,ResponsePartMeta> bodyPartMetas = new 
ConcurrentHashMap<>();
-       final ResponseBeanMeta responseMeta;
-
-       final Map<Integer,AtomicInteger> statusCodes = new 
ConcurrentHashMap<>();
-
-       final int hierarchyDepth;
+       private final Map<Class<?>,ResponseBeanMeta> responseBeanMetas = new 
ConcurrentHashMap<>();
+       private final Map<Class<?>,ResponsePartMeta> headerPartMetas = new 
ConcurrentHashMap<>();
+       private final Map<Class<?>,ResponsePartMeta> bodyPartMetas = new 
ConcurrentHashMap<>();
+       private final ResponseBeanMeta responseMeta;
+       private final int hierarchyDepth;
 
        /**
         * Creator.
@@ -739,22 +735,22 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                        mi = MethodInfo.of(method).accessible();
                        Object r = context.getResource();
 
-                       BeanFactory bf = 
BeanFactory.of(context.rootBeanFactory, r)
+                       BeanFactory bf = 
BeanFactory.of(context.getRootBeanFactory(), r)
                                .addBean(RestOperationContext.class, this)
                                .addBean(Method.class, method)
                                .addBean(ContextProperties.class, cp);
                        bf.addBean(BeanFactory.class, bf);
 
-                       serializers = createSerializers(r, bf, cp);
+                       serializers = createSerializers(r, cp, bf);
                        bf.addBean(SerializerGroup.class, serializers);
 
-                       parsers = createParsers(r, bf, cp);
+                       parsers = createParsers(r, cp, bf);
                        bf.addBean(ParserGroup.class, parsers);
 
-                       partSerializer = createPartSerializer(r, bf, cp);
+                       partSerializer = createPartSerializer(r, cp, bf);
                        bf.addBean(HttpPartSerializer.class, partSerializer);
 
-                       partParser = createPartParser(r, bf, cp);
+                       partParser = createPartParser(r, cp, bf);
                        bf.addBean(HttpPartParser.class, partParser);
 
                        converters = createConverters(r, cp, bf).asArray();
@@ -774,17 +770,17 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                        encoders = createEncoders(r, cp, bf);
                        bf.addBean(EncoderGroup.class, encoders);
 
-                       jsonSchemaGenerator = createJsonSchemaGenerator(r, bf, 
cp);
+                       jsonSchemaGenerator = createJsonSchemaGenerator(r, cp, 
bf);
                        bf.addBean(JsonSchemaGenerator.class, 
jsonSchemaGenerator);
 
-                       supportedAcceptTypes = cp.getList(REST_produces, 
MediaType.class).orElse(serializers.getSupportedMediaTypes());
-                       supportedContentTypes = cp.getList(REST_consumes, 
MediaType.class).orElse(parsers.getSupportedMediaTypes());
+                       supportedAcceptTypes = 
unmodifiableList(cp.getList(REST_produces, 
MediaType.class).orElse(serializers.getSupportedMediaTypes()));
+                       supportedContentTypes = 
unmodifiableList(cp.getList(REST_consumes, 
MediaType.class).orElse(parsers.getSupportedMediaTypes()));
 
-                       defaultRequestHeaders = createDefaultRequestHeaders(r, 
cp, bf, method, context).asArray();
-                       defaultResponseHeaders = 
createDefaultResponseHeaders(r, cp, bf, method, context).asArray();
-                       defaultRequestQuery = createDefaultRequestQuery(r, cp, 
bf, method).asArray();
-                       defaultRequestFormData = 
createDefaultRequestFormData(r, cp, bf, method).asArray();
-                       defaultRequestAttributes = 
createDefaultRequestAttributes(r, cp, bf, method, context).asArray();
+                       defaultRequestHeaders = 
unmodifiableList(createDefaultRequestHeaders(r, cp, bf, method, context));
+                       defaultResponseHeaders = 
unmodifiableList(createDefaultResponseHeaders(r, cp, bf, method, context));
+                       defaultRequestQuery = 
unmodifiableList(createDefaultRequestQuery(r, cp, bf, method));
+                       defaultRequestFormData = 
unmodifiableList(createDefaultRequestFormData(r, cp, bf, method));
+                       defaultRequestAttributes = 
unmodifiableList(createDefaultRequestAttributes(r, cp, bf, method, context));
 
                        int _hierarchyDepth = 0;
                        Class<?> sc = 
method.getDeclaringClass().getSuperclass();
@@ -801,7 +797,7 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                                _httpMethod = "*";
                        httpMethod = _httpMethod.toUpperCase(Locale.ENGLISH);
 
-                       defaultCharset = cp.get(REST_defaultCharset, 
String.class).orElse("utf-8");
+                       defaultCharset = 
cp.getString(REST_defaultCharset).orElse("utf-8");
 
                        maxInput = 
StringUtils.parseLongWithSuffix(cp.get(REST_maxInput, 
String.class).orElse("100M"));
 
@@ -819,29 +815,6 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                }
        }
 
-       private String joinnlFirstNonEmptyArray(String[]...s) {
-               for (String[] ss : s)
-                       if (ss.length > 0)
-                               return joinnl(ss);
-               return null;
-       }
-
-       ResponseBeanMeta getResponseBeanMeta(Object o) {
-               if (o == null)
-                       return null;
-               Class<?> c = o.getClass();
-               ResponseBeanMeta rbm = responseBeanMetas.get(c);
-               if (rbm == null) {
-                       rbm = ResponseBeanMeta.create(c, 
serializers.getContextProperties());
-                       if (rbm == null)
-                               rbm = ResponseBeanMeta.NULL;
-                       responseBeanMetas.put(c, rbm);
-               }
-               if (rbm == ResponseBeanMeta.NULL)
-                       return null;
-               return rbm;
-       }
-
        /**
         * Instantiates the result converters for this REST resource method.
         *
@@ -1092,13 +1065,13 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
         * </ul>
         *
         * @param resource The REST resource object.
-        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @param properties The property store of this method.
+        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @return The serializers for this REST resource.
         * @throws Exception If serializers could not be instantiated.
         * @seealso #REST_serializers
         */
-       protected SerializerGroup createSerializers(Object resource, 
BeanFactory beanFactory, ContextProperties properties) throws Exception {
+       protected SerializerGroup createSerializers(Object resource, 
ContextProperties properties, BeanFactory beanFactory) throws Exception {
 
                SerializerGroup g = 
beanFactory.getBean(SerializerGroup.class).orElse(null);
 
@@ -1153,13 +1126,13 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
         * </ul>
         *
         * @param resource The REST resource object.
-        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @param properties The property store of this method.
+        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @return The parsers for this REST resource.
         * @throws Exception If parsers could not be instantiated.
         * @seealso #REST_parsers
         */
-       protected ParserGroup createParsers(Object resource, BeanFactory 
beanFactory, ContextProperties properties) throws Exception {
+       protected ParserGroup createParsers(Object resource, ContextProperties 
properties, BeanFactory beanFactory) throws Exception {
 
                ParserGroup g = 
beanFactory.getBean(ParserGroup.class).orElse(null);
 
@@ -1215,13 +1188,13 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
         * </ul>
         *
         * @param resource The REST resource object.
-        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @param properties The property store of this method.
+        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @return The HTTP part serializer for this REST resource.
         * @throws Exception If serializer could not be instantiated.
         * @seealso #REST_partSerializer
         */
-       protected HttpPartSerializer createPartSerializer(Object resource, 
BeanFactory beanFactory, ContextProperties properties) throws Exception {
+       protected HttpPartSerializer createPartSerializer(Object resource, 
ContextProperties properties, BeanFactory beanFactory) throws Exception {
 
                HttpPartSerializer x = null;
 
@@ -1273,13 +1246,13 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
         * </ul>
         *
         * @param resource The REST resource object.
-        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @param properties The property store of this method.
+        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @return The HTTP part parser for this REST resource.
         * @throws Exception If parser could not be instantiated.
         * @seealso #REST_partParser
         */
-       protected HttpPartParser createPartParser(Object resource, BeanFactory 
beanFactory, ContextProperties properties) throws Exception {
+       protected HttpPartParser createPartParser(Object resource, 
ContextProperties properties, BeanFactory beanFactory) throws Exception {
 
                HttpPartParser x = null;
 
@@ -1350,12 +1323,12 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
         * Instantiates the JSON-schema generator for this method.
         *
         * @param resource The REST resource object.
-        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @param properties The property store of this method.
+        * @param beanFactory The bean factory to use for retrieving and 
creating beans.
         * @return The JSON-schema generator for this method.
         * @throws Exception If schema generator could not be instantiated.
         */
-       protected JsonSchemaGenerator createJsonSchemaGenerator(Object 
resource, BeanFactory beanFactory, ContextProperties properties) throws 
Exception {
+       protected JsonSchemaGenerator createJsonSchemaGenerator(Object 
resource, ContextProperties properties, BeanFactory beanFactory) throws 
Exception {
 
                JsonSchemaGenerator x = null;
 
@@ -1395,7 +1368,7 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
 
                HeaderList x = HeaderList.create();
 
-               x.appendUnique(context.defaultRequestHeaders);
+               x.appendUnique(context.getDefaultRequestHeaders());
 
                
x.appendUnique(properties.getInstanceArray(RESTOP_defaultRequestHeaders, 
org.apache.http.Header.class, beanFactory).orElse(new 
org.apache.http.Header[0]));
 
@@ -1441,7 +1414,7 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
 
                HeaderList x = HeaderList.create();
 
-               x.appendUnique(context.defaultResponseHeaders);
+               x.appendUnique(context.getDefaultResponseHeaders());
 
                
x.appendUnique(properties.getInstanceArray(RESTOP_defaultResponseHeaders, 
org.apache.http.Header.class, beanFactory).orElse(new 
org.apache.http.Header[0]));
 
@@ -1470,7 +1443,7 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
        protected NamedAttributeList createDefaultRequestAttributes(Object 
resource, ContextProperties properties, BeanFactory beanFactory, Method method, 
RestContext context) throws Exception {
                NamedAttributeList x = NamedAttributeList.create();
 
-               x.appendUnique(context.defaultRequestAttributes);
+               x.appendUnique(context.getDefaultRequestAttributes());
 
                
x.appendUnique(properties.getInstanceArray(RESTOP_defaultRequestAttributes, 
NamedAttribute.class, beanFactory).orElse(new NamedAttribute[0]));
 
@@ -1573,6 +1546,22 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                return x;
        }
 
+       ResponseBeanMeta getResponseBeanMeta(Object o) {
+               if (o == null)
+                       return null;
+               Class<?> c = o.getClass();
+               ResponseBeanMeta rbm = responseBeanMetas.get(c);
+               if (rbm == null) {
+                       rbm = ResponseBeanMeta.create(c, 
serializers.getContextProperties());
+                       if (rbm == null)
+                               rbm = ResponseBeanMeta.NULL;
+                       responseBeanMetas.put(c, rbm);
+               }
+               if (rbm == ResponseBeanMeta.NULL)
+                       return null;
+               return rbm;
+       }
+
        ResponsePartMeta getResponseHeaderMeta(Object o) {
                if (o == null)
                        return null;
@@ -1616,43 +1605,175 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
        }
 
        /**
-        * Returns <jk>true</jk> if this Java method has any guards or matchers.
-        */
-       boolean hasGuardsOrMatchers() {
-               return (guards.length != 0 || requiredMatchers.length != 0 || 
optionalMatchers.length != 0);
-       }
-
-       /**
         * Returns the HTTP method name (e.g. <js>"GET"</js>).
+        *
+        * @return The HTTP method name.
         */
-       String getHttpMethod() {
+       public String getHttpMethod() {
                return httpMethod;
        }
 
        /**
         * Returns the path pattern for this method.
+        *
+        * @return The path pattern.
         */
-       String getPathPattern() {
+       public String getPathPattern() {
                return pathMatchers[0].toString();
        }
 
+
        /**
-        * Returns <jk>true</jk> if the specified request object can call this 
method.
+        * Bean property getter:  <property>serializers</property>.
+        *
+        * @return The value of the <property>serializers</property> property 
on this bean, or <jk>null</jk> if it is not set.
         */
-       boolean isRequestAllowed(RestRequest req) {
-               for (RestGuard guard : guards) {
-                       req.setJavaMethod(method);
-                       if (! guard.isRequestAllowed(req))
-                               return false;
-               }
-               return true;
+       public SerializerGroup getSerializers() {
+               return serializers;
        }
 
-       boolean matches(UrlPath urlPath) {
-               for (UrlPathMatcher p : pathMatchers)
-                       if (p.match(urlPath) != null)
-                               return true;
-               return false;
+       /**
+        * Bean property getter:  <property>parsers</property>.
+        *
+        * @return The value of the <property>parsers</property> property on 
this bean, or <jk>null</jk> if it is not set.
+        */
+       public ParserGroup getParsers() {
+               return parsers;
+       }
+
+       /**
+        * Bean property getter:  <property>encoders</property>.
+        *
+        * @return The value of the <property>encoders</property> property on 
this bean, or <jk>null</jk> if it is not set.
+        */
+       public EncoderGroup getEncoders() {
+               return encoders;
+       }
+
+       /**
+        * Bean property getter:  <property>partSerializer</property>.
+        *
+        * @return The value of the <property>partSerializer</property> 
property on this bean, or <jk>null</jk> if it is not set.
+        */
+       public HttpPartSerializer getPartSerializer() {
+               return partSerializer;
+       }
+
+       /**
+        * Bean property getter:  <property>partParser</property>.
+        *
+        * @return The value of the <property>partParser</property> property on 
this bean, or <jk>null</jk> if it is not set.
+        */
+       public HttpPartParser getPartParser() {
+               return partParser;
+       }
+
+       /**
+        * Returns the JSON-Schema generator applicable to this Java method.
+        *
+        * @return The JSON-Schema generator applicable to this Java method.
+        */
+       public JsonSchemaGenerator getJsonSchemaGenerator() {
+               return jsonSchemaGenerator;
+       }
+
+       /**
+        * Returns the underlying Java method that this context belongs to.
+        *
+        * @return The underlying Java method that this context belongs to.
+        */
+       public Method getJavaMethod() {
+               return method;
+       }
+
+       /**
+        * Returns the default request headers.
+        *
+        * @return The default request headers.  Never <jk>null</jk>.
+        */
+       public List<org.apache.http.Header> getDefaultRequestHeaders() {
+               return defaultRequestHeaders;
+       }
+
+       /**
+        * Returns the default response headers.
+        *
+        * @return The default response headers.  Never <jk>null</jk>.
+        */
+       public List<org.apache.http.Header> getDefaultResponseHeaders() {
+               return defaultResponseHeaders;
+       }
+
+       /**
+        * Returns the default request query parameters.
+        *
+        * @return The default request query parameters.  Never <jk>null</jk>.
+        */
+       public List<NameValuePair> getDefaultRequestQuery() {
+               return defaultRequestQuery;
+       }
+
+       /**
+        * Returns the default form data parameters.
+        *
+        * @return The default form data parameters.  Never <jk>null</jk>.
+        */
+       public List<NameValuePair> getDefaultRequestFormData() {
+               return defaultRequestFormData;
+       }
+
+       /**
+        * Returns the default request attributes.
+        *
+        * @return The default request attributes.  Never <jk>null</jk>.
+        */
+       public List<NamedAttribute> getDefaultRequestAttributes() {
+               return defaultRequestAttributes;
+       }
+
+       /**
+        * Returns the default charset.
+        *
+        * @return The default charset.  Never <jk>null</jk>.
+        */
+       public String getDefaultCharset() {
+               return defaultCharset;
+       }
+
+       /**
+        * Returns the max number of bytes to process in the input body.
+        *
+        * @return The max number of bytes to process in the input body.
+        */
+       public long getMaxInput() {
+               return maxInput;
+       }
+
+       /**
+        * Returns the list of supported content types.
+        *
+        * @return An unmodifiable list.
+        */
+       public List<MediaType> getSupportedContentTypes() {
+               return supportedContentTypes;
+       }
+
+       /**
+        * Returns a list of supported accept types.
+        *
+        * @return An unmodifiable list.
+        */
+       public List<MediaType> getSupportedAcceptTypes() {
+               return supportedAcceptTypes;
+       }
+
+       /**
+        * Returns the response bean meta if this method returns a {@link 
Response}-annotated bean.
+        *
+        * @return The response bean meta or <jk>null</jk> if it's not a {@link 
Response}-annotated bean.
+        */
+       public ResponseBeanMeta getResponseMeta() {
+               return responseMeta;
        }
 
        /**
@@ -1712,14 +1833,6 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                }
        }
 
-       private UrlPathMatch matchPattern(RestCall call) {
-               UrlPathMatch pm = null;
-               for (UrlPathMatcher pp : pathMatchers)
-                       if (pm == null)
-                               pm = pp.match(call.getUrlPath());
-               return pm;
-       }
-
        /**
         * Workhorse method.
         *
@@ -1871,88 +1984,6 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                return 0;
        }
 
-       /**
-        * Bean property getter:  <property>serializers</property>.
-        *
-        * @return The value of the <property>serializers</property> property 
on this bean, or <jk>null</jk> if it is not set.
-        */
-       public SerializerGroup getSerializers() {
-               return serializers;
-       }
-
-       /**
-        * Bean property getter:  <property>parsers</property>.
-        *
-        * @return The value of the <property>parsers</property> property on 
this bean, or <jk>null</jk> if it is not set.
-        */
-       public ParserGroup getParsers() {
-               return parsers;
-       }
-
-       /**
-        * Bean property getter:  <property>partSerializer</property>.
-        *
-        * @return The value of the <property>partSerializer</property> 
property on this bean, or <jk>null</jk> if it is not set.
-        */
-       public HttpPartSerializer getPartSerializer() {
-               return partSerializer;
-       }
-
-       /**
-        * Bean property getter:  <property>partParser</property>.
-        *
-        * @return The value of the <property>partParser</property> property on 
this bean, or <jk>null</jk> if it is not set.
-        */
-       public HttpPartParser getPartParser() {
-               return partParser;
-       }
-
-       /**
-        * Returns the JSON-Schema generator applicable to this Java method.
-        *
-        * @return The JSON-Schema generator applicable to this Java method.
-        */
-       public JsonSchemaGenerator getJsonSchemaGenerator() {
-               return jsonSchemaGenerator;
-       }
-
-       /**
-        * Returns the underlying Java method that this context belongs to.
-        *
-        * @return The underlying Java method that this context belongs to.
-        */
-       public Method getJavaMethod() {
-               return method;
-       }
-
-       Optional<List<MediaType>> supportedAcceptTypes() {
-               return Optional.of(supportedAcceptTypes);
-       }
-
-       Optional<List<MediaType>> supportedContentTypes() {
-               return Optional.of(supportedContentTypes);
-       }
-
-       Optional<ContextProperties> contextProperties() {
-               return Optional.of(getContextProperties());
-       }
-
-       Optional<String> defaultCharset() {
-               return Optional.of(defaultCharset);
-       }
-
-       Optional<NameValuePair[]> defaultRequestFormData() {
-               return Optional.of(defaultRequestFormData);
-       }
-
-       Optional<SerializerGroup> serializers() {
-               return Optional.of(serializers);
-       }
-
-       Optional<ParserGroup> parsers() {
-               return Optional.of(parsers);
-       }
-
        @Override /* Object */
        public boolean equals(Object o) {
                return (o instanceof RestOperationContext) && eq(this, 
(RestOperationContext)o, (x,y)->x.method.equals(y.method));
@@ -1964,22 +1995,6 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
-       // Utility methods.
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       static String[] resolveVars(VarResolver vr, String[] in) {
-               String[] out = new String[in.length];
-               for (int i = 0; i < in.length; i++)
-                       out[i] = vr.resolve(in[i]);
-               return out;
-       }
-
-       static HttpPartSerializer createPartSerializer(Class<? extends 
HttpPartSerializer> c, ContextProperties cp, HttpPartSerializer _default) {
-               HttpPartSerializer hps = castOrCreate(HttpPartSerializer.class, 
c, true, cp);
-               return hps == null ? _default : hps;
-       }
-
-       
//-----------------------------------------------------------------------------------------------------------------
        // Other methods.
        
//-----------------------------------------------------------------------------------------------------------------
 
@@ -1998,4 +2013,28 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                                .a("priority", priority)
                        );
        }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Helper methods.
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       private static HttpPartSerializer createPartSerializer(Class<? extends 
HttpPartSerializer> c, ContextProperties cp, HttpPartSerializer _default) {
+               HttpPartSerializer hps = castOrCreate(HttpPartSerializer.class, 
c, true, cp);
+               return hps == null ? _default : hps;
+       }
+
+       private String joinnlFirstNonEmptyArray(String[]...s) {
+               for (String[] ss : s)
+                       if (ss.length > 0)
+                               return joinnl(ss);
+               return null;
+       }
+
+       private UrlPathMatch matchPattern(RestCall call) {
+               UrlPathMatch pm = null;
+               for (UrlPathMatcher pp : pathMatchers)
+                       if (pm == null)
+                               pm = pp.match(call.getUrlPath());
+               return pm;
+       }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContextBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContextBuilder.java
index 841c8db..f604d40 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContextBuilder.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContextBuilder.java
@@ -70,7 +70,7 @@ public class RestOperationContextBuilder extends 
BeanContextBuilder {
 
                this.restContext = context;
                this.restMethod = method;
-               this.beanFactory = context.rootBeanFactory;
+               this.beanFactory = context.getRootBeanFactory();
 
                String sig = method.getDeclaringClass().getName() + '.' + 
method.getName();
                MethodInfo mi = MethodInfo.of(context.getResourceClass(), 
method);
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
index c4d016c..d66a0ae 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -197,28 +197,28 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         */
        final void init(RestOperationContext roc) throws IOException {
                this.opContext = Optional.of(roc);
-               this.javaMethod = roc.method;
+               this.javaMethod = roc.getJavaMethod();
                this.beanSession = roc.createSession();
-               this.partParserSession = 
roc.partParser.createPartSession(getParserSessionArgs());
-               this.partSerializerSession = 
roc.partSerializer.createPartSession(getSerializerSessionArgs());
+               this.partParserSession = 
roc.getPartParser().createPartSession(getParserSessionArgs());
+               this.partSerializerSession = 
roc.getPartSerializer().createPartSession(getSerializerSessionArgs());
                this.pathParams
                        .parser(partParserSession);
                this.queryParams
-                       .addDefault(roc.defaultRequestQuery)
+                       .addDefault(roc.getDefaultRequestQuery())
                        .parser(partParserSession);
                this.headers
-                       .addDefault(roc.defaultRequestHeaders)
-                       .addDefault(context.defaultRequestHeaders)
+                       .addDefault(roc.getDefaultRequestHeaders())
+                       .addDefault(context.getDefaultRequestHeaders())
                        .parser(partParserSession);
                this.attrs = new RequestAttributes(this);
                this.attrs
-                       .addDefault(roc.defaultRequestAttributes)
-                       .addDefault(context.defaultRequestAttributes);
+                       .addDefault(roc.getDefaultRequestAttributes())
+                       .addDefault(context.getDefaultRequestAttributes());
                this.body
-                       .encoders(roc.encoders)
-                       .parsers(roc.parsers)
+                       .encoders(roc.getEncoders())
+                       .parsers(roc.getParsers())
                        .headers(headers)
-                       .maxInput(roc.maxInput);
+                       .maxInput(roc.getMaxInput());
 
                if (isDebug()) {
                        inner = CachingHttpServletRequest.wrap(inner);
@@ -311,7 +311,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         * @return The set of media types registered in the serializer group of 
this request.
         */
        public List<MediaType> getProduces() {
-               return 
opContext.flatMap(RestOperationContext::supportedAcceptTypes).orElse(emptyList());
+               return opContext.isPresent() ? 
opContext.get().getSupportedAcceptTypes() : emptyList();
        }
 
        /**
@@ -320,7 +320,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         * @return The set of media types registered in the parser group of 
this request.
         */
        public List<MediaType> getConsumes() {
-               return 
opContext.flatMap(RestOperationContext::supportedContentTypes).orElse(emptyList());
+               return opContext.isPresent() ? 
opContext.get().getSupportedContentTypes() : emptyList();
        }
 
        /**
@@ -334,7 +334,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         *      <br>Never <jk>null</jk>.
         */
        public ContextProperties getContextProperties() {
-               return 
opContext.flatMap(RestOperationContext::contextProperties).orElse(ContextProperties.DEFAULT);
+               return opContext.isPresent() ? 
opContext.get().getContextProperties() : ContextProperties.DEFAULT;
        }
 
        /**
@@ -360,8 +360,8 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                                if (i > 0)
                                        charset = h.substring(i+9).trim();
                        }
-                       if (charset == null)
-                               charset = 
opContext.flatMap(RestOperationContext::defaultCharset).orElse(null);
+                       if (charset == null && opContext.isPresent())
+                               charset = opContext.get().getDefaultCharset();
                        if (charset == null)
                                charset = "UTF-8";
                        if (! Charset.isSupported(charset))
@@ -610,7 +610,8 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                                        }
                                }
                        }
-                       
formData.addDefault(opContext.flatMap(RestOperationContext::defaultRequestFormData).orElse(new
 NameValuePair[0]));
+                       if (opContext.isPresent())
+                               
formData.addDefault(opContext.get().getDefaultRequestFormData());
                        return formData;
                } catch (Exception e) {
                        throw new InternalServerError(e);
@@ -925,7 +926,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         * @return The serializers associated with this request.
         */
        public SerializerGroup getSerializers() {
-               return 
opContext.flatMap(RestOperationContext::serializers).orElse(SerializerGroup.EMPTY);
+               return opContext.isPresent() ? opContext.get().getSerializers() 
: SerializerGroup.EMPTY;
        }
 
        /**
@@ -938,7 +939,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         * @return The parsers associated with this request.
         */
        public ParserGroup getParsers() {
-               return 
opContext.flatMap(RestOperationContext::parsers).orElse(ParserGroup.EMPTY);
+               return opContext.isPresent() ? opContext.get().getParsers() : 
ParserGroup.EMPTY;
        }
 
        /**
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
index 6e8a35f..ec39800 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
@@ -106,11 +106,11 @@ public final class RestResponse extends 
HttpServletResponseWrapper {
                String h = request.getHeader("accept-charset");
                String charset = null;
                if (h == null)
-                       charset = roc.defaultCharset;
+                       charset = roc.getDefaultCharset();
                else for (StringRange r : StringRanges.of(h).getRanges()) {
                        if (r.getQValue() > 0) {
                                if (r.getName().equals("*"))
-                                       charset = roc.defaultCharset;
+                                       charset = roc.getDefaultCharset();
                                else if (Charset.isSupported(r.getName()))
                                        charset = r.getName();
                                if (charset != null)
@@ -118,16 +118,16 @@ public final class RestResponse extends 
HttpServletResponseWrapper {
                        }
                }
 
-               for (Header e : request.getContext().defaultResponseHeaders)
+               for (Header e : 
request.getContext().getDefaultResponseHeaders())
                        setHeaderSafe(e.getName(), stringify(e.getValue()));
-               for (Header e : roc.defaultResponseHeaders)
+               for (Header e : roc.getDefaultResponseHeaders())
                        setHeaderSafe(e.getName(), stringify(e.getValue()));
 
                if (charset == null)
                        throw new NotAcceptable("No supported charsets in 
header ''Accept-Charset'': ''{0}''", request.getHeader("Accept-Charset"));
                super.setCharacterEncoding(charset);
 
-               this.responseMeta = roc.responseMeta;
+               this.responseMeta = roc.getResponseMeta();
        }
 
        /**
@@ -140,7 +140,7 @@ public final class RestResponse extends 
HttpServletResponseWrapper {
         * @return The serializer group for the response.
         */
        public SerializerGroup getSerializers() {
-               return opContext == null ? SerializerGroup.EMPTY : 
opContext.serializers;
+               return opContext == null ? SerializerGroup.EMPTY : 
opContext.getSerializers();
        }
 
        /**
@@ -149,7 +149,7 @@ public final class RestResponse extends 
HttpServletResponseWrapper {
         * @return The set of media types registered in the parser group of 
this request.
         */
        public List<MediaType> getSupportedMediaTypes() {
-               return opContext == null ? Collections.<MediaType>emptyList() : 
opContext.supportedAcceptTypes;
+               return opContext == null ? Collections.<MediaType>emptyList() : 
opContext.getSupportedAcceptTypes();
        }
 
        /**
@@ -159,7 +159,7 @@ public final class RestResponse extends 
HttpServletResponseWrapper {
         * @return The set of media types registered in the parser group of 
this request.
         */
        public List<String> getSupportedEncodings() {
-               return opContext == null ? Collections.<String>emptyList() : 
opContext.encoders.getSupportedEncodings();
+               return opContext == null ? Collections.<String>emptyList() : 
opContext.getEncoders().getSupportedEncodings();
        }
 
        /**
@@ -285,7 +285,7 @@ public final class RestResponse extends 
HttpServletResponseWrapper {
        public FinishableServletOutputStream getNegotiatedOutputStream() throws 
NotAcceptable, IOException {
                if (os == null) {
                        Encoder encoder = null;
-                       EncoderGroup encoders = opContext == null ? 
EncoderGroup.DEFAULT : opContext.encoders;
+                       EncoderGroup encoders = opContext == null ? 
EncoderGroup.DEFAULT : opContext.getEncoders();
 
                        String ae = request.getHeader("Accept-Encoding");
                        if (! (ae == null || ae.isEmpty())) {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
index 27c44bf..c3771a5 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
@@ -88,7 +88,7 @@ public abstract class RestServlet extends HttpServlet {
         */
        protected void setContext(RestContext context) throws ServletException {
                if (this.context.get() == null) {
-                       super.init(context.builder);
+                       super.init(context.getBuilder());
                        this.context.set(context);
                }
        }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RrpcRestOperationContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RrpcRestOperationContext.java
index c7431db..82cdf13 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RrpcRestOperationContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RrpcRestOperationContext.java
@@ -41,10 +41,10 @@ public class RrpcRestOperationContext extends 
RestOperationContext {
        public RrpcRestOperationContext(RestOperationContextBuilder builder) 
throws ServletException {
                super(builder);
 
-               ClassMeta<?> interfaceClass = 
getClassMeta(mi.inner().getGenericReturnType());
+               ClassMeta<?> interfaceClass = 
getClassMeta(getJavaMethod().getGenericReturnType());
                meta = new RrpcInterfaceMeta(interfaceClass.getInnerClass(), 
null);
                if (meta.getMethodsByPath().isEmpty())
-                       throw new InternalServerError("Method {0} returns an 
interface {1} that doesn't define any remote methods.", mi.getSignature(), 
interfaceClass.getFullName());
+                       throw new InternalServerError("Method {0} returns an 
interface {1} that doesn't define any remote methods.", 
getJavaMethod().getName(), interfaceClass.getFullName());
 
        }
 

Reply via email to