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

commit f36370246c04d152479bf74552e228d556b7872a
Author: JamesBognar <[email protected]>
AuthorDate: Mon Sep 13 19:34:46 2021 -0400

    Context API refactoring.
---
 .../java/org/apache/juneau/rest/RestContext.java   | 116 +----------------
 .../org/apache/juneau/rest/RestContextBuilder.java | 104 +++++++++++++++-
 .../org/apache/juneau/rest/RestOperations.java     | 137 +++++++++++++++++++--
 .../apache/juneau/rest/RestOperationsBuilder.java  | 116 -----------------
 4 files changed, 234 insertions(+), 239 deletions(-)

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 92cb97b..2abf3a9 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
@@ -294,11 +294,10 @@ public class RestContext extends Context {
                        destroyMethods = 
builder.destroyMethods().stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);
                        preCallMethods = 
builder.preCallMethods().stream().map(this::toRestOpInvoker).toArray(RestOpInvoker[]::
 new);
                        postCallMethods = 
builder.postCallMethods().stream().map(this::toRestOpInvoker).toArray(RestOpInvoker[]::
 new);
+                       restOperations = builder.restOperations(this).build();
 
                        Object r = resource.get();
 
-                       restOperations = createRestOperations(r, builder, bs);
-
                        List<RestOpContext> opContexts = 
restOperations.getOpContexts();
 
                        if (builder.produces != null)
@@ -464,119 +463,6 @@ public class RestContext extends Context {
        }
 
        /**
-        * Creates the set of {@link RestOpContext} objects that represent the 
methods on this resource.
-        *
-        * @param resource
-        *      The REST servlet or bean that this context defines.
-        * @param builder
-        *      The builder for this object.
-        * @param beanStore
-        *      The factory used for creating beans and retrieving injected 
beans.
-        *      <br>Created by {@link RestContextBuilder#beanStore()}.
-        * @return The builder for the {@link RestOperations} object.
-        * @throws Exception An error occurred.
-        */
-       protected RestOperations createRestOperations(Object resource, 
RestContextBuilder builder, BeanStore beanStore) throws Exception {
-
-               RestOperations x = createRestOperationsBuilder(resource, 
builder, beanStore).build();
-
-               x = BeanStore
-                       .of(beanStore, resource)
-                       .addBean(RestOperations.class, x)
-                       .beanCreateMethodFinder(RestOperations.class, resource)
-                       .find("createRestOperations")
-                       .withDefault(x)
-                       .run();
-
-               return x;
-       }
-
-       /**
-        * Instantiates the REST methods builder for this REST resource.
-        *
-        * <p>
-        * Allows subclasses to intercept and modify the builder used by the 
{@link #createRestOperations(Object,RestContextBuilder,BeanStore)} method.
-        *
-        * @param resource
-        *      The REST servlet or bean that this context defines.
-        * @param builder
-        *      The builder for this object.
-        * @param beanStore
-        *      The factory used for creating beans and retrieving injected 
beans.
-        *      <br>Created by {@link RestContextBuilder#beanStore()}.
-        * @return The REST methods builder for this REST resource.
-        * @throws Exception If REST methods builder could not be instantiated.
-        */
-       protected RestOperationsBuilder createRestOperationsBuilder(Object 
resource, RestContextBuilder builder, BeanStore beanStore) throws Exception {
-
-               RestOperationsBuilder x = RestOperations
-                       .create()
-                       .beanStore(beanStore)
-                       .implClass(builder.operationsClass);
-
-               ClassInfo rci = ClassInfo.of(resource);
-
-               for (MethodInfo mi : rci.getPublicMethods()) {
-                       AnnotationList al = 
mi.getAnnotationGroupList(RestOp.class);
-
-                       // Also include methods on @Rest-annotated interfaces.
-                       if (al.size() == 0) {
-                               for (Method mi2 : mi.getMatching()) {
-                                       Class<?> ci2 = mi2.getDeclaringClass();
-                                       if (ci2.isInterface() && 
ci2.getAnnotation(Rest.class) != null) {
-                                               
al.add(AnnotationInfo.of(MethodInfo.of(mi2), RestOpAnnotation.DEFAULT));
-                                       }
-                               }
-                       }
-                       if (al.size() > 0) {
-                               try {
-                                       if (mi.isNotPublic())
-                                               throw new 
RestServletException("@RestOp method {0}.{1} must be defined as public.", 
rci.inner().getName(), mi.getSimpleName());
-
-                                       RestOpContext roc = RestOpContext
-                                               .create(mi.inner(), this)
-                                               .beanStore(beanStore)
-                                               .type(builder.opContextClass)
-                                               .build();
-
-                                       String httpMethod = roc.getHttpMethod();
-
-                                       // RRPC is a special case where a 
method returns an interface that we
-                                       // can perform REST calls against.
-                                       // We override the CallMethod.invoke() 
method to insert our logic.
-                                       if ("RRPC".equals(httpMethod)) {
-
-                                               RestOpContext roc2 = 
RestOpContext
-                                                       .create(mi.inner(), 
this)
-                                                       .dotAll()
-                                                       
.beanStore(rootBeanStore)
-                                                       
.type(RrpcRestOpContext.class)
-                                                       .build();
-                                               x
-                                                       .add("GET", roc2)
-                                                       .add("POST", roc2);
-
-                                       } else {
-                                               x.add(roc);
-                                       }
-                               } catch (Throwable e) {
-                                       throw new RestServletException(e, 
"Problem occurred trying to initialize methods on class {0}", 
rci.inner().getName());
-                               }
-                       }
-               }
-
-               x = BeanStore
-                       .of(beanStore, resource)
-                       .addBean(RestOperationsBuilder.class, x)
-                       .beanCreateMethodFinder(RestOperationsBuilder.class, 
resource)
-                       .find("createRestOperationsBuilder")
-                       .withDefault(x)
-                       .run();
-
-               return x;
-       }
-
-       /**
         * Creates the builder for the children of this resource.
         *
         * @param resource
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 d46d5c0..6df09eb 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
@@ -145,6 +145,7 @@ public class RestContextBuilder extends ContextBuilder 
implements ServletConfig
        private RestOpArgList.Builder restOpArgs, hookMethodArgs;
        private DebugEnablement.Builder debugEnablement;
        private MethodList startCallMethods, endCallMethods, postInitMethods, 
postInitChildFirstMethods, destroyMethods, preCallMethods, postCallMethods;
+       private RestOperations.Builder restOperations;
 
        String
                allowedHeaderParams = env("RestContext.allowedHeaderParams", 
"Accept,Content-Type"),
@@ -3069,6 +3070,107 @@ public class RestContextBuilder extends ContextBuilder 
implements ServletConfig
                return v.get();
        }
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // restOperations
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Returns the list of rest operations.
+        *
+        * @param restContext The rest context.
+        * @return The list of rest operations.
+        * @throws RestServletException If a problem occurred instantiating one 
of the child rest contexts.
+        */
+       public final RestOperations.Builder restOperations(RestContext 
restContext) throws RestServletException {
+               if (restOperations == null)
+                       restOperations = createRestOperations(beanStore(), 
resource(), restContext);
+               return restOperations;
+       }
+
+       /**
+        * Creates the set of {@link RestOpContext} objects that represent the 
methods on this resource.
+        *
+        * @param restContext The rest context.
+        * @param beanStore
+        *      The factory used for creating beans and retrieving injected 
beans.
+        * @param resource
+        *      The REST servlet or bean that this context defines.
+        * @return The default response headers for this REST object.
+        * @throws RestServletException If a problem occurred instantiating one 
of the child rest contexts.
+        */
+       protected RestOperations.Builder createRestOperations(BeanStore 
beanStore, Supplier<?> resource, RestContext restContext) throws 
RestServletException {
+
+               Value<RestOperations.Builder> v = 
Value.of(RestOperations.create());
+               Object r = resource.get();
+
+               ClassInfo rci = ClassInfo.of(r);
+
+               for (MethodInfo mi : rci.getPublicMethods()) {
+                       AnnotationList al = 
mi.getAnnotationGroupList(RestOp.class);
+
+                       // Also include methods on @Rest-annotated interfaces.
+                       if (al.size() == 0) {
+                               for (Method mi2 : mi.getMatching()) {
+                                       Class<?> ci2 = mi2.getDeclaringClass();
+                                       if (ci2.isInterface() && 
ci2.getAnnotation(Rest.class) != null) {
+                                               
al.add(AnnotationInfo.of(MethodInfo.of(mi2), RestOpAnnotation.DEFAULT));
+                                       }
+                               }
+                       }
+                       if (al.size() > 0) {
+                               try {
+                                       if (mi.isNotPublic())
+                                               throw new 
RestServletException("@RestOp method {0}.{1} must be defined as public.", 
rci.inner().getName(), mi.getSimpleName());
+
+                                       RestOpContext roc = RestOpContext
+                                               .create(mi.inner(), restContext)
+                                               .beanStore(beanStore)
+                                               .type(opContextClass)
+                                               .build();
+
+                                       String httpMethod = roc.getHttpMethod();
+
+                                       // RRPC is a special case where a 
method returns an interface that we
+                                       // can perform REST calls against.
+                                       // We override the CallMethod.invoke() 
method to insert our logic.
+                                       if ("RRPC".equals(httpMethod)) {
+
+                                               RestOpContext roc2 = 
RestOpContext
+                                                       .create(mi.inner(), 
restContext)
+                                                       .dotAll()
+                                                       
.beanStore(restContext.getRootBeanStore())
+                                                       
.type(RrpcRestOpContext.class)
+                                                       .build();
+                                               v.get()
+                                                       .add("GET", roc2)
+                                                       .add("POST", roc2);
+
+                                       } else {
+                                               v.get().add(roc);
+                                       }
+                               } catch (Throwable e) {
+                                       throw new RestServletException(e, 
"Problem occurred trying to initialize methods on class {0}", 
rci.inner().getName());
+                               }
+                       }
+               }
+
+               BeanStore
+                       .of(beanStore, r)
+                       .addBean(RestOperations.Builder.class, v.get())
+                       .beanCreateMethodFinder(RestOperations.Builder.class, r)
+                       .find("createRestOperationsBuilder")
+                       .run(x -> v.set(x));
+
+               BeanStore
+                       .of(beanStore, r)
+                       .addBean(RestOperations.Builder.class, v.get())
+                       .beanCreateMethodFinder(RestOperations.class, r)
+                       .find("createRestOperations")
+                       .run(x -> v.get().impl(x));
+
+               return v.get();
+       }
+
        private int TODO;
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -4213,7 +4315,7 @@ public class RestContextBuilder extends ContextBuilder 
implements ServletConfig
         * <p>
         * The subclass must have a public constructor that takes in any of the 
following arguments:
         * <ul>
-        *      <li>{@link RestOperationsBuilder} - The builder for the object.
+        *      <li>{@link RestOperations.Builder} - The builder for the object.
         *      <li>Any beans found in the specified bean store.
         *      <li>Any {@link Optional} beans that may or may not be found in 
the specified bean store.
         * </ul>
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperations.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperations.java
index 9255fdbf..340a92c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperations.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperations.java
@@ -13,10 +13,13 @@
 package org.apache.juneau.rest;
 
 import static org.apache.juneau.internal.ClassUtils.*;
+import static org.apache.juneau.internal.ObjectUtils.*;
+import static org.apache.juneau.rest.HttpRuntimeException.*;
 
 import java.util.*;
 
 import org.apache.juneau.collections.*;
+import org.apache.juneau.cp.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.rest.annotation.*;
 
@@ -25,34 +28,154 @@ import org.apache.juneau.rest.annotation.*;
  */
 public class RestOperations {
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Static
+       
//-----------------------------------------------------------------------------------------------------------------
+
        /**
         * Represents a null value for the {@link Rest#restOperationsClass()} 
annotation.
         */
        @SuppressWarnings("javadoc")
        public final class Null extends RestOperations {
-               public Null(RestOperationsBuilder builder) throws Exception {
+               public Null(Builder builder) throws Exception {
                        super(builder);
                }
        }
 
-       private final Map<String,List<RestOpContext>> map;
-       private List<RestOpContext> list;
-
        /**
         * Creates a new builder.
         *
         * @return A new builder.
         */
-       public static RestOperationsBuilder create() {
-               return new RestOperationsBuilder();
+       public static Builder create() {
+               return new Builder();
        }
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Builder
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Builder class.
+        */
+       public static class Builder  {
+
+               TreeMap<String,TreeSet<RestOpContext>> map = new TreeMap<>();
+               Set<RestOpContext> set = ASet.of();
+
+               private BeanStore beanStore;
+               private Class<? extends RestOperations> type;
+               private RestOperations impl;
+
+               /**
+                * Instantiates a {@link RestOperations} object based on the 
contents of this builder.
+                *
+                * @return A new {@link RestOperations} object.
+                */
+               public RestOperations build() {
+                       try {
+                               if (impl != null)
+                                       return impl;
+                               Class<? extends RestOperations> ic = 
firstNonNull(type, getDefaultImplClass());
+                               return 
BeanStore.of(beanStore).addBeans(Builder.class, this).createBean(ic);
+                       } catch (Exception e) {
+                               throw toHttpException(e, 
InternalServerError.class);
+                       }
+               }
+
+               /**
+                * Specifies the default implementation class if not specified 
via {@link #type(Class)}.
+                *
+                * @return The default implementation class if not specified 
via {@link #type(Class)}.
+                */
+               protected Class<? extends RestOperations> getDefaultImplClass() 
{
+                       return RestOperations.class;
+               }
+
+               /**
+                * Adds a method context to this builder.
+                *
+                * @param value The REST method context to add.
+                * @return Adds a method context to this builder.
+                */
+               public Builder add(RestOpContext value) {
+                       return add(value.getHttpMethod(), value);
+               }
+
+               /**
+                * Adds a method context to this builder.
+                *
+                * @param httpMethodName The HTTP method name.
+                * @param value The REST method context to add.
+                * @return Adds a method context to this builder.
+                */
+               public Builder add(String httpMethodName, RestOpContext value) {
+                       httpMethodName = httpMethodName.toUpperCase();
+                       if (! map.containsKey(httpMethodName))
+                               map.put(httpMethodName, new TreeSet<>());
+                       map.get(httpMethodName).add(value);
+                       set.add(value);
+                       return this;
+               }
+
+               /**
+                * Specifies a {@link RestOperations} implementation subclass 
to use.
+                *
+                * <p>
+                * When specified, the {@link #build()} method will create an 
instance of that class instead of the default {@link RestOperations}.
+                *
+                * <p>
+                * The subclass must have a public constructor that takes in 
any of the following arguments:
+                * <ul>
+                *      <li>{@link Builder} - This object.
+                *      <li>Any beans found in the specified {@link 
#beanStore(BeanStore) bean store}.
+                *      <li>Any {@link Optional} beans that may or may not be 
found in the specified {@link #beanStore(BeanStore) bean store}.
+                * </ul>
+                *
+                * @param value The implementation class to build.
+                * @return This object.
+                */
+               public Builder type(Class<? extends RestOperations> value) {
+                       type = value;
+                       return this;
+               }
+
+               /**
+                * Specifies a {@link BeanStore} to use when resolving 
constructor arguments.
+                *
+                * @param value The bean store to use for resolving constructor 
arguments.
+                * @return This object.
+                */
+               public Builder beanStore(BeanStore value) {
+                       beanStore = value;
+                       return this;
+               }
+
+               /**
+                * Specifies an already-instantiated bean for the {@link 
#build()} method to return.
+                *
+                * @param value The value for this setting.
+                * @return This object.
+                */
+               public Builder impl(RestOperations value) {
+                       impl = value;
+                       return this;
+               }
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Instance
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       private final Map<String,List<RestOpContext>> map;
+       private List<RestOpContext> list;
+
        /**
         * Constructor.
         *
         * @param builder The builder containing the settings for this object.
         */
-       public RestOperations(RestOperationsBuilder builder) {
+       public RestOperations(Builder builder) {
                AMap<String,List<RestOpContext>> m = AMap.create();
                for (Map.Entry<String,TreeSet<RestOpContext>> e : 
builder.map.entrySet())
                        m.put(e.getKey(), AList.of(e.getValue()));
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationsBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationsBuilder.java
deleted file mode 100644
index 40e7907..0000000
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationsBuilder.java
+++ /dev/null
@@ -1,116 +0,0 @@
-// 
***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
-// * with the License.  You may obtain a copy of the License at                
                                              *
-// *                                                                           
                                              *
-// *  http://www.apache.org/licenses/LICENSE-2.0                               
                                              *
-// *                                                                           
                                              *
-// * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
-// * specific language governing permissions and limitations under the 
License.                                              *
-// 
***************************************************************************************************************************
-package org.apache.juneau.rest;
-
-import static org.apache.juneau.internal.ObjectUtils.*;
-import static org.apache.juneau.rest.HttpRuntimeException.*;
-
-import java.util.*;
-
-import org.apache.juneau.collections.*;
-import org.apache.juneau.cp.*;
-import org.apache.juneau.http.response.*;
-
-/**
- * Builder for {@link RestOperations} object.
- */
-public class RestOperationsBuilder  {
-
-       TreeMap<String,TreeSet<RestOpContext>> map = new TreeMap<>();
-       Set<RestOpContext> set = ASet.of();
-
-       private BeanStore beanStore;
-       private Class<? extends RestOperations> implClass;
-
-       /**
-        * Instantiates a {@link RestOperations} object based on the contents 
of this builder.
-        *
-        * @return A new {@link RestOperations} object.
-        */
-       public RestOperations build() {
-               try {
-                       Class<? extends RestOperations> ic = 
firstNonNull(implClass, getDefaultImplClass());
-                       return 
BeanStore.of(beanStore).addBeans(RestOperationsBuilder.class, 
this).createBean(ic);
-               } catch (Exception e) {
-                       throw toHttpException(e, InternalServerError.class);
-               }
-       }
-
-       /**
-        * Specifies the default implementation class if not specified via 
{@link #implClass(Class)}.
-        *
-        * @return The default implementation class if not specified via {@link 
#implClass(Class)}.
-        */
-       protected Class<? extends RestOperations> getDefaultImplClass() {
-               return RestOperations.class;
-       }
-
-       /**
-        * Adds a method context to this builder.
-        *
-        * @param mc The REST method context to add.
-        * @return Adds a method context to this builder.
-        */
-       public RestOperationsBuilder add(RestOpContext mc) {
-               return add(mc.getHttpMethod(), mc);
-       }
-
-       /**
-        * Adds a method context to this builder.
-        *
-        * @param httpMethodName The HTTP method name.
-        * @param mc The REST method context to add.
-        * @return Adds a method context to this builder.
-        */
-       public RestOperationsBuilder add(String httpMethodName, RestOpContext 
mc) {
-               httpMethodName = httpMethodName.toUpperCase();
-               if (! map.containsKey(httpMethodName))
-                       map.put(httpMethodName, new TreeSet<>());
-               map.get(httpMethodName).add(mc);
-               set.add(mc);
-               return this;
-       }
-
-       /**
-        * Specifies a {@link RestOperations} implementation subclass to use.
-        *
-        * <p>
-        * When specified, the {@link #build()} method will create an instance 
of that class instead of the default {@link RestOperations}.
-        *
-        * <p>
-        * The subclass must have a public constructor that takes in any of the 
following arguments:
-        * <ul>
-        *      <li>{@link RestOperationsBuilder} - This object.
-        *      <li>Any beans found in the specified {@link 
#beanStore(BeanStore) bean store}.
-        *      <li>Any {@link Optional} beans that may or may not be found in 
the specified {@link #beanStore(BeanStore) bean store}.
-        * </ul>
-        *
-        * @param implClass The implementation class to build.
-        * @return This object (for method chaining).
-        */
-       public RestOperationsBuilder implClass(Class<? extends RestOperations> 
implClass) {
-               this.implClass = implClass;
-               return this;
-       }
-
-       /**
-        * Specifies a {@link BeanStore} to use when resolving constructor 
arguments.
-        *
-        * @param beanStore The bean store to use for resolving constructor 
arguments.
-        * @return This object (for method chaining).
-        */
-       public RestOperationsBuilder beanStore(BeanStore beanStore) {
-               this.beanStore = beanStore;
-               return this;
-       }
-}
\ No newline at end of file

Reply via email to