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 0a7b86f  Context API refactoring.
0a7b86f is described below

commit 0a7b86f8fa82bcc4daf6d430c82298f59692abf3
Author: JamesBognar <[email protected]>
AuthorDate: Sun Aug 29 14:27:06 2021 -0400

    Context API refactoring.
---
 .../apache/juneau/rest/ResponseProcessorList.java  | 102 +++++++++++--
 .../java/org/apache/juneau/rest/RestContext.java   | 159 ++-------------------
 .../org/apache/juneau/rest/RestContextBuilder.java | 118 ++++++++++++---
 .../java/org/apache/juneau/rest/RestGuardList.java |  23 +--
 .../org/apache/juneau/rest/RestMatcherList.java    |  39 ++---
 .../java/org/apache/juneau/rest/RestOpContext.java |  27 ++--
 .../java/org/apache/juneau/rest/RestResponse.java  |   2 +-
 .../org/apache/juneau/rest/annotation/Rest.java    |   2 +-
 .../juneau/rest/annotation/RestAnnotation.java     |   2 +-
 9 files changed, 231 insertions(+), 243 deletions(-)

diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ResponseProcessorList.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ResponseProcessorList.java
index 935b5c3..ea593fe 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ResponseProcessorList.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ResponseProcessorList.java
@@ -12,31 +12,115 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest;
 
+import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
+import org.apache.juneau.cp.*;
 
 /**
  * A list of {@link ResponseProcessor} objects.
  */
-public class ResponseProcessorList extends AList<ResponseProcessor> {
+public class ResponseProcessorList {
 
-       private static final long serialVersionUID = 1L;
+       private final ResponseProcessor[] entries;
 
        /**
         * Static creator.
         *
         * @return An empty list.
         */
-       @SuppressWarnings("unchecked")
-       public static ResponseProcessorList create() {
-               return new ResponseProcessorList();
+       public static Builder create() {
+               return new Builder();
        }
 
        /**
-        * Returns the contents of this list as a {@link ResponseProcessor} 
array.
+        * Constructor.
         *
-        * @return The contents of this list as a {@link ResponseProcessor} 
array.
+        * @param builder The builder containing the contents for this list.
         */
-       public ResponseProcessor[] asArray() {
-               return asArrayOf(ResponseProcessor.class);
+       protected ResponseProcessorList(Builder builder) {
+               entries =
+                       builder
+                               .entries
+                               .stream()
+                               .map(x -> instantiate(x, builder.beanStore))
+                               .toArray(ResponseProcessor[]::new);
+       }
+
+       /**
+        * Builder for {@link RestMatcherList} objects.
+        */
+       public static class Builder {
+
+               AList<Object> entries;
+               BeanStore beanStore;
+
+               /**
+                * Create an empty builder.
+                */
+               protected Builder() {
+                       this.entries = AList.create();
+               }
+
+               /**
+                * Creates a new {@link ResponseProcessorList} object using a 
snapshot of the settings defined in this builder.
+                *
+                * @return A new {@link ResponseProcessorList} object.
+                */
+               public ResponseProcessorList build() {
+                       return new ResponseProcessorList(this);
+               }
+
+               /**
+                * Appends the specified rest response processor classes to the 
list.
+                *
+                * @param values The values to add.
+                * @return This object (for method chaining).
+                */
+               @SuppressWarnings("unchecked")
+               public Builder append(Class<? extends 
ResponseProcessor>...values) {
+                       entries.append((Object[])values);
+                       return this;
+               }
+
+               /**
+                * Appends the specified rest response processor objects to the 
list.
+                *
+                * @param values The values to add.
+                * @return This object (for method chaining).
+                */
+               public Builder append(ResponseProcessor...values) {
+                       entries.append((Object[])values);
+                       return this;
+               }
+
+               /**
+                * Specifies the bean store to use for instantiating rest 
response processor classes.
+                *
+                * @param value The bean store to use for instantiating rest 
response processor classes.
+                * @return This object (for method chaining).
+                */
+               public Builder beanStore(BeanStore value) {
+                       beanStore = value;
+                       return this;
+               }
+       }
+
+       private static ResponseProcessor instantiate(Object o, BeanStore bs) {
+               if (o instanceof ResponseProcessor)
+                       return (ResponseProcessor)o;
+               try {
+                       return (ResponseProcessor)bs.createBean((Class<?>)o);
+               } catch (ExecutableException e) {
+                       throw new ConfigException(e, "Could not instantiate 
class {0}", o);
+               }
+       }
+
+       /**
+        * Returns the entries in this list.
+        *
+        * @return The entries in this list.
+        */
+       public ResponseProcessor[] toArray() {
+               return entries;
        }
 }
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 078e4ba..9410ce9 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
@@ -66,7 +66,6 @@ import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.args.*;
 import org.apache.juneau.rest.converters.*;
 import org.apache.juneau.rest.logging.*;
-import org.apache.juneau.rest.processors.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.rest.util.*;
@@ -1310,114 +1309,6 @@ public class RestContext extends BeanContext {
        public static final String REST_renderResponseStackTraces = PREFIX + 
".renderResponseStackTraces.b";
 
        /**
-        * Configuration property:  Response processors.
-        *
-        * <h5 class='section'>Property:</h5>
-        * <ul class='spaced-list'>
-        *      <li><b>ID:</b>  {@link 
org.apache.juneau.rest.RestContext#REST_responseProcessors 
REST_responseHandlers}
-        *      <li><b>Name:</b>  <js>"RestContext.responseProcessors.lo"</js>
-        *      <li><b>Data type:</b>  <c>List&lt;{@link 
org.apache.juneau.rest.ResponseProcessor}|Class&lt;{@link 
org.apache.juneau.rest.ResponseProcessor}&gt;&gt;</c>
-        *      <li><b>Default:</b>  empty list
-        *      <li><b>Session property:</b>  <jk>false</jk>
-        *      <li><b>Annotations:</b>
-        *              <ul>
-        *                      <li class='ja'>{@link 
org.apache.juneau.rest.annotation.Rest#responseProcessors()}
-        *              </ul>
-        *      <li><b>Methods:</b>
-        *              <ul>
-        *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestContextBuilder#responseProcessors(Class...)}
-        *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestContextBuilder#responseProcessors(ResponseProcessor...)}
-        *              </ul>
-        * </ul>
-        *
-        * <h5 class='section'>Description:</h5>
-        * <p>
-        * Specifies a list of {@link ResponseProcessor} classes that know how 
to convert POJOs returned by REST methods or
-        * set via {@link RestResponse#setOutput(Object)} into appropriate HTTP 
responses.
-        *
-        * <p>
-        * By default, the following response handlers are provided in the 
specified order:
-        * <ul>
-        *      <li class='jc'>{@link ReaderProcessor}
-        *      <li class='jc'>{@link InputStreamProcessor}
-        *      <li class='jc'>{@link ThrowableProcessor}
-        *      <li class='jc'>{@link HttpResponseProcessor}
-        *      <li class='jc'>{@link HttpResourceProcessor}
-        *      <li class='jc'>{@link HttpEntityProcessor}
-        *      <li class='jc'>{@link ResponseBeanProcessor}
-        *      <li class='jc'>{@link PlainTextPojoProcessor}
-        *      <li class='jc'>{@link SerializedPojoProcessor}
-        * </ul>
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Our custom response processor for Foo objects. </jc>
-        *      <jk>public class</jk> MyResponseProcessor <jk>implements</jk> 
ResponseProcessor {
-        *
-        *              <ja>@Override</ja>
-        *              <jk>public int</jk> process(RestCall <jv>call</jv>) 
<jk>throws</jk> IOException {
-        *
-        *                              RestResponse <jv>res</jv> = 
<jv>call</jv>.getRestResponse();
-        *                              Foo <jv>foo</jv> = 
<jv>res</jv>.getOutput(Foo.<jk>class</jk>);
-        *
-        *                              <jk>if</jk> (<jv>foo</jv> == 
<jk>null</jk>)
-        *                                      <jk>return</jk> 
<jsf>NEXT</jsf>;  <jc>// Let the next processor handle it.</jc>
-        *
-        *                              <jk>try</jk> (Writer <jv>w</jv> = 
<jv>res</jv>.getNegotiatedWriter()) {
-        *                                      <jc>//Pipe it to the writer 
ourselves.</jc>
-        *                              }
-        *
-        *                              <jk>return</jk> <jsf>FINISHED</jsf>;  
<jc>// We handled it.</jc>
-        *                      }
-        *              }
-        *      }
-        *
-        *      <jc>// Option #1 - Defined via annotation.</jc>
-        *      
<ja>@Rest</ja>(responseProcessors=MyResponseProcessor.<jk>class</jk>)
-        *      <jk>public class</jk> MyResource {
-        *
-        *              <jc>// Option #2 - Defined via builder passed in 
through resource constructor.</jc>
-        *              <jk>public</jk> MyResource(RestContextBuilder 
<jv>builder</jv>) <jk>throws</jk> Exception {
-        *
-        *                      <jc>// Using method on builder.</jc>
-        *                      
<jv>builder</jv>.responseProcessors(MyResponseProcessor.<jk>class</jk>);
-        *
-        *                      <jc>// Same, but using property.</jc>
-        *                      
<jv>builder</jv>.addTo(<jsf>REST_responseProcessors</jsf>, 
MyResponseProcessor.<jk>class</jk>);
-        *              }
-        *
-        *              <jc>// Option #3 - Defined via builder passed in 
through init method.</jc>
-        *              <ja>@RestHook</ja>(<jsf>INIT</jsf>)
-        *              <jk>public void</jk> init(RestContextBuilder 
<jv>builder</jv>) <jk>throws</jk> Exception {
-        *                      
<jv>builder</jv>.responseProcessors(MyResponseProcessors.<jk>class</jk>);
-        *              }
-        *
-        *              <ja>@RestGet</ja>(...)
-        *              <jk>public</jk> Object myMethod() {
-        *                      <jc>// Return a special object for our 
handler.</jc>
-        *                      <jk>return new</jk> MySpecialObject();
-        *              }
-        *      }
-        * </p>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              Response processors are always inherited from ascendant 
resources.
-        *      <li>
-        *              When defined as a class, the implementation must have 
one of the following constructors:
-        *              <ul>
-        *                      <li><code><jk>public</jk> T(RestContext)</code>
-        *                      <li><code><jk>public</jk> T()</code>
-        *                      <li><code><jk>public static</jk> T 
<jsm>create</jsm>(RestContext)</code>
-        *                      <li><code><jk>public static</jk> T 
<jsm>create</jsm>()</code>
-        *              </ul>
-        *      <li>
-        *              Inner classes of the REST resource class are allowed.
-        * </ul>
-        */
-       public static final String REST_responseProcessors = PREFIX + 
".responseProcessors.lo";
-
-       /**
         * Configuration property:  Java REST method parameter resolvers.
         *
         * <h5 class='section'>Property:</h5>
@@ -1789,7 +1680,7 @@ public class RestContext extends BeanContext {
        private final List<MediaType> consumes, produces;
        private final HeaderList defaultRequestHeaders, defaultResponseHeaders;
        private final NamedAttributeList defaultRequestAttributes;
-       private final List<ResponseProcessor> responseProcessors;
+       private final ResponseProcessor[] responseProcessors;
        private final Messages messages;
        private final Config config;
        private final VarResolver varResolver;
@@ -1914,7 +1805,7 @@ public class RestContext extends BeanContext {
                        config = builder.config.resolving(vr.createSession());
                        bf.addBean(Config.class, config);
 
-                       responseProcessors = 
unmodifiableList(createResponseProcessors(r, cp, bf));
+                       responseProcessors = createResponseProcessors(r, 
builder, bf).toArray();
 
                        callLogger = createCallLogger(r, cp, bf, l, ts);
                        bf.addBean(RestLogger.class, callLogger);
@@ -2555,7 +2446,7 @@ public class RestContext extends BeanContext {
         * <p>
         * Instantiates based on the following logic:
         * <ul>
-        *      <li>Looks for {@link #REST_responseProcessors} value set via 
any of the following:
+        *      <li>Looks for response processors set via any of the following:
         *              <ul>
         *                      <li>{@link 
RestContextBuilder#responseProcessors(Class...)}/{@link 
RestContextBuilder#responseProcessors(ResponseProcessor...)}
         *                      <li>{@link Rest#responseProcessors()}.
@@ -2571,39 +2462,29 @@ public class RestContext extends BeanContext {
         *      <li>Instantiates a <c>ResponseProcessor[0]</c>.
         * </ul>
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link #REST_responseProcessors}
-        * </ul>
-        *
         * @param resource
         *      The REST servlet or bean that this context defines.
-        * @param properties
-        *      The properties of this bean.
-        *      <br>Consists of all properties gathered through the builder and 
annotations on this class and all parent classes.
+        * @param builder
+        *      The builder for this object.
         * @param beanStore
         *      The factory used for creating beans and retrieving injected 
beans.
         *      <br>Created by {@link 
#createBeanStore(Object,ContextProperties,RestContext)}.
         * @return The response handlers for this REST resource.
         * @throws Exception If response handlers could not be instantiated.
         */
-       protected ResponseProcessorList createResponseProcessors(Object 
resource, ContextProperties properties, BeanStore beanStore) throws Exception {
-
-               ResponseProcessorList x = ResponseProcessorList.create();
-
-               x.append(properties.getInstanceArray(REST_responseProcessors, 
ResponseProcessor.class, beanStore).orElse(new ResponseProcessor[0]));
+       protected ResponseProcessorList createResponseProcessors(Object 
resource, RestContextBuilder builder, BeanStore beanStore) throws Exception {
 
-               if (x.isEmpty())
-                       
x.append(beanStore.getBean(ResponseProcessorList.class).orElse(null));
+               ResponseProcessorList.Builder x = 
builder.responseProcessors.beanStore(beanStore);
 
                x = BeanStore
                        .of(beanStore, resource)
-                       .addBean(ResponseProcessorList.class, x)
-                       .beanCreateMethodFinder(ResponseProcessorList.class, 
resource)
+                       .addBean(ResponseProcessorList.Builder.class, x)
+                       
.beanCreateMethodFinder(ResponseProcessorList.Builder.class, resource)
                        .find("createResponseProcessors")
                        .withDefault(x)
                        .run();
 
-               return x;
+               return x.build();
        }
 
        /**
@@ -4588,21 +4469,6 @@ public class RestContext extends BeanContext {
        }
 
        /**
-        * Returns the response processors associated with this resource.
-        *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link RestContext#REST_responseProcessors}
-        * </ul>
-        *
-        * @return
-        *      The response processors associated with this resource.
-        *      <br>Never <jk>null</jk>.
-        */
-       protected List<ResponseProcessor> getResponseProcessors() {
-               return responseProcessors;
-       }
-
-       /**
         * Returns the authority path of the resource.
         *
         * <ul class='seealso'>
@@ -5025,10 +4891,9 @@ public class RestContext extends BeanContext {
        public void processResponse(RestCall call) throws IOException, 
BasicHttpException, NotImplemented {
 
                // Loop until we find the correct processor for the POJO.
-               List<ResponseProcessor> l = getResponseProcessors();
                int loops = 5;
-               for (int i = 0; i < l.size(); i++) {
-                       int j = l.get(i).process(call);
+               for (int i = 0; i < responseProcessors.length; i++) {
+                       int j = responseProcessors[i].process(call);
                        if (j == FINISHED)
                                return;
                        if (j == RESTART) {
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 e1924ba..29c918e 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
@@ -132,6 +132,19 @@ public class RestContextBuilder extends BeanContextBuilder 
implements ServletCon
        Class<? extends SwaggerProvider> swaggerProviderClass;
        SwaggerProvider swaggerProvider;
 
+       @SuppressWarnings("unchecked")
+       ResponseProcessorList.Builder responseProcessors = 
ResponseProcessorList.create().append(
+               ReaderProcessor.class,
+               InputStreamProcessor.class,
+               ThrowableProcessor.class,
+               HttpResponseProcessor.class,
+               HttpResourceProcessor.class,
+               HttpEntityProcessor.class,
+               ResponseBeanProcessor.class,
+               PlainTextPojoProcessor.class,
+               SerializedPojoProcessor.class
+       );
+
        List<Object> children = new ArrayList<>();
 
        RestContextBuilder(Optional<RestContext> parentContext, 
Optional<ServletConfig> servletConfig, Class<?> resourceClass, Optional<Object> 
resource) throws ServletException {
@@ -148,17 +161,6 @@ public class RestContextBuilder extends BeanContextBuilder 
implements ServletCon
                        partSerializer(OpenApiSerializer.class);
                        partParser(OpenApiParser.class);
                        encoders(IdentityEncoder.INSTANCE);
-                       responseProcessors(
-                               ReaderProcessor.class,
-                               InputStreamProcessor.class,
-                               ThrowableProcessor.class,
-                               HttpResponseProcessor.class,
-                               HttpResourceProcessor.class,
-                               HttpEntityProcessor.class,
-                               ResponseBeanProcessor.class,
-                               PlainTextPojoProcessor.class,
-                               SerializedPojoProcessor.class
-                       );
 
                        // Pass-through default values.
                        if (parentContext.isPresent()) {
@@ -1887,40 +1889,112 @@ public class RestContextBuilder extends 
BeanContextBuilder implements ServletCon
        }
 
        /**
-        * <i><l>RestContext</l> configuration property:&emsp;</i>  Response 
processors.
+        * Response processors.
         *
         * <p>
         * Specifies a list of {@link ResponseProcessor} classes that know how 
to convert POJOs returned by REST methods or
         * set via {@link RestResponse#setOutput(Object)} into appropriate HTTP 
responses.
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link RestContext#REST_responseProcessors}
+        * <p>
+        * By default, the following response handlers are provided in the 
specified order:
+        * <ul>
+        *      <li class='jc'>{@link ReaderProcessor}
+        *      <li class='jc'>{@link InputStreamProcessor}
+        *      <li class='jc'>{@link ThrowableProcessor}
+        *      <li class='jc'>{@link HttpResponseProcessor}
+        *      <li class='jc'>{@link HttpResourceProcessor}
+        *      <li class='jc'>{@link HttpEntityProcessor}
+        *      <li class='jc'>{@link ResponseBeanProcessor}
+        *      <li class='jc'>{@link PlainTextPojoProcessor}
+        *      <li class='jc'>{@link SerializedPojoProcessor}
+        * </ul>
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bcode w800'>
+        *      <jc>// Our custom response processor for Foo objects. </jc>
+        *      <jk>public class</jk> MyResponseProcessor <jk>implements</jk> 
ResponseProcessor {
+        *
+        *              <ja>@Override</ja>
+        *              <jk>public int</jk> process(RestCall <jv>call</jv>) 
<jk>throws</jk> IOException {
+        *
+        *                              RestResponse <jv>res</jv> = 
<jv>call</jv>.getRestResponse();
+        *                              Foo <jv>foo</jv> = 
<jv>res</jv>.getOutput(Foo.<jk>class</jk>);
+        *
+        *                              <jk>if</jk> (<jv>foo</jv> == 
<jk>null</jk>)
+        *                                      <jk>return</jk> 
<jsf>NEXT</jsf>;  <jc>// Let the next processor handle it.</jc>
+        *
+        *                              <jk>try</jk> (Writer <jv>w</jv> = 
<jv>res</jv>.getNegotiatedWriter()) {
+        *                                      <jc>//Pipe it to the writer 
ourselves.</jc>
+        *                              }
+        *
+        *                              <jk>return</jk> <jsf>FINISHED</jsf>;  
<jc>// We handled it.</jc>
+        *                      }
+        *              }
+        *      }
+        *
+        *      <jc>// Option #1 - Defined via annotation.</jc>
+        *      
<ja>@Rest</ja>(responseProcessors=MyResponseProcessor.<jk>class</jk>)
+        *      <jk>public class</jk> MyResource {
+        *
+        *              <jc>// Option #2 - Defined via builder passed in 
through resource constructor.</jc>
+        *              <jk>public</jk> MyResource(RestContextBuilder 
<jv>builder</jv>) <jk>throws</jk> Exception {
+        *
+        *                      <jc>// Using method on builder.</jc>
+        *                      
<jv>builder</jv>.responseProcessors(MyResponseProcessor.<jk>class</jk>);
+        *              }
+        *
+        *              <jc>// Option #3 - Defined via builder passed in 
through init method.</jc>
+        *              <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+        *              <jk>public void</jk> init(RestContextBuilder 
<jv>builder</jv>) <jk>throws</jk> Exception {
+        *                      
<jv>builder</jv>.responseProcessors(MyResponseProcessors.<jk>class</jk>);
+        *              }
+        *
+        *              <ja>@RestGet</ja>(...)
+        *              <jk>public</jk> Object myMethod() {
+        *                      <jc>// Return a special object for our 
handler.</jc>
+        *                      <jk>return new</jk> MySpecialObject();
+        *              }
+        *      }
+        * </p>
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              Response processors are always inherited from ascendant 
resources.
+        *      <li>
+        *              When defined as a class, the implementation must have 
one of the following constructors:
+        *              <ul>
+        *                      <li><code><jk>public</jk> T(RestContext)</code>
+        *                      <li><code><jk>public</jk> T()</code>
+        *                      <li><code><jk>public static</jk> T 
<jsm>create</jsm>(RestContext)</code>
+        *                      <li><code><jk>public static</jk> T 
<jsm>create</jsm>()</code>
+        *              </ul>
+        *      <li>
+        *              Inner classes of the REST resource class are allowed.
         * </ul>
         *
         * @param values The values to add to this setting.
         * @return This object (for method chaining).
         */
+       @SuppressWarnings("unchecked")
        @FluentSetter
-       public RestContextBuilder responseProcessors(Class<?>...values) {
-               return prependTo(REST_responseProcessors, values);
+       public RestContextBuilder responseProcessors(Class<? extends 
ResponseProcessor>...values) {
+               responseProcessors.append(values);
+               return this;
        }
 
        /**
-        * <i><l>RestContext</l> configuration property:&emsp;</i>  Response 
processors.
+        * Response processors.
         *
         * <p>
         * Same as {@link #responseProcessors(Class...)} except input is 
pre-constructed instances.
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link RestContext#REST_responseProcessors}
-        * </ul>
-        *
         * @param values The values to add to this setting.
         * @return This object (for method chaining).
         */
        @FluentSetter
        public RestContextBuilder 
responseProcessors(ResponseProcessor...values) {
-               return prependTo(REST_responseProcessors, values);
+               responseProcessors.append(values);
+               return this;
        }
 
        /**
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuardList.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuardList.java
index 6a65370..93ab699 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuardList.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuardList.java
@@ -12,11 +12,6 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest;
 
-import static java.util.Collections.*;
-import static java.util.stream.Collectors.*;
-
-import java.util.*;
-
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.cp.*;
@@ -26,7 +21,7 @@ import org.apache.juneau.cp.*;
  */
 public class RestGuardList {
 
-       private final List<RestGuard> entries;
+       private RestGuard[] entries;
 
        /**
         * Static creator.
@@ -43,13 +38,12 @@ public class RestGuardList {
         * @param builder The builder containing the contents for this list.
         */
        protected RestGuardList(Builder builder) {
-               entries = unmodifiableList(
+               entries =
                        builder
                                .entries
                                .stream()
                                .map(x -> instantiate(x, builder.beanStore))
-                               .collect(toList())
-               );
+                               .toArray(RestGuard[]::new);
        }
 
        /**
@@ -89,7 +83,7 @@ public class RestGuardList {
                }
 
                /**
-                * Appends the specified rest matcher classes to the list.
+                * Appends the specified rest matcher objects to the list.
                 *
                 * @param values The values to add.
                 * @return This object (for method chaining).
@@ -127,15 +121,6 @@ public class RestGuardList {
         * @return The entries in this list.
         */
        public RestGuard[] asArray() {
-               return entries.toArray(new RestGuard[entries.size()]);
-       }
-
-       /**
-        * Returns the entries in this list.
-        *
-        * @return An unmodifiable list of entries in this list.
-        */
-       public List<RestGuard> getEntries() {
                return entries;
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherList.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherList.java
index b0f9b35..62caf26 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherList.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherList.java
@@ -13,7 +13,6 @@
 package org.apache.juneau.rest;
 
 import static java.util.stream.Collectors.*;
-import static java.util.Collections.*;
 
 import java.util.*;
 
@@ -26,9 +25,8 @@ import org.apache.juneau.cp.*;
  */
 public class RestMatcherList {
 
-       private final List<RestMatcher> entries;
-       private final List<RestMatcher> optionalEntries;
-       private final List<RestMatcher> requiredEntries;
+       private final RestMatcher[] optionalEntries;
+       private final RestMatcher[] requiredEntries;
 
        /**
         * Static creator.
@@ -45,15 +43,14 @@ public class RestMatcherList {
         * @param builder The builder containing the contents for this list.
         */
        protected RestMatcherList(Builder builder) {
-               entries = unmodifiableList(
+               List<RestMatcher> l =
                        builder
                                .entries
                                .stream()
                                .map(x -> instantiate(x, builder.beanStore))
-                               .collect(toList())
-               );
-               optionalEntries = unmodifiableList(entries.stream().filter(x -> 
! x.required()).collect(toList()));
-               requiredEntries = unmodifiableList(entries.stream().filter(x -> 
x.required()).collect(toList()));
+                               .collect(toList());
+               optionalEntries = l.stream().filter(x -> ! 
x.required()).toArray(RestMatcher[]::new);
+               requiredEntries = l.stream().filter(x -> 
x.required()).toArray(RestMatcher[]::new);
        }
 
        /**
@@ -93,7 +90,7 @@ public class RestMatcherList {
                }
 
                /**
-                * Appends the specified rest matcher classes to the list.
+                * Appends the specified rest matcher objects to the list.
                 *
                 * @param values The values to add.
                 * @return This object (for method chaining).
@@ -126,20 +123,11 @@ public class RestMatcherList {
        }
 
        /**
-        * Returns the entries in this list.
-        *
-        * @return An unmodifiable list of entries in this list.
-        */
-       public List<RestMatcher> getEntries() {
-               return entries;
-       }
-
-       /**
         * Returns the entries in this list that are specified as optional.
         *
         * @return An unmodifiable list of entries in this list that are 
specified as optional.
         */
-       public List<RestMatcher> getOptionalEntries() {
+       public RestMatcher[] getOptionalEntries() {
                return optionalEntries;
        }
 
@@ -148,16 +136,7 @@ public class RestMatcherList {
         *
         * @return An unmodifiable list of entries in this list that are 
specified as required.
         */
-       public List<RestMatcher> getRequiredEntries() {
+       public RestMatcher[] getRequiredEntries() {
                return requiredEntries;
        }
-
-       /**
-        * Returns <jk>true</jk> if this list is empty.
-        *
-        * @return <jk>true</jk> if this list is empty.
-        */
-       public boolean isEmpty() {
-               return entries.isEmpty();
-       }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
index 864cc33..11f46a0 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
@@ -78,8 +78,8 @@ public class RestOpContext extends BeanContext implements 
Comparable<RestOpConte
        private final String httpMethod;
        private final UrlPathMatcher[] pathMatchers;
        private final RestOpArg[] opArgs;
-       private final RestGuardList guards;
-       private final RestMatcherList matchers;
+       private final RestGuard[] guards;
+       private final RestMatcher[] requiredMatchers, optionalMatchers;
        private final RestConverter[] converters;
        private final RestContext context;
        private final Method method;
@@ -164,10 +164,11 @@ public class RestOpContext extends BeanContext implements 
Comparable<RestOpConte
                        converters = createConverters(r, cp, bs).asArray();
                        bs.addBean(RestConverter[].class, converters);
 
-                       guards = createGuards(r, builder, bs);
-                       bs.addBean(RestGuardList.class, guards);
+                       guards = createGuards(r, builder, bs).asArray();
 
-                       matchers = createMatchers(r, builder, bs);
+                       RestMatcherList matchers = createMatchers(r, builder, 
bs);
+                       optionalMatchers = matchers.getOptionalEntries();
+                       requiredMatchers = matchers.getRequiredEntries();
 
                        pathMatchers = createPathMatchers(r, cp, builder, 
bs).asArray();
                        bs.addBean(UrlPathMatcher[].class, pathMatchers);
@@ -1214,7 +1215,7 @@ public class RestOpContext extends BeanContext implements 
Comparable<RestOpConte
                if (pm == null)
                        return 0;
 
-               if (matchers.isEmpty()) {
+               if (requiredMatchers.length == 0 && optionalMatchers.length == 
0) {
                        call.urlPathMatch(pm);  // Cache so we don't have to 
recalculate.
                        return 2;
                }
@@ -1223,12 +1224,12 @@ public class RestOpContext extends BeanContext 
implements Comparable<RestOpConte
                        HttpServletRequest req = call.getRequest();
 
                        // If the method implements matchers, test them.
-                       for (RestMatcher m :  matchers.getRequiredEntries())
+                       for (RestMatcher m :  requiredMatchers)
                                if (! m.matches(req))
                                        return 1;
-                       if (! matchers.getOptionalEntries().isEmpty()) {
+                       if (optionalMatchers.length > 0) {
                                boolean matches = false;
-                               for (RestMatcher m : 
matchers.getOptionalEntries())
+                               for (RestMatcher m : optionalMatchers)
                                        matches |= m.matches(req);
                                if (! matches)
                                        return 1;
@@ -1272,7 +1273,7 @@ public class RestOpContext extends BeanContext implements 
Comparable<RestOpConte
 
                try {
 
-                       for (RestGuard guard : guards.getEntries())
+                       for (RestGuard guard : guards)
                                if (! guard.guard(req, res))
                                        return;
 
@@ -1345,15 +1346,15 @@ public class RestOpContext extends BeanContext 
implements Comparable<RestOpConte
                if (c != 0)
                        return c;
 
-               c = compare(o.matchers.getRequiredEntries().size(), 
matchers.getRequiredEntries().size());
+               c = compare(o.requiredMatchers.length, requiredMatchers.length);
                if (c != 0)
                        return c;
 
-               c = compare(o.matchers.getOptionalEntries().size(), 
matchers.getOptionalEntries().size());
+               c = compare(o.optionalMatchers.length, optionalMatchers.length);
                if (c != 0)
                        return c;
 
-               c = compare(o.guards.getEntries().size(), 
guards.getEntries().size());
+               c = compare(o.guards.length, guards.length);
 
                if (c != 0)
                        return c;
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 0ccf83e..c391e88 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
@@ -171,7 +171,7 @@ public final class RestResponse {
         * </ul>
         *
         * <ul class='seealso'>
-        *      <li class='jf'>{@link RestContext#REST_responseProcessors}
+        *      <li class='jm'>{@link 
RestContextBuilder#responseProcessors(Class...)}
         *      <li class='link'>{@doc RestmReturnTypes}
         * </ul>
         *
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
index 4ee871e..9de435a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
@@ -928,7 +928,7 @@ public @interface Rest {
         * set via {@link RestResponse#setOutput(Object)} into appropriate HTTP 
responses.
         *
         * <ul class='seealso'>
-        *      <li class='jf'>{@link RestContext#REST_responseProcessors}
+        *      <li class='jm'>{@link 
RestContextBuilder#responseProcessors(Class...)}
         * </ul>
         */
        Class<? extends ResponseProcessor>[] responseProcessors() default {};
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
index 435d647..559649e 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
@@ -1050,7 +1050,7 @@ public class RestAnnotation {
                        stringStream(a.defaultResponseHeaders()).map(x -> 
stringHeader(x)).forEach(x -> b.appendTo(REST_defaultResponseHeaders, x));
                        b.appendToIfNotEmpty(REST_defaultRequestHeaders, 
accept(string(a.defaultAccept())));
                        b.appendToIfNotEmpty(REST_defaultRequestHeaders, 
contentType(string(a.defaultContentType())));
-                       b.prependTo(REST_responseProcessors, 
a.responseProcessors());
+                       b.responseProcessors(a.responseProcessors());
                        b.children((Object[])a.children());
                        b.prependTo(REST_restOperationArgs, a.restOpArgs());
                        value(a.contextClass()).ifPresent(x -> 
b.contextClass(x));

Reply via email to