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 3f8024b Context API refactoring.
3f8024b is described below
commit 3f8024b6071094de6e6cca6ba2baf6ad40fb29c0
Author: JamesBognar <[email protected]>
AuthorDate: Mon Aug 30 18:44:47 2021 -0400
Context API refactoring.
---
.../java/org/apache/juneau/rest/RestContext.java | 163 ++-------------------
.../org/apache/juneau/rest/RestContextBuilder.java | 108 +++++++++++++-
.../java/org/apache/juneau/rest/RestOpArg.java | 2 +-
.../java/org/apache/juneau/rest/RestOpArgList.java | 64 +++++++-
.../org/apache/juneau/rest/annotation/Rest.java | 2 +-
.../juneau/rest/annotation/RestAnnotation.java | 2 +-
6 files changed, 178 insertions(+), 163 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 9065918..862fca7 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
@@ -969,94 +969,6 @@ public class RestContext extends BeanContext {
public static final String REST_renderResponseStackTraces = PREFIX +
".renderResponseStackTraces.b";
/**
- * Configuration property: Java REST method parameter resolvers.
- *
- * <h5 class='section'>Property:</h5>
- * <ul class='spaced-list'>
- * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestContext#REST_restOperationArgs REST_restParams}
- * <li><b>Name:</b> <js>"RestContext.restOperationsParams.lo"</js>
- * <li><b>Data type:</b> <c>List<Class<{@link
org.apache.juneau.rest.RestOpArg}>></c>
- * <li><b>Default:</b> empty list
- * <li><b>Session property:</b> <jk>false</jk>
- * <li><b>Annotations:</b>
- * <ul>
- * <li class='ja'>{@link
org.apache.juneau.rest.annotation.Rest#restOpArgs()}
- * </ul>
- * <li><b>Methods:</b>
- * <ul>
- * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#restOpArgs(Class...)}
- * </ul>
- * </ul>
- *
- * <h5 class='section'>Description:</h5>
- * <p>
- * By default, the Juneau framework will automatically Java method
parameters of various types (e.g.
- * <c>RestRequest</c>, <c>Accept</c>, <c>Reader</c>).
- * This setting allows you to provide your own resolvers for your own
class types that you want resolved.
- *
- * <p>
- * For example, if you want to pass in instances of
<c>MySpecialObject</c> to your Java method, define
- * the following resolver:
- * <p class='bcode w800'>
- * <jc>// Define a parameter resolver for resolving
MySpecialObject objects.</jc>
- * <jk>public class</jk> MyRestParam <jk>implements</jk> RestOpArg
{
- *
- * <jc>// Must implement a static creator method that
takes in a ParamInfo that describes the parameter
- * // being checked. If the parameter isn't of type
MySpecialObject, then it should return null.</jc>
- * <jk>public static</jk> MyRestParam
<jsm>create</jsm>(ParamInfo <jv>paramInfo</jv>) {
- * <jk>if</jk>
(<jv>paramInfo</jv>.isType(MySpecialObject.<jk>class</jk>)
- * <jk>return new</jk> MyRestParam();
- * <jk>return null</jk>;
- * }
- *
- * <jk>public</jk> MyRestParam() {}
- *
- * <jc>// The method that creates our object.
- * // In this case, we're taking in a query parameter and
converting it to our object.</jc>
- * <ja>@Override</ja>
- * <jk>public</jk> Object resolve(RestCall <jv>call</jv>)
<jk>throws</jk> Exception {
- * <jk>return new</jk>
MySpecialObject(<jv>call</jv>.getRestRequest().getQuery().get(<js>"myparam"</js>));
- * }
- * }
- *
- * <jc>// Option #1 - Registered via annotation.</jc>
- * <ja>@Rest</ja>(restOpArgs=MyRestParam.<jk>class</jk>)
- * <jk>public class</jk> MyResource {
- *
- * <jc>// Option #2 - Registered via builder passed in
through resource constructor.</jc>
- * <jk>public</jk> MyResource(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
- *
- * <jc>// Using method on builder.</jc>
- *
<jv>builder</jv>.restOperationParams(MyRestParam.<jk>class</jk>);
- *
- * <jc>// Same, but using property.</jc>
- *
<jv>builder</jv>.addTo(<jsf>REST_restOperationArgs</jsf>,
MyRestParam.<jk>class</jk>);
- * }
- *
- * <jc>// Option #3 - Registered via builder passed in
through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
- * <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
- *
<jv>builder</jv>.restOperationParams(MyRestParam.<jk>class</jk>);
- * }
- *
- * <jc>// Now pass it into your method.</jc>
- * <ja>@RestPost</ja>(...)
- * <jk>public</jk> Object doMyMethod(MySpecialObject
<jv>mySpecialObject</jv>) {
- * <jc>// Do something with it.</jc>
- * }
- * }
- * </p>
- *
- * <ul class='notes'>
- * <li>
- * Inner classes of the REST resource class are allowed.
- * <li>
- * Refer to {@link RestOpArg} for the list of predefined
parameter resolvers.
- * </ul>
- */
- public static final String REST_restOperationArgs = PREFIX +
".restOperationArgs.lo";
-
- /**
* Configuration property: Serializers.
*
* <h5 class='section'>Property:</h5>
@@ -1496,7 +1408,7 @@ public class RestContext extends BeanContext {
defaultResponseHeaders =
createDefaultResponseHeaders(r, cp, bf).build();
defaultRequestAttributes =
createDefaultRequestAttributes(r, cp, bf);
- opArgs = createOpArgs(r, cp, bf).asArray();
+ opArgs = createOpArgs(r, builder, bf).asArray();
hookMethodArgs = createHookMethodArgs(r, cp,
bf).asArray();
uriContext = builder.uriContext;
@@ -2289,7 +2201,7 @@ public class RestContext extends BeanContext {
* <p>
* Instantiates based on the following logic:
* <ul>
- * <li>Looks for {@link #REST_restOperationArgs} value set via any
of the following:
+ * <li>Looks for REST op args set via any of the following:
* <ul>
* <li>{@link
RestContextBuilder#restOpArgs(Class...)}/{@link
RestContextBuilder#restOpArgs(Class...)}
* <li>{@link Rest#restOpArgs()}.
@@ -2301,76 +2213,27 @@ public class RestContext extends BeanContext {
*
* @param resource
* The REST servlet or bean that this context defines.
- * @param properties
- * The properties of this bean.
- * <br>Consists of all properties gathered through the builder and
annotations on this class and all parent classes.
+ * @param builder
+ * The builder for this object.
* @param beanStore
* The factory used for creating beans and retrieving injected
beans.
* <br>Created by {@link
#createBeanStore(Object,ContextProperties,RestContext)}.
* @return The REST method parameter resolvers for this REST resource.
* @throws Exception If parameter resolvers could not be instantiated.
*/
- @SuppressWarnings("unchecked")
- protected RestOpArgList createOpArgs(Object resource, ContextProperties
properties, BeanStore beanStore) throws Exception {
-
- RestOpArgList x = RestOpArgList.create();
+ protected RestOpArgList createOpArgs(Object resource,
RestContextBuilder builder, BeanStore beanStore) throws Exception {
- for (Class<?> c : properties.getList(REST_restOperationArgs,
Class.class).orElse(emptyList()))
- x.append((Class<? extends RestOpArg>)c);
-
- x.append(
- AttributeArg.class,
- BodyArg.class,
- ConfigArg.class,
- FormDataArg.class,
- HasFormDataArg.class,
- HasQueryArg.class,
- HeaderArg.class,
- HttpServletRequestArg.class,
- HttpServletResponseArg.class,
- InputStreamArg.class,
- InputStreamParserArg.class,
- LocaleArg.class,
- MessagesArg.class,
- MethodArg.class,
- OutputStreamArg.class,
- ParserArg.class,
- PathArg.class,
- QueryArg.class,
- ReaderArg.class,
- ReaderParserArg.class,
- RequestAttributesArg.class,
- RequestBeanArg.class,
- RequestBodyArg.class,
- RequestFormDataArg.class,
- RequestHeadersArg.class,
- RequestPathArg.class,
- RequestQueryArg.class,
- ResourceBundleArg.class,
- ResponseBeanArg.class,
- ResponseHeaderArg.class,
- ResponseStatusArg.class,
- RestContextArg.class,
- RestRequestArg.class,
- ServetInputStreamArg.class,
- ServletOutputStreamArg.class,
- SwaggerArg.class,
- TimeZoneArg.class,
- UriContextArg.class,
- UriResolverArg.class,
- WriterArg.class,
- DefaultArg.class
- );
+ RestOpArgList.Builder x = builder.restOpArgs;
x = BeanStore
.of(beanStore, resource)
- .addBean(RestOpArgList.class, x)
- .beanCreateMethodFinder(RestOpArgList.class, resource)
+ .addBean(RestOpArgList.Builder.class, x)
+ .beanCreateMethodFinder(RestOpArgList.Builder.class,
resource)
.find("createRestOperationArgs")
.withDefault(x)
.run();
- return x;
+ return x.build();
}
/**
@@ -2390,7 +2253,7 @@ public class RestContext extends BeanContext {
@SuppressWarnings("unchecked")
protected RestOpArgList createHookMethodArgs(Object resource,
ContextProperties properties, BeanStore beanStore) throws Exception {
- RestOpArgList x = RestOpArgList.create();
+ RestOpArgList.Builder x = RestOpArgList.create();
x.append(
ConfigArg.class,
@@ -2415,13 +2278,13 @@ public class RestContext extends BeanContext {
x = BeanStore
.of(beanStore, resource)
- .addBean(RestOpArgList.class, x)
- .beanCreateMethodFinder(RestOpArgList.class, resource)
+ .addBean(RestOpArgList.Builder.class, x)
+ .beanCreateMethodFinder(RestOpArgList.Builder.class,
resource)
.find("createHookMethodArgs")
.withDefault(x)
.run();
- return x;
+ return x.build();
}
/**
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 40c6dea..7092d52 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
@@ -44,6 +44,7 @@ import org.apache.juneau.oapi.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.reflect.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.args.*;
import org.apache.juneau.rest.logging.*;
import org.apache.juneau.rest.processors.*;
import org.apache.juneau.rest.vars.*;
@@ -154,6 +155,51 @@ public class RestContextBuilder extends BeanContextBuilder
implements ServletCon
List<Object> children = new ArrayList<>();
+ @SuppressWarnings("unchecked")
+ RestOpArgList.Builder restOpArgs = RestOpArgList.create().append(
+ AttributeArg.class,
+ BodyArg.class,
+ ConfigArg.class,
+ FormDataArg.class,
+ HasFormDataArg.class,
+ HasQueryArg.class,
+ HeaderArg.class,
+ HttpServletRequestArg.class,
+ HttpServletResponseArg.class,
+ InputStreamArg.class,
+ InputStreamParserArg.class,
+ LocaleArg.class,
+ MessagesArg.class,
+ MethodArg.class,
+ OutputStreamArg.class,
+ ParserArg.class,
+ PathArg.class,
+ QueryArg.class,
+ ReaderArg.class,
+ ReaderParserArg.class,
+ RequestAttributesArg.class,
+ RequestBeanArg.class,
+ RequestBodyArg.class,
+ RequestFormDataArg.class,
+ RequestHeadersArg.class,
+ RequestPathArg.class,
+ RequestQueryArg.class,
+ ResourceBundleArg.class,
+ ResponseBeanArg.class,
+ ResponseHeaderArg.class,
+ ResponseStatusArg.class,
+ RestContextArg.class,
+ RestRequestArg.class,
+ ServetInputStreamArg.class,
+ ServletOutputStreamArg.class,
+ SwaggerArg.class,
+ TimeZoneArg.class,
+ UriContextArg.class,
+ UriResolverArg.class,
+ WriterArg.class,
+ DefaultArg.class
+ );
+
RestContextBuilder(Optional<RestContext> parentContext,
Optional<ServletConfig> servletConfig, Class<?> resourceClass, Optional<Object>
resource) throws ServletException {
try {
contextClass(RestContext.class);
@@ -2160,15 +2206,68 @@ public class RestContextBuilder extends
BeanContextBuilder implements ServletCon
}
/**
- * <i><l>RestContext</l> configuration property: </i> Java method
parameter resolvers.
+ * Java method parameter resolvers.
*
* <p>
* By default, the Juneau framework will automatically Java method
parameters of various types (e.g.
* <c>RestRequest</c>, <c>Accept</c>, <c>Reader</c>).
* This annotation allows you to provide your own resolvers for your
own class types that you want resolved.
*
- * <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_restOperationArgs}
+ * <p>
+ * For example, if you want to pass in instances of
<c>MySpecialObject</c> to your Java method, define
+ * the following resolver:
+ * <p class='bcode w800'>
+ * <jc>// Define a parameter resolver for resolving
MySpecialObject objects.</jc>
+ * <jk>public class</jk> MyRestOpArg <jk>implements</jk> RestOpArg
{
+ *
+ * <jc>// Must implement a static creator method that
takes in a ParamInfo that describes the parameter
+ * // being checked. If the parameter isn't of type
MySpecialObject, then it should return null.</jc>
+ * <jk>public static</jk> MyRestOpArg
<jsm>create</jsm>(ParamInfo <jv>paramInfo</jv>) {
+ * <jk>if</jk>
(<jv>paramInfo</jv>.isType(MySpecialObject.<jk>class</jk>)
+ * <jk>return new</jk> MyRestParam();
+ * <jk>return null</jk>;
+ * }
+ *
+ * <jk>public</jk> MyRestOpArg(ParamInfo
<jv>paramInfo</jv>) {}
+ *
+ * <jc>// The method that creates our object.
+ * // In this case, we're taking in a query parameter and
converting it to our object.</jc>
+ * <ja>@Override</ja>
+ * <jk>public</jk> Object resolve(RestCall <jv>call</jv>)
<jk>throws</jk> Exception {
+ * <jk>return new</jk>
MySpecialObject(<jv>call</jv>.getRestRequest().getQuery().get(<js>"myparam"</js>));
+ * }
+ * }
+ *
+ * <jc>// Option #1 - Registered via annotation.</jc>
+ * <ja>@Rest</ja>(restOpArgs=MyRestParam.<jk>class</jk>)
+ * <jk>public class</jk> MyResource {
+ *
+ * <jc>// Option #2 - Registered via builder passed in
through resource constructor.</jc>
+ * <jk>public</jk> MyResource(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
+ *
+ * <jc>// Using method on builder.</jc>
+ *
<jv>builder</jv>.restOpArgs(MyRestParam.<jk>class</jk>);
+ * }
+ *
+ * <jc>// Option #3 - Registered via builder passed in
through init method.</jc>
+ * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
+ *
<jv>builder</jv>.restOpArgs(MyRestParam.<jk>class</jk>);
+ * }
+ *
+ * <jc>// Now pass it into your method.</jc>
+ * <ja>@RestPost</ja>(...)
+ * <jk>public</jk> Object doMyMethod(MySpecialObject
<jv>mySpecialObject</jv>) {
+ * <jc>// Do something with it.</jc>
+ * }
+ * }
+ * </p>
+ *
+ * <ul class='notes'>
+ * <li>
+ * Inner classes of the REST resource class are allowed.
+ * <li>
+ * Refer to {@link RestOpArg} for the list of predefined
parameter resolvers.
* </ul>
*
* @param values The values to add to this setting.
@@ -2177,7 +2276,8 @@ public class RestContextBuilder extends
BeanContextBuilder implements ServletCon
@FluentSetter
@SuppressWarnings("unchecked")
public RestContextBuilder restOpArgs(Class<? extends
RestOpArg>...values) {
- return prependTo(REST_restOperationArgs, values);
+ restOpArgs.append(values);
+ return this;
}
/**
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpArg.java
index 42eea17..1ba0282 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpArg.java
@@ -43,7 +43,7 @@ import org.apache.juneau.rest.annotation.*;
* </p>
*
* <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_restOperationArgs}
+ * <li class='jm'>{@link RestContextBuilder#restOpArgs(Class...)}
* <li class='link'>{@doc RestmParameters}
* </ul>
*/
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpArgList.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpArgList.java
index 72dad28..df47e77 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpArgList.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpArgList.java
@@ -12,23 +12,75 @@
//
***************************************************************************************************************************
package org.apache.juneau.rest;
+import java.util.*;
+
import org.apache.juneau.collections.*;
+import org.apache.juneau.cp.*;
/**
* A list of {@link RestOpArg} classes.
*/
-public class RestOpArgList extends AList<Class<? extends RestOpArg>> {
+public class RestOpArgList {
- private static final long serialVersionUID = 1L;
+ private final Class<? extends RestOpArg>[] entries;
/**
* Static creator.
*
* @return An empty list.
*/
- @SuppressWarnings("unchecked")
- public static RestOpArgList create() {
- return new RestOpArgList();
+ public static Builder create() {
+ return new Builder();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param builder The builder containing the contents for this list.
+ */
+ protected RestOpArgList(Builder builder) {
+ entries =
+ builder
+ .entries
+ .stream()
+ .toArray(Class[]::new);
+ }
+
+ /**
+ * Builder for {@link RestOpArgList} objects.
+ */
+ public static class Builder {
+
+ AList<Class<? extends RestOpArg>> entries;
+ BeanStore beanStore;
+
+ /**
+ * Create an empty builder.
+ */
+ protected Builder() {
+ this.entries = AList.create();
+ }
+
+ /**
+ * Creates a new {@link RestOpArgList} object using a snapshot
of the settings defined in this builder.
+ *
+ * @return A new {@link RestOpArgList} object.
+ */
+ public RestOpArgList build() {
+ return new RestOpArgList(this);
+ }
+
+ /**
+ * Prepends the specified rest op arg classes to the list.
+ *
+ * @param values The values to add.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public Builder append(Class<? extends RestOpArg>...values) {
+ entries.addAll(0, Arrays.asList(values));
+ return this;
+ }
}
/**
@@ -37,6 +89,6 @@ public class RestOpArgList extends AList<Class<? extends
RestOpArg>> {
* @return The contents of this list as a {@link Class} array.
*/
public Class<? extends RestOpArg>[] asArray() {
- return asArrayOf(Class.class);
+ return entries;
}
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
index ccb508c..bcb8f8a 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
@@ -977,7 +977,7 @@ public @interface Rest {
* <br>This setting allows you to provide your own resolvers for your
own class types that you want resolved.
*
* <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_restOperationArgs}
+ * <li class='jm'>{@link RestContextBuilder#restOpArgs(Class...)}
* </ul>
*/
Class<? extends RestOpArg>[] restOpArgs() default {};
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
index 3e230a4..8c5e27a 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
@@ -1052,7 +1052,7 @@ public class RestAnnotation {
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
contentType(string(a.defaultContentType())));
b.responseProcessors(a.responseProcessors());
b.children((Object[])a.children());
- b.prependTo(REST_restOperationArgs, a.restOpArgs());
+ b.restOpArgs(a.restOpArgs());
value(a.contextClass()).ifPresent(x ->
b.contextClass(x));
value(a.uriContext()).ifPresent(x -> b.uriContext(x));
value(a.uriAuthority()).ifPresent(x ->
b.uriAuthority(x));