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 f4afbf8  REST refactoring.
f4afbf8 is described below

commit f4afbf88cc514ca719371cef6883bee9ba13c877
Author: JamesBognar <[email protected]>
AuthorDate: Thu Jan 21 18:37:30 2021 -0500

    REST refactoring.
---
 .../rest/annotation/RestMethodAnnotation_Test.java |  5 ++
 .../juneau/rest/annotation/Rest_Context_Test.java  |  2 +-
 .../java/org/apache/juneau/rest/RestContext.java   | 12 +++--
 .../org/apache/juneau/rest/RestContextBuilder.java |  7 ++-
 .../org/apache/juneau/rest/RestMethodContext.java  | 58 ++++++++++++++++++----
 .../juneau/rest/RestMethodContextBuilder.java      | 49 ++++++++++++++----
 .../apache/juneau/rest/RrpcRestMethodContext.java  |  6 +--
 .../apache/juneau/rest/annotation/RestMethod.java  | 15 ++++++
 .../rest/annotation/RestMethodAnnotation.java      | 20 ++++++++
 9 files changed, 141 insertions(+), 33 deletions(-)

diff --git 
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
 
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
index 5ecf817..3e46c26 100644
--- 
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
+++ 
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
@@ -36,6 +36,7 @@ public class RestMethodAnnotation_Test {
        RestMethod a1 = RestMethodAnnotation.create()
                .clientVersion("clientVersion")
                .consumes("consumes")
+               .context(RestMethodContext.class)
                .converters(RestConverter.class)
                .debug("debug")
                .defaultAccept("defaultAccept")
@@ -68,6 +69,7 @@ public class RestMethodAnnotation_Test {
        RestMethod a2 = RestMethodAnnotation.create()
                .clientVersion("clientVersion")
                .consumes("consumes")
+               .context(RestMethodContext.class)
                .converters(RestConverter.class)
                .debug("debug")
                .defaultAccept("defaultAccept")
@@ -103,6 +105,7 @@ public class RestMethodAnnotation_Test {
                        + "{"
                                + "clientVersion:'clientVersion',"
                                + "consumes:['consumes'],"
+                               + 
"context:'org.apache.juneau.rest.RestMethodContext',"
                                + 
"converters:['org.apache.juneau.rest.RestConverter'],"
                                + "debug:'debug',"
                                + "defaultAccept:'defaultAccept',"
@@ -178,6 +181,7 @@ public class RestMethodAnnotation_Test {
        @RestMethod(
                clientVersion="clientVersion",
                consumes="consumes",
+               context=RestMethodContext.class,
                converters=RestConverter.class,
                debug="debug",
                defaultAccept="defaultAccept",
@@ -212,6 +216,7 @@ public class RestMethodAnnotation_Test {
        @RestMethod(
                clientVersion="clientVersion",
                consumes="consumes",
+               context=RestMethodContext.class,
                converters=RestConverter.class,
                debug="debug",
                defaultAccept="defaultAccept",
diff --git 
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
 
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
index e09b6ce..cba61b1 100644
--- 
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
+++ 
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
@@ -91,7 +91,7 @@ public class Rest_Context_Test {
 
        @Test
        public void a05_invalidConstructor() throws Exception {
-               assertThrown(()->client(A5.class)).contains("Invalid class 
specified for REST_context");
+               assertThrown(()->client(A5.class)).contains("Could not create 
instance");
        }
 
        
//------------------------------------------------------------------------------------------------------------------
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 4863d25..5c3212a 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
@@ -4575,7 +4575,7 @@ public class RestContext extends BeanContext {
                                        if (mi.isNotPublic())
                                                throw new 
RestServletException("@RestMethod method {0}.{1} must be defined as public.", 
rci.inner().getName(), mi.getSimpleName());
 
-                                       RestMethodContextBuilder rmcb = new 
RestMethodContextBuilder(resource, mi.inner(), this);
+                                       RestMethodContextBuilder rmcb = new 
RestMethodContextBuilder(mi.inner(), this);
                                        RestMethodContext rmc = rmcb.build();
                                        String httpMethod = rmc.getHttpMethod();
 
@@ -4584,11 +4584,13 @@ public class RestContext extends BeanContext {
                                        // We override the CallMethod.invoke() 
method to insert our logic.
                                        if ("RRPC".equals(httpMethod)) {
 
-                                               RestMethodContextBuilder smb = 
new RestMethodContextBuilder(resource, mi.inner(), this);
-                                               smb.dotAll();
+                                               RestMethodContext smb = new 
RestMethodContextBuilder(mi.inner(), this)
+                                                       .dotAll()
+                                                       
.context(RrpcRestMethodContext.class)
+                                                       .build();
                                                x
-                                                       .add("GET", 
smb.build(RrpcRestMethodContext.class))
-                                                       .add("POST", 
smb.build(RrpcRestMethodContext.class));
+                                                       .add("GET", smb)
+                                                       .add("POST", smb);
 
                                        } else {
                                                x.add(rmc);
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 9079e9d..5b60ff0 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
@@ -185,10 +185,9 @@ public class RestContextBuilder extends BeanContextBuilder 
implements ServletCon
                try {
                        PropertyStore ps = getPropertyStore();
                        Class<? extends RestContext> c = 
ps.getClassProperty(REST_context, RestContext.class, RestContext.class);
-                       ConstructorInfo ci = 
ClassInfo.of(c).getConstructor(Visibility.PUBLIC, RestContextBuilder.class);
-                       if (ci == null)
-                               throw new InternalServerError("Invalid class 
specified for REST_context.  Must extend from RestContext and provide a public 
constructor of the form T(RestContextBuilder).");
-                       return ci.invoke(this);
+                       BeanFactory bf = new BeanFactory(beanFactory, resource);
+                       bf.addBean(RestContextBuilder.class, this);
+                       return bf.createBean(c);
                } catch (Exception e) {
                        throw toHttpException(e, InternalServerError.class);
                }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
index 0a68e4d..1f1d218 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
@@ -65,6 +65,14 @@ import org.apache.juneau.utils.*;
 @ConfigurableContext(nocache=true)
 public class RestMethodContext extends BeanContext implements 
Comparable<RestMethodContext>  {
 
+       /** Represents a null value for the {@link RestMethod#context()} 
annotation.*/
+       @SuppressWarnings("javadoc")
+       public static final class Null extends RestMethodContext {
+               public Null(RestMethodContextBuilder builder) throws Exception {
+                       super(builder);
+               }
+       }
+
        
//-------------------------------------------------------------------------------------------------------------------
        // Configurable properties
        
//-------------------------------------------------------------------------------------------------------------------
@@ -157,6 +165,37 @@ public class RestMethodContext extends BeanContext 
implements Comparable<RestMet
        public static final String RESTMETHOD_clientVersion = PREFIX + 
".clientVersion.s";
 
        /**
+        * Configuration property:  REST method context class.
+        *
+        * <ul class='spaced-list'>
+        *      <li><b>ID:</b>  {@link 
org.apache.juneau.rest.RestMethodContext#RESTMETHOD_context RESTMETHOD_context}
+        *      <li><b>Name:</b>  <js>"RestMethodContext.context.c"</js>
+        *      <li><b>Data type:</b>  <c>Class&lt;? extends {@link 
org.apache.juneau.rest.RestMethodContext}&gt;</c>
+        *      <li><b>Default:</b>  {@link 
org.apache.juneau.rest.RestMethodContext}
+        *      <li><b>Session property:</b>  <jk>false</jk>
+        *      <li><b>Annotations:</b>
+        *              <ul>
+        *                      <li class='ja'>{@link 
org.apache.juneau.rest.annotation.RestMethod#context()}
+        *              </ul>
+        *      <li><b>Methods:</b>
+        *              <ul>
+        *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestMethodContextBuilder#context(Class)}
+        *              </ul>
+        * </ul>
+        *
+        * <h5 class='section'>Description:</h5>
+        * <p>
+        * Allows you to extend the {@link RestMethodContext} class to modify 
how any of the functions are implemented.
+        *
+        * <p>
+        * The subclass must provide the following:
+        * <ul>
+        *      <li>A public constructor that takes in one parameter that 
should be passed to the super constructor:  {@link RestMethodContextBuilder}.
+        * </ul>
+        */
+       public static final String RESTMETHOD_context = PREFIX + ".context.c";
+
+       /**
         * Configuration property:  Debug mode.
         *
         * <h5 class='section'>Property:</h5>
@@ -638,16 +677,17 @@ public class RestMethodContext extends BeanContext 
implements Comparable<RestMet
        /**
         * Context constructor.
         *
-        * @param ps The property store with settings.
+        * @param builder The builder for this object.
         * @throws ServletException If context could not be created.
         */
-       public RestMethodContext(PropertyStore ps) throws ServletException {
-               super(ps);
+       public RestMethodContext(RestMethodContextBuilder builder) throws 
ServletException {
+               super(builder.getPropertyStore());
 
                try {
-                       context = 
getInstanceProperty("RestMethodContext.restContext.o", RestContext.class);
-                       method = 
getInstanceProperty("RestMethodContext.restMethod.o", Method.class);
-                       boolean dotAll = 
getBooleanProperty("RestMethodContext.dotAll.b", false);
+                       context = builder.restContext;
+                       method = builder.restMethod;
+
+                       PropertyStore ps = getPropertyStore();
 
                        methodInvoker = new MethodInvoker(method, 
context.getMethodExecStats(method));
                        mi = MethodInfo.of(method).accessible();
@@ -681,7 +721,7 @@ public class RestMethodContext extends BeanContext 
implements Comparable<RestMet
                        requiredMatchers = matchers.stream().filter(x -> 
x.required()).toArray(RestMatcher[]::new);
                        optionalMatchers = matchers.stream().filter(x -> ! 
x.required()).toArray(RestMatcher[]::new);
 
-                       pathMatchers = createPathMatchers(r, beanFactory, 
dotAll).asArray();
+                       pathMatchers = createPathMatchers(r, 
beanFactory).asArray();
                        beanFactory.addBean(UrlPathMatcher[].class, 
pathMatchers);
                        beanFactory.addBean(UrlPathMatcher.class, 
pathMatchers.length > 0 ? pathMatchers[0] : null);
 
@@ -1223,14 +1263,14 @@ public class RestMethodContext extends BeanContext 
implements Comparable<RestMet
         *
         * @param resource The REST resource object.
         * @param beanFactory The bean factory to use for retrieving and 
creating beans.
-        * @param dotAll If {@link RestMethodContextBuilder#dotAll()} was 
specified.
         * @return The HTTP part parser for this REST resource.
         * @throws Exception If parser could not be instantiated.
         * @seealso #RESTMETHOD_paths
         */
-       protected UrlPathMatcherList createPathMatchers(Object resource, 
BeanFactory beanFactory, boolean dotAll) throws Exception {
+       protected UrlPathMatcherList createPathMatchers(Object resource, 
BeanFactory beanFactory) throws Exception {
 
                UrlPathMatcherList x = UrlPathMatcherList.create();
+               boolean dotAll = 
getBooleanProperty("RestMethodContext.dotAll.b", false);
 
                for (String p : getArrayProperty(RESTMETHOD_path, 
String.class)) {
                        if (dotAll && ! p.endsWith("/*"))
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
index bd3dbda..02824cd 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
@@ -13,17 +13,18 @@
 package org.apache.juneau.rest;
 
 import static java.util.Arrays.*;
+import static org.apache.juneau.rest.HttpRuntimeException.*;
 import static org.apache.juneau.rest.RestMethodContext.*;
 
 import java.lang.annotation.*;
 import java.util.*;
 import java.util.function.*;
 
-import javax.servlet.*;
-
 import org.apache.http.*;
 import org.apache.juneau.*;
+import org.apache.juneau.cp.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.http.exception.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.rest.annotation.*;
@@ -35,22 +36,29 @@ import java.lang.reflect.Method;
  */
 public class RestMethodContextBuilder extends BeanContextBuilder {
 
-       @Override
+       RestContext restContext;
+       Method restMethod;
+
+       @Override /* BeanContextBuilder */
        public RestMethodContext build() {
                try {
-                       return new RestMethodContext(getPropertyStore());
-               } catch (ServletException e) {
-                       throw new RuntimeException(e);
+                       PropertyStore ps = getPropertyStore();
+                       Class<? extends RestMethodContext> c = 
ps.getClassProperty(RESTMETHOD_context, RestMethodContext.class, 
RestMethodContext.class);
+                       BeanFactory bf = new 
BeanFactory(restContext.rootBeanFactory, restContext.getResource());
+                       bf.addBean(RestMethodContextBuilder.class, this);
+                       return bf.createBean(c);
+               } catch (Exception e) {
+                       throw toHttpException(e, InternalServerError.class);
                }
        }
 
-       RestMethodContextBuilder(Object servlet, java.lang.reflect.Method 
method, RestContext context) throws RestServletException {
-               set("RestMethodContext.restContext.o", context);
-               set("RestMethodContext.restMethod.o", method);
-               set("RestMethodContext.restObject.o", context.getResource());  
// Added to force a new cache hash.
+       RestMethodContextBuilder(java.lang.reflect.Method method, RestContext 
context) throws RestServletException {
+
+               this.restContext = context;
+               this.restMethod = method;
 
                String sig = method.getDeclaringClass().getName() + '.' + 
method.getName();
-               MethodInfo mi = MethodInfo.of(servlet.getClass(), method);
+               MethodInfo mi = MethodInfo.of(context.getResource().getClass(), 
method);
 
                try {
 
@@ -113,6 +121,25 @@ public class RestMethodContextBuilder extends 
BeanContextBuilder {
        }
 
        /**
+        * <i><l>RestMethodContext</l> configuration property:&emsp;</i>  REST 
method context class.
+        *
+        * Allows you to extend the {@link RestMethodContext} class to modify 
how any of the methods are implemented.
+        *
+        * <p>
+        * The subclass must provide the following:
+        * <ul>
+        *      <li>A public constructor that takes in one parameter that 
should be passed to the super constructor:  {@link RestMethodContextBuilder}.
+        * </ul>
+        *
+        * @param value The new value for this setting.
+        * @return This object (for method chaining).
+        */
+       @FluentSetter
+       public RestMethodContextBuilder context(Class<? extends 
RestMethodContext> value) {
+               return set(RESTMETHOD_context, value);
+       }
+
+       /**
         * <i><l>RestMethodContext</l> configuration property:&emsp;</i>  Debug 
mode.
         *
         * <p>
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RrpcRestMethodContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RrpcRestMethodContext.java
index accaafe..8d0c591 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RrpcRestMethodContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RrpcRestMethodContext.java
@@ -35,11 +35,11 @@ public class RrpcRestMethodContext extends 
RestMethodContext {
        /**
         * Constructor.
         *
-        * @param ps The property store containing the settings for this 
context.
+        * @param builder The builder for this method context.
         * @throws ServletException Problem with metadata was detected.
         */
-       public RrpcRestMethodContext(PropertyStore ps) throws ServletException {
-               super(ps);
+       public RrpcRestMethodContext(RestMethodContextBuilder builder) throws 
ServletException {
+               super(builder);
 
                ClassMeta<?> interfaceClass = 
getClassMeta(mi.inner().getGenericReturnType());
                meta = new RrpcInterfaceMeta(interfaceClass.getInnerClass(), 
null);
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index b88cccb..7f0ed4a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -117,6 +117,21 @@ public @interface RestMethod {
        String[] consumes() default {};
 
        /**
+        * Allows you to extend the {@link RestContext} class to modify how any 
of the methods are implemented.
+        *
+        * <p>
+        * The subclass must provide the following:
+        * <ul>
+        *      <li>A public constructor that takes in one parameter that 
should be passed to the super constructor:  {@link RestMethodContextBuilder}.
+        * </ul>
+        *
+        * <ul class='seealso'>
+        *      <li class='jm'>{@link RestMethodContextBuilder#context(Class)}
+        * </ul>
+        */
+       Class<? extends RestMethodContext> context() default 
RestMethodContext.Null.class;
+
+       /**
         * Class-level response converters.
         *
         * <p>
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
index e7f899f..db221bf 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
@@ -61,6 +61,7 @@ public class RestMethodAnnotation {
                Class<? extends RestConverter>[] converters = new Class[0];
                Class<? extends RestGuard>[] guards = new Class[0];
                Class<? extends RestMatcher>[] matchers = new Class[0];
+               Class<? extends RestMethodContext> context = 
RestMethodContext.Null.class;
                Class<?>[] encoders=new Class<?>[0], parsers=new Class<?>[0], 
serializers=new Class<?>[0];
                int priority = 0;
                MethodSwagger swagger = MethodSwaggerAnnotation.DEFAULT;
@@ -106,6 +107,17 @@ public class RestMethodAnnotation {
                }
 
                /**
+                * Sets the {@link RestMethod#context()} property on this 
annotation.
+                *
+                * @param value The new value for this property.
+                * @return This object (for method chaining).
+                */
+               public Builder context(Class<? extends RestMethodContext> 
value) {
+                       this.context = value;
+                       return this;
+               }
+
+               /**
                 * Sets the {@link RestMethod#converters()} property on this 
annotation.
                 *
                 * @param value The new value for this property.
@@ -413,6 +425,7 @@ public class RestMethodAnnotation {
                private final Class<? extends RestConverter>[] converters;
                private final Class<? extends RestGuard>[] guards;
                private final Class<? extends RestMatcher>[] matchers;
+               private final Class<? extends RestMethodContext> context;
                private final Class<?>[] encoders, parsers, serializers;
                private final int priority;
                private final MethodSwagger swagger;
@@ -423,6 +436,7 @@ public class RestMethodAnnotation {
                        super(b);
                        this.clientVersion = b.clientVersion;
                        this.consumes = copyOf(b.consumes);
+                       this.context = b.context;
                        this.converters = copyOf(b.converters);
                        this.debug = b.debug;
                        this.defaultAccept = b.defaultAccept;
@@ -463,6 +477,11 @@ public class RestMethodAnnotation {
                }
 
                @Override /* RestMethod */
+               public Class<? extends RestMethodContext> context() {
+                       return context;
+               }
+
+               @Override /* RestMethod */
                public Class<? extends RestConverter>[] converters() {
                        return converters;
                }
@@ -615,6 +634,7 @@ public class RestMethodAnnotation {
                        psb.set(REST_serializers, 
merge(ConverterUtils.toType(psb.peek(REST_serializers), Object[].class), 
a.serializers()));
                        psb.set(REST_parsers, 
merge(ConverterUtils.toType(psb.peek(REST_parsers), Object[].class), 
a.parsers()));
                        psb.set(REST_encoders, 
merge(ConverterUtils.toType(psb.peek(REST_encoders), Object[].class), 
a.encoders()));
+                       psb.setIf(a.context() != RestMethodContext.Null.class, 
RESTMETHOD_context, a.context());
                        psb.setIfNotEmpty(REST_produces, 
stringList(a.produces()));
                        psb.setIfNotEmpty(REST_consumes, 
stringList(a.consumes()));
                        stringStream(a.defaultRequestHeaders()).map(x -> 
BasicHeader.ofPair(x)).forEach(x -> 
psb.appendTo(RESTMETHOD_defaultRequestHeaders, x));

Reply via email to