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>