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

commit fbdb368f254cb4529b2ec0977f1f98f4cc8f103f
Author: JamesBognar <[email protected]>
AuthorDate: Mon Sep 13 20:29:20 2021 -0400

    Context API refactoring.
---
 .../java/org/apache/juneau/rest/RestChildren.java  | 122 ++++++++++++++++++++-
 .../apache/juneau/rest/RestChildrenBuilder.java    | 100 -----------------
 .../java/org/apache/juneau/rest/RestContext.java   | 108 +-----------------
 .../org/apache/juneau/rest/RestContextBuilder.java |  94 +++++++++++++++-
 4 files changed, 210 insertions(+), 214 deletions(-)

diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
index d8987e0..506c51a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
@@ -12,10 +12,16 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest;
 
+import static org.apache.juneau.internal.ObjectUtils.*;
+import static org.apache.juneau.rest.HttpRuntimeException.*;
+
 import java.util.*;
 
 import javax.servlet.*;
 
+import org.apache.juneau.collections.*;
+import org.apache.juneau.cp.*;
+import org.apache.juneau.http.response.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.util.*;
 
@@ -24,33 +30,137 @@ import org.apache.juneau.rest.util.*;
  */
 public class RestChildren {
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Static
+       
//-----------------------------------------------------------------------------------------------------------------
+
        /**
         * Represents a null value for the {@link Rest#restChildrenClass()} 
annotation.
         */
        @SuppressWarnings("javadoc")
        public final class Null extends RestChildren {
-               public Null(RestChildrenBuilder builder) throws Exception {
+               public Null(Builder builder) throws Exception {
                        super(builder);
                }
        }
 
-       private final Map<String,RestContext> children = 
Collections.synchronizedMap(new LinkedHashMap<String,RestContext>());
-
        /**
         * Creates a new builder for this object.
         *
         * @return A new builder for this object.
         */
-       public static RestChildrenBuilder create() {
-               return new RestChildrenBuilder();
+       public static Builder create() {
+               return new Builder();
        }
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Builder
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Builder class.
+        */
+       public static class Builder {
+
+               final List<RestContext> list = AList.create();
+
+               private BeanStore beanStore;
+               private Class<? extends RestChildren> type;
+               private RestChildren impl;
+
+               /**
+                * Instantiates a {@link RestChildren} object based on the 
contents of this builder.
+                *
+                * @return A new {@link RestChildren} object.
+                */
+               public RestChildren build() {
+                       try {
+                               if (impl != null)
+                                       return impl;
+                               Class<? extends RestChildren> 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 RestChildren> getDefaultImplClass() {
+                       return RestChildren.class;
+               }
+
+               /**
+                * Adds a child resource to this builder.
+                *
+                * @param value The REST context of the child resource.
+                * @return This object.
+                */
+               public Builder add(RestContext value) {
+                       list.add(value);
+                       return this;
+               }
+
+               /**
+                * Specifies a {@link RestChildren} implementation subclass to 
use.
+                *
+                * <p>
+                * When specified, the {@link #build()} method will create an 
instance of that class instead of the default {@link RestChildren}.
+                *
+                * <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 RestChildren> 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(RestChildren value) {
+                       impl = value;
+                       return this;
+               }
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Instance
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       private final Map<String,RestContext> children = 
Collections.synchronizedMap(new LinkedHashMap<String,RestContext>());
+
        /**
         * Constructor.
         *
         * @param builder The builder containing the settings for this object.
         */
-       public RestChildren(RestChildrenBuilder builder) {
+       public RestChildren(Builder builder) {
                for (RestContext rc : builder.list)
                        children.put(rc.getPath(), rc);
        }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildrenBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildrenBuilder.java
deleted file mode 100644
index 352b389..0000000
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildrenBuilder.java
+++ /dev/null
@@ -1,100 +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.rest.HttpRuntimeException.*;
-import static org.apache.juneau.internal.ObjectUtils.*;
-
-import java.util.*;
-
-import org.apache.juneau.collections.*;
-import org.apache.juneau.cp.*;
-import org.apache.juneau.http.response.*;
-
-/**
- * Builder for {@link RestChildren} objects.
- */
-public class RestChildrenBuilder {
-
-       final List<RestContext> list = AList.create();
-
-       private BeanStore beanStore;
-       private Class<? extends RestChildren> implClass;
-
-       /**
-        * Instantiates a {@link RestChildren} object based on the contents of 
this builder.
-        *
-        * @return A new {@link RestChildren} object.
-        */
-       public RestChildren build() {
-               try {
-                       Class<? extends RestChildren> ic = 
firstNonNull(implClass, getDefaultImplClass());
-                       return 
BeanStore.of(beanStore).addBeans(RestChildrenBuilder.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 RestChildren> getDefaultImplClass() {
-               return RestChildren.class;
-       }
-
-       /**
-        * Adds a child resource to this builder.
-        *
-        * @param childContext The REST context of the child resource.
-        * @return This object (for method chaining).
-        */
-       public RestChildrenBuilder add(RestContext childContext) {
-               this.list.add(childContext);
-               return this;
-       }
-
-       /**
-        * Specifies a {@link RestChildren} implementation subclass to use.
-        *
-        * <p>
-        * When specified, the {@link #build()} method will create an instance 
of that class instead of the default {@link RestChildren}.
-        *
-        * <p>
-        * The subclass must have a public constructor that takes in any of the 
following arguments:
-        * <ul>
-        *      <li>{@link RestChildrenBuilder} - 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 RestChildrenBuilder implClass(Class<? extends RestChildren> 
implClass) {
-               this.implClass = implClass;
-               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 (for method chaining).
-        */
-       public RestChildrenBuilder beanStore(BeanStore value) {
-               this.beanStore = value;
-               return this;
-       }
-}
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 2abf3a9..0704889 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
@@ -295,6 +295,7 @@ public class RestContext extends Context {
                        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();
+                       restChildren = builder.restChildren(this).build();
 
                        Object r = resource.get();
 
@@ -316,7 +317,6 @@ public class RestContext extends Context {
                                consumes = AList.unmodifiable(s);
                        }
 
-                       restChildren = createRestChildren(r, builder, bs, 
builder.inner);
 
                        swaggerProvider = createSwaggerProvider(r, builder, bs, 
fileFinder, messages, varResolver);
 
@@ -463,112 +463,6 @@ public class RestContext extends Context {
        }
 
        /**
-        * Creates the builder for the children of 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()}.
-        * @param servletConfig
-        *      The servlet config passed into the servlet by the servlet 
container.
-        * @return The builder for the {@link RestChildren} object.
-        * @throws Exception An error occurred.
-        */
-       protected RestChildren createRestChildren(Object resource, 
RestContextBuilder builder, BeanStore beanStore, ServletConfig servletConfig) 
throws Exception {
-
-               RestChildren x = createRestChildrenBuilder(resource, builder, 
beanStore, servletConfig).build();
-
-               x = BeanStore
-                       .of(beanStore, resource)
-                       .addBean(RestChildren.class, x)
-                       .beanCreateMethodFinder(RestChildren.class, resource)
-                       .find("createRestChildren")
-                       .withDefault(x)
-                       .run();
-
-               return x;
-       }
-
-       /**
-        * Instantiates the REST children builder for this REST resource.
-        *
-        * <p>
-        * Allows subclasses to intercept and modify the builder used by the 
{@link #createRestChildren(Object,RestContextBuilder,BeanStore,ServletConfig)} 
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()}.
-        * @param servletConfig
-        *      The servlet config passed into the servlet by the servlet 
container.
-        * @return The REST children builder for this REST resource.
-        * @throws Exception If REST children builder could not be instantiated.
-        */
-       protected RestChildrenBuilder createRestChildrenBuilder(Object 
resource, RestContextBuilder builder, BeanStore beanStore, ServletConfig 
servletConfig) throws Exception {
-
-               RestChildrenBuilder x = RestChildren
-                       .create()
-                       .beanStore(beanStore)
-                       .implClass(builder.childrenClass);
-
-               // Initialize our child resources.
-               for (Object o : builder.children) {
-                       String path = null;
-
-                       if (o instanceof RestChild) {
-                               RestChild rc = (RestChild)o;
-                               path = rc.path;
-                               o = rc.resource;
-                       }
-
-                       RestContextBuilder cb = null;
-
-                       if (o instanceof Class) {
-                               Class<?> oc = (Class<?>)o;
-                               // Don't allow specifying yourself as a child.  
Causes an infinite loop.
-                               if (oc == builder.resourceClass)
-                                       continue;
-                               cb = RestContext.create(oc, this, 
servletConfig);
-                               BeanStore bf = BeanStore.of(beanStore, 
resource).addBean(RestContextBuilder.class, cb);
-                               if (bf.getBean(oc).isPresent()) {
-                                       o = 
(Supplier<?>)()->bf.getBean(oc).get();  // If we resolved via injection, always 
get it this way.
-                               } else {
-                                       o = bf.createBean(oc);
-                               }
-                       } else {
-                               cb = RestContext.create(o.getClass(), this, 
servletConfig);
-                       }
-
-                       if (path != null)
-                               cb.path(path);
-
-                       RestContext cc = cb.init(o).build();
-
-                       MethodInfo mi = ClassInfo.of(o).getMethod("setContext", 
RestContext.class);
-                       if (mi != null)
-                               mi.accessible().invoke(o, cc);
-
-                       x.add(cc);
-               }
-
-               x = BeanStore
-                       .of(beanStore, resource)
-                       .addBean(RestChildrenBuilder.class, x)
-                       .beanCreateMethodFinder(RestChildrenBuilder.class, 
resource)
-                       .find("createRestChildrenBuilder")
-                       .withDefault(x)
-                       .run();
-
-               return x;
-       }
-
-       /**
         * Returns the bean store associated with this context.
         *
         * <p>
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 6df09eb..6e92a9b 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
@@ -146,6 +146,7 @@ public class RestContextBuilder extends ContextBuilder 
implements ServletConfig
        private DebugEnablement.Builder debugEnablement;
        private MethodList startCallMethods, endCallMethods, postInitMethods, 
postInitChildFirstMethods, destroyMethods, preCallMethods, postCallMethods;
        private RestOperations.Builder restOperations;
+       private RestChildren.Builder restChildren;
 
        String
                allowedHeaderParams = env("RestContext.allowedHeaderParams", 
"Accept,Content-Type"),
@@ -3171,6 +3172,97 @@ public class RestContextBuilder extends ContextBuilder 
implements ServletConfig
                return v.get();
        }
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // restChildren
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Returns the list of rest operations.
+        *
+        * @param restContext The rest context.
+        * @return The list of rest operations.
+        * @throws Exception If a problem occurred instantiating one of the 
child rest contexts.
+        */
+       public final RestChildren.Builder restChildren(RestContext restContext) 
throws Exception {
+               if (restChildren == null)
+                       restChildren = createRestChildren(beanStore(), 
resource(), restContext);
+               return restChildren;
+       }
+
+       /**
+        * Instantiates the REST children builder for this REST 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 Exception If a problem occurred instantiating one of the 
child rest contexts.
+        */
+       protected RestChildren.Builder createRestChildren(BeanStore beanStore, 
Supplier<?> resource, RestContext restContext) throws Exception {
+
+               Value<RestChildren.Builder> v = 
Value.of(RestChildren.create().beanStore(beanStore).type(childrenClass));
+               Object r = resource.get();
+
+               // Initialize our child resources.
+               for (Object o : children) {
+                       String path = null;
+
+                       if (o instanceof RestChild) {
+                               RestChild rc = (RestChild)o;
+                               path = rc.path;
+                               o = rc.resource;
+                       }
+
+                       RestContextBuilder cb = null;
+
+                       if (o instanceof Class) {
+                               Class<?> oc = (Class<?>)o;
+                               // Don't allow specifying yourself as a child.  
Causes an infinite loop.
+                               if (oc == resourceClass)
+                                       continue;
+                               cb = RestContext.create(oc, restContext, inner);
+                               BeanStore bf = BeanStore.of(beanStore, 
resource).addBean(RestContextBuilder.class, cb);
+                               if (bf.getBean(oc).isPresent()) {
+                                       o = 
(Supplier<?>)()->bf.getBean(oc).get();  // If we resolved via injection, always 
get it this way.
+                               } else {
+                                       o = bf.createBean(oc);
+                               }
+                       } else {
+                               cb = RestContext.create(o.getClass(), 
restContext, inner);
+                       }
+
+                       if (path != null)
+                               cb.path(path);
+
+                       RestContext cc = cb.init(o).build();
+
+                       MethodInfo mi = ClassInfo.of(o).getMethod("setContext", 
RestContext.class);
+                       if (mi != null)
+                               mi.accessible().invoke(o, cc);
+
+                       v.get().add(cc);
+               }
+
+               BeanStore
+                       .of(beanStore, r)
+                       .addBean(RestChildren.Builder.class, v.get())
+                       .beanCreateMethodFinder(RestChildren.Builder.class, r)
+                       .find("createRestChildrenBuilder")
+                       .run(x -> v.set(x));
+
+               BeanStore
+                       .of(beanStore, r)
+                       .addBean(RestChildren.Builder.class, v.get())
+                       .beanCreateMethodFinder(RestChildren.class, r)
+                       .find("createRestChildren")
+                       .run(x -> v.get().impl(x));
+
+               return v.get();
+       }
+
+
        private int TODO;
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -4193,7 +4285,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 RestChildrenBuilder} - The builder for the object.
+        *      <li>{@link RestChildren.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>

Reply via email to