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 576597a REST refactoring.
576597a is described below
commit 576597ad03d343e34c12596ce39e31c61575b332
Author: JamesBognar <[email protected]>
AuthorDate: Wed Jan 13 16:41:29 2021 -0500
REST refactoring.
---
.../org/apache/juneau/cp/BeanFactory_Test.java | 85 ++++--
.../apache/juneau/cp/BeanCreateMethodFinder.java | 135 +++++++++
.../java/org/apache/juneau/cp/BeanFactory.java | 65 ++--
.../org/apache/juneau/internal/ObjectUtils.java | 4 +-
.../org/apache/juneau/rest/RequestFormData.java | 24 +-
.../org/apache/juneau/rest/RequestHeaders.java | 25 +-
.../java/org/apache/juneau/rest/RequestQuery.java | 25 +-
.../java/org/apache/juneau/rest/RestContext.java | 217 +++++++++++---
.../org/apache/juneau/rest/RestContextBuilder.java | 7 +-
.../org/apache/juneau/rest/RestMethodContext.java | 329 +++++++++++++++------
.../java/org/apache/juneau/rest/RestRequest.java | 8 +-
11 files changed, 736 insertions(+), 188 deletions(-)
diff --git
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/BeanFactory_Test.java
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/BeanFactory_Test.java
index 3e09892..1ddd4a7 100644
---
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/BeanFactory_Test.java
+++
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/BeanFactory_Test.java
@@ -351,36 +351,65 @@ public class BeanFactory_Test {
}
@Test
- public void e01_createBeanViaMethod_noArgs() throws Exception {
- BeanFactory bf = new BeanFactory();
+ public void e01_beanCreateMethodFinder() throws Exception {
+ BeanFactory bf = BeanFactory.create();
E1 x = new E1();
- assertObject(bf.createBeanViaMethod(E.class, x, "createA0",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createA1",
null)).exists();
- assertObject(bf.createBeanViaMethod(E.class, x, "createA2",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createA3",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createA4",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createA5",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createA6",
null)).doesNotExist();
- assertThrown(()->bf.createBeanViaMethod(E.class, x, "createA7",
null)).contains("foo");
-
- assertObject(bf.createBeanViaMethod(E.class, x, "createB0",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createB1",
null)).exists();
- assertObject(bf.createBeanViaMethod(E.class, x, "createB2",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createB3",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createB4",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createB5",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createB6",
null)).doesNotExist();
- assertThrown(()->bf.createBeanViaMethod(E.class, x, "createB7",
null)).contains("foo");
-
- assertObject(bf.createBeanViaMethod(E.class, x, "createC1",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createC2",
null)).doesNotExist();
- assertObject(bf.createBeanViaMethod(E.class, x, "createC3",
null)).exists();
- assertObject(bf.createBeanViaMethod(E.class, x, "createC3",
null).a).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA0").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA1").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA2").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA3").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA4").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA5").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA6").run()).doesNotExist();
+ assertThrown(()->bf.beanCreateMethodFinder(E.class,
x).find("createA7").run()).contains("foo");
+
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createB0").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createB1").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createB2").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createB3").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createB4").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createB5").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createB6").run()).doesNotExist();
+ assertThrown(()->bf.beanCreateMethodFinder(E.class,
x).find("createB7").run()).contains("foo");
+
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC1").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC2").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run().a).doesNotExist();
bf.addBean(A.class, new A());
- assertObject(bf.createBeanViaMethod(E.class, x, "createC1",
null)).exists();
- assertObject(bf.createBeanViaMethod(E.class, x, "createC2",
null)).exists();
- assertObject(bf.createBeanViaMethod(E.class, x, "createC3",
null)).exists();
- assertObject(bf.createBeanViaMethod(E.class, x, "createC3",
null).a).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC1").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC2").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run().a).exists();
+ bf.addBean(A.class, null);
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC1").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC2").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run().a).doesNotExist();
+ bf.addBeanSupplier(A.class, ()->new A());
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC1").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC2").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run().a).exists();
+ bf.addBeanSupplier(A.class, null);
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC1").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC2").run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createC3").run().a).doesNotExist();
+
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createAx").thenFind("createA1").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA1").thenFind("createAx").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA1", A.class).thenFind("createA2",
A.class).run()).doesNotExist();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA1", A.class).thenFind("createA1").run()).exists();
+ assertObject(bf.beanCreateMethodFinder(E.class,
x).find("createA1", A.class).withDefault(new E()).run()).exists();
+
+ bf.addBeanSupplier(A.class, ()->new A());
+ assertObject(bf.createBean(A.class)).exists();
+
+ BeanFactory bf2 = BeanFactory.of(bf, null);
+ assertObject(bf2.beanCreateMethodFinder(E.class,
x).find("createA1").run()).exists();
+
+
assertString(bf2.toString()).is("{beanMap:[],parent:{beanMap:['A']}}");
}
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
new file mode 100644
index 0000000..d0fc615
--- /dev/null
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
@@ -0,0 +1,135 @@
+//
***************************************************************************************************************************
+// * 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.cp;
+
+import static org.apache.juneau.assertions.Assertions.*;
+import static org.apache.juneau.reflect.ReflectFlags.*;
+
+import java.util.*;
+import java.util.function.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.reflect.*;
+
+/**
+ * Used for finding methods on an object that take in arbitrary parameters and
returns bean instances.
+ *
+ * See {@link BeanFactory#beanCreateMethodFinder(Class, Object)} for usage.
+ *
+ * @param <T> The bean type being created.
+ */
+public class BeanCreateMethodFinder<T> {
+
+ private Class<T> beanType;
+ private final Object resource;
+ private final BeanFactory beanFactory;
+
+ private MethodInfo method;
+ private Object[] args;
+
+ private Supplier<T> def = ()->null;
+
+ BeanCreateMethodFinder(Class<T> beanType, Object resource, BeanFactory
beanFactory) {
+ this.beanType = beanType;
+ this.resource = resource;
+ this.beanFactory = beanFactory;
+ }
+
+ /**
+ * Find the method matching the specified name and optionally having
the specified required parameters present.
+ *
+ * <p>
+ * In order for the method to be used, it must adhere to the following
restrictions:
+ * <ul>
+ * <li>The method must be public.
+ * <li>The method can be static.
+ * <li>The method name must match exactly.
+ * <li>The method must not be deprecated or annotated with {@link
BeanIgnore}.
+ * <li>The method must have all parameter types specified in
<c>requiredParams</c>.
+ * <li>The bean factory must contain beans for all parameter types.
+ * <li>The bean factory may contain beans for all {@link Optional}
parameter types.
+ * </ul>
+ *
+ * <p>
+ * This method can be called multiple times with different method names
or required parameters until a match is found.
+ * <br>Once a method is found, subsequent calls to this method will be
no-ops.
+ *
+ * See {@link BeanFactory#beanCreateMethodFinder(Class, Object)} for
usage.
+ *
+ * @param methodName The method name.
+ * @param requiredParams Optional required parameters.
+ * @return This object (for method chaining).
+ */
+ public BeanCreateMethodFinder<T> find(String methodName,
Class<?>...requiredParams) {
+ if (method == null) {
+ ClassInfo ci = ClassInfo.of(resource);
+ for (MethodInfo m : ci.getPublicMethods()) {
+ if (m.isAll(NOT_DEPRECATED) &&
m.hasReturnType(beanType) && m.getSimpleName().equals(methodName) &&
(!m.hasAnnotation(BeanIgnore.class))) {
+ List<ClassInfo> missing =
beanFactory.getMissingParamTypes(m.getParamTypes());
+ if (missing.isEmpty() &&
m.hasAllArgs(requiredParams)) {
+ this.method = m;
+ this.args =
beanFactory.getParams(m.getParamTypes());
+ }
+ }
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Identical to {@link #find(String, Class...)} but named for
fluent-style calls.
+ *
+ * @param methodName The method name.
+ * @param requiredParams Optional required parameters.
+ * @return This object (for method chaining).
+ */
+ public BeanCreateMethodFinder<T> thenFind(String methodName,
Class<?>...requiredParams) {
+ return find(methodName, requiredParams);
+ }
+
+ /**
+ * A default value to return if no matching methods were found.
+ *
+ * @param def The default value. Can be <jk>null</jk>.
+ * @return This object (for method chaining).
+ */
+ public BeanCreateMethodFinder<T> withDefault(T def) {
+ return withDefault(()->def);
+ }
+
+ /**
+ * A default value to return if no matching methods were found.
+ *
+ * @param def The default value.
+ * @return This object (for method chaining).
+ */
+ public BeanCreateMethodFinder<T> withDefault(Supplier<T> def) {
+ assertArgNotNull("def", def);
+ this.def = def;
+ return this;
+ }
+
+ /**
+ * Executes the matched method and returns the result.
+ *
+ * @return The object returned by the method invocation, or the default
value if method was not found.
+ * @throws ExecutableException If method invocation threw an exception.
+ */
+ @SuppressWarnings("unchecked")
+ public T run() throws ExecutableException {
+ if (method != null)
+ return (T)method.invoke(resource, args);
+ return def.get();
+ }
+}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
index 247ee46..b8e7c98 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
@@ -42,16 +42,16 @@ public class BeanFactory {
/**
* Static creator.
- *
+ *
* @return A new {@link BeanFactory} object.
*/
- public static BeanFactory of() {
+ public static BeanFactory create() {
return new BeanFactory();
}
/**
* Static creator.
- *
+ *
* @param parent Parent bean factory. Can be <jk>null</jk> if this is
the root resource.
* @param outer Outer bean context to use when instantiating local
classes. Can be <jk>null</jk>.
* @return A new {@link BeanFactory} object.
@@ -138,7 +138,7 @@ public class BeanFactory {
* @param t The bean supplier.
* @return This object (for method chaining).
*/
- public <T> BeanFactory addBean(Class<T> c, Supplier<T> t) {
+ public <T> BeanFactory addBeanSupplier(Class<T> c, Supplier<T> t) {
if (t == null)
beanMap.remove(c);
else
@@ -214,29 +214,46 @@ public class BeanFactory {
throw new ExecutableException("Could not instantiate class {0}:
{1}.", c.getName(), msg.get());
}
-
/**
- * Creates a bean via a static or non-static method defined on the
specified class.
+ * Create a method finder for finding bean creation methods.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode w800'>
+ * <jc>// The bean we want to create.</jc>
+ * <jk>public class</jk> A {}
+ *
+ * <jc>// The bean that has a creator method for the bean
above.</jc>
+ * <jk>public class</jk> B {
+ *
+ * <jc>// Creator method.</jc>
+ * <jc>// Bean factory must have a C bean and optionally a
D bean.</jc>
+ * <jk>public</jk> A createA(C <mv>c</mv>,
Optional<D> <mv>d</mv>) {
+ * <jk>return new</jk> A(<mv>c</mv>,
<mv>d</mv>.orElse(<jk>null</jk>));
+ * }
+ * }
+ *
+ * <jc>// Instantiate the bean with the creator method.</jc>
+ * B <mv>b</mv> = <jk>new</jk> B();
+ *
+ * <jc>// Create a bean factory with some mapped beans.</jc>
+ * BeanFactory <mv>beanFactory</mv> =
BeanFactory.<jsm>create</jsm>().addBean(C.<jk>class</jk>, <jk>new</jk> C());
+ *
+ * <jc>// Instantiate the bean using the creator method.</jc>
+ * A <mv>a</mv> = <mv>beanFactory</mv>
+ * .beanCreateMethodFinder(A.<jk>class</jk>, <mv>b</mv>)
<jc>// Looking for creator for A on b object.</jc>
+ * .find(<js>"createA"</js>)
<jc>// Look for method called "createA".</jc>
+ * .thenFind(<js>"createA2"</js>)
<jc>// Then look for method called "createA2".</jc>
+ * .withDefault(()-><jk>new</jk> A())
<jc>// Optionally supply a default value if method not found.</jc>
+ * .run(); <jc>//
Execute.</jc>
+ * </p>
*
* @param <T> The bean type to create.
* @param c The bean type to create.
- * @param resource The object where the method is defined.
- * @param methodName The method name on the object to call.
- * @param def The default value to return if method doesn't exist.
- * @param requiredParams The parameter types that must be present on
the method.
- * @return A newly-created bean or <jk>null</jk> if method not found or
it returns <jk>null</jk>.
- * @throws ExecutableException If bean could not be created.
+ * @param resource The class containing the bean creator method.
+ * @return The created bean or the default value if method could not be
found.
*/
- public <T> T createBeanViaMethod(Class<T> c, Object resource, String
methodName, T def, Class<?>...requiredParams) throws ExecutableException {
- ClassInfo ci = ClassInfo.of(resource);
- for (MethodInfo m : ci.getPublicMethods()) {
- if (m.isAll(NOT_DEPRECATED) && m.hasReturnType(c) &&
m.getSimpleName().equals(methodName) && (!m.hasAnnotation(BeanIgnore.class))) {
- List<ClassInfo> missing =
getMissingParamTypes(m.getParamTypes());
- if (missing.isEmpty() &&
m.hasAllArgs(requiredParams))
- return m.invoke(resource,
getParams(m.getParamTypes()));
- }
- }
- return def;
+ public <T> BeanCreateMethodFinder<T> beanCreateMethodFinder(Class<T> c,
Object resource) {
+ return new BeanCreateMethodFinder<>(c, resource, this);
}
/**
@@ -291,8 +308,8 @@ public class BeanFactory {
public OMap toMap() {
return OMap.of()
.a("beanMap", beanMap.keySet().stream().map(x ->
x.getSimpleName()).collect(Collectors.toList()))
- .a("outer", ObjectUtils.identity(outer))
- .a("parent", ObjectUtils.identity(parent));
+ .asn("outer", ObjectUtils.identity(outer))
+ .asn("parent", parent.orElse(null));
}
@Override /* Object */
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java
index 0798158..41654b0 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java
@@ -321,10 +321,10 @@ public class ObjectUtils {
* @return An identity string.
*/
public static String identity(Object o) {
+ if (o instanceof Optional)
+ o = ((Optional<?>)o).orElse(null);
if (o == null)
return null;
- if (o instanceof Optional)
- o = ((Optional<?>)o).get();
return ClassInfo.of(o).getShortName() + "@" +
System.identityHashCode(o);
}
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
index d72db38..c92a9ee 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
@@ -21,6 +21,7 @@ import java.util.*;
import javax.servlet.http.*;
+import org.apache.http.*;
import org.apache.juneau.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.http.annotation.*;
@@ -28,7 +29,7 @@ import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.oapi.*;
-import org.apache.juneau.parser.*;
+import org.apache.juneau.parser.ParseException;
import org.apache.juneau.http.exception.*;
/**
@@ -91,6 +92,25 @@ public class RequestFormData extends
LinkedHashMap<String,String[]> {
}
/**
+ * Adds default entries to these form-data parameters.
+ *
+ * @param pairs
+ * The default entries.
+ * <br>Can be <jk>null</jk>.
+ * @return This object (for method chaining).
+ */
+ public RequestFormData addDefault(NameValuePair...pairs) {
+ for (NameValuePair p : pairs) {
+ String key = p.getName();
+ Object value = p.getValue();
+ String[] v = get(key);
+ if (v == null || v.length == 0 ||
StringUtils.isEmpty(v[0]))
+ put(key, stringifyAll(value));
+ }
+ return this;
+ }
+
+ /**
* Adds a default entries to these form-data parameters.
*
* <p>
@@ -562,7 +582,7 @@ public class RequestFormData extends
LinkedHashMap<String,String[]> {
public <T> T get(String name, Type type, Type...args) throws
BadRequest, InternalServerError {
return getInner(null, null, name, null,
this.<T>getClassMeta(type, args));
}
-
+
/**
* Same as {@link #get(String, Type, Type...)} but allows you to
override the part parser.
*
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
index 75fe74e..979122b 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
@@ -18,13 +18,14 @@ import static org.apache.juneau.internal.StringUtils.*;
import java.lang.reflect.*;
import java.util.*;
+import org.apache.http.*;
import org.apache.juneau.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.oapi.*;
-import org.apache.juneau.parser.*;
+import org.apache.juneau.parser.ParseException;
import org.apache.juneau.http.exception.*;
import org.apache.juneau.http.header.*;
import org.apache.juneau.http.header.Date;
@@ -88,6 +89,28 @@ public class RequestHeaders extends TreeMap<String,String[]>
{
}
/**
+ * Adds default entries to these headers.
+ *
+ * <p>
+ * Similar to {@link #put(String, Object)} but doesn't override
existing values.
+ *
+ * @param pairs
+ * The default entries.
+ * <br>Can be <jk>null</jk>.
+ * @return This object (for method chaining).
+ */
+ public RequestHeaders addDefault(Header...pairs) {
+ for (Header p : pairs) {
+ String key = p.getName();
+ Object value = p.getValue();
+ String[] v = get(key);
+ if (v == null || v.length == 0 ||
StringUtils.isEmpty(v[0]))
+ put(key, stringifyAll(value));
+ }
+ return this;
+ }
+
+ /**
* Adds a default header value on this request.
*
* <p>
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQuery.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQuery.java
index 4ea89c9..1f55775 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQuery.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQuery.java
@@ -20,13 +20,14 @@ import java.util.*;
import javax.servlet.http.*;
+import org.apache.http.*;
import org.apache.juneau.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.oapi.*;
-import org.apache.juneau.parser.*;
+import org.apache.juneau.parser.ParseException;
import org.apache.juneau.http.exception.*;
import org.apache.juneau.utils.*;
@@ -92,6 +93,28 @@ public final class RequestQuery extends
LinkedHashMap<String,String[]> {
}
/**
+ * Adds default entries to these query parameters.
+ *
+ * <p>
+ * This includes the default queries defined at the resource and method
levels.
+ *
+ * @param pairs
+ * The default entries.
+ * <br>Can be <jk>null</jk>.
+ * @return This object (for method chaining).
+ */
+ public RequestQuery addDefault(NameValuePair...pairs) {
+ for (NameValuePair p : pairs) {
+ String key = p.getName();
+ Object value = p.getValue();
+ String[] v = get(key);
+ if (v == null || v.length == 0 ||
StringUtils.isEmpty(v[0]))
+ put(key, stringifyAll(value));
+ }
+ return this;
+ }
+
+ /**
* Adds a default entries to these query parameters.
*
* <p>
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 621f508..4fddaea 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
@@ -3689,19 +3689,30 @@ public class RestContext extends BeanContext {
*/
protected FileFinder createFileFinder(Object resource, BeanFactory
beanFactory) throws Exception {
FileFinder x = null;
+
if (resource instanceof FileFinder)
x = (FileFinder)resource;
+
if (x == null)
x = getInstanceProperty(REST_fileFinder,
FileFinder.class, null, beanFactory);
+
if (x == null)
x = beanFactory.getBean(FileFinder.class).orElse(null);
+
if (x == null)
x = getInstanceProperty(REST_fileFinderDefault,
FileFinder.class, null, beanFactory);
+
if (x == null)
x = new BasicFileFinder(this);
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(FileFinder.class, x)
- .createBeanViaMethod(FileFinder.class, resource,
"createFileFinder", x);
+ .beanCreateMethodFinder(FileFinder.class, resource)
+ .find("createFileFinder")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -3736,17 +3747,27 @@ public class RestContext extends BeanContext {
*/
protected RestInfoProvider createInfoProvider(Object resource,
BeanFactory beanFactory) throws Exception {
RestInfoProvider x = null;
+
if (resource instanceof RestInfoProvider)
x = (RestInfoProvider)resource;
+
if (x == null)
x = getInstanceProperty(REST_infoProvider,
RestInfoProvider.class, null, beanFactory);
+
if (x == null)
x =
beanFactory.getBean(RestInfoProvider.class).orElse(null);
+
if (x == null)
x = new BasicRestInfoProvider(this);
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(RestInfoProvider.class, x)
- .createBeanViaMethod(RestInfoProvider.class, resource,
"createInfoProvider", x);
+ .beanCreateMethodFinder(RestInfoProvider.class,
resource)
+ .find("createInfoProvider")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -3783,19 +3804,30 @@ public class RestContext extends BeanContext {
*/
protected StaticFiles createStaticFiles(Object resource, BeanFactory
beanFactory) throws Exception {
StaticFiles x = null;
+
if (resource instanceof StaticFiles)
x = (StaticFiles)resource;
+
if (x == null)
x = getInstanceProperty(REST_staticFiles,
StaticFiles.class, null, beanFactory);
+
if (x == null)
x = beanFactory.getBean(StaticFiles.class).orElse(null);
+
if (x == null)
x = getInstanceProperty(REST_staticFilesDefault,
StaticFiles.class, null, beanFactory);
+
if (x == null)
x = new BasicStaticFiles(this);
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(StaticFiles.class, x)
- .createBeanViaMethod(StaticFiles.class, resource,
"createStaticFiles", x);
+ .beanCreateMethodFinder(StaticFiles.class, resource)
+ .find("createStaticFiles")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -3832,19 +3864,30 @@ public class RestContext extends BeanContext {
*/
protected RestLogger createCallLogger(Object resource, BeanFactory
beanFactory) throws Exception {
RestLogger x = null;
+
if (resource instanceof RestLogger)
x = (RestLogger)resource;
+
if (x == null)
x = getInstanceProperty(REST_callLogger,
RestLogger.class, null, beanFactory);
+
if (x == null)
x = beanFactory.getBean(RestLogger.class).orElse(null);
+
if (x == null)
x = getInstanceProperty(REST_callLoggerDefault,
RestLogger.class, null, beanFactory);
+
if (x == null)
x = new BasicRestLogger(this);
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(RestLogger.class, x)
- .createBeanViaMethod(RestLogger.class, resource,
"createCallLogger", x);
+ .beanCreateMethodFinder(RestLogger.class, resource)
+ .find("createCallLogger")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -3878,18 +3921,28 @@ public class RestContext extends BeanContext {
*/
protected BeanFactory createBeanFactory(Object resource) throws
Exception {
BeanFactory x = null;
+
if (resource instanceof BeanFactory)
x = (BeanFactory)resource;
+
BeanFactory bf = createRootBeanFactory(resource)
.addBean(RestContext.class, this)
.addBean(BeanFactory.class, parentContext == null ?
null : parentContext.rootBeanFactory)
.addBean(PropertyStore.class, getPropertyStore())
.addBean(Object.class, resource);
+
if (x == null)
x = getInstanceProperty(REST_beanFactory,
BeanFactory.class, null, bf);
+
if (x == null)
x = bf;
- x = bf.createBeanViaMethod(BeanFactory.class, resource,
"createBeanFactory", x);
+
+ x = bf
+ .beanCreateMethodFinder(BeanFactory.class, resource)
+ .find("createBeanFactory")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -3926,16 +3979,26 @@ public class RestContext extends BeanContext {
*/
protected BeanFactory createRootBeanFactory(Object resource) throws
Exception {
BeanFactory x = null;
+
if (resource instanceof BeanFactory)
x = (BeanFactory)resource;
+
BeanFactory parent = parentContext == null ? null :
parentContext.rootBeanFactory;
BeanFactory bf = new BeanFactory(parent, resource);
bf.addBean(BeanFactory.class, bf);
+
if (x == null)
x = getInstanceProperty(REST_beanFactory,
BeanFactory.class, null, bf);
+
if (x == null)
x = bf;
- x = bf.createBeanViaMethod(BeanFactory.class, resource,
"createBeanFactory", x);
+
+ x = bf
+ .beanCreateMethodFinder(BeanFactory.class, resource)
+ .find("createBeanFactory")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -3969,13 +4032,21 @@ public class RestContext extends BeanContext {
*/
protected ResponseHandler[] createResponseHandlers(Object resource,
BeanFactory beanFactory) throws Exception {
ResponseHandler[] x =
getInstanceArrayProperty(REST_responseHandlers, ResponseHandler.class, null,
beanFactory);
+
if (x == null)
x =
beanFactory.getBean(ResponseHandler[].class).orElse(null);
+
if (x == null)
x = new ResponseHandler[0];
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(ResponseHandler[].class, x)
- .createBeanViaMethod(ResponseHandler[].class, resource,
"createResponseHandlers", x);
+ .beanCreateMethodFinder(ResponseHandler[].class,
resource)
+ .find("createResponseHandlers")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -4013,10 +4084,13 @@ public class RestContext extends BeanContext {
if (g == null) {
Object[] x = getArrayProperty(REST_serializers,
Object.class);
+
if (x == null)
x =
beanFactory.getBean(Serializer[].class).orElse(null);
+
if (x == null)
x = new Serializer[0];
+
g = SerializerGroup
.create()
.append(x)
@@ -4024,9 +4098,13 @@ public class RestContext extends BeanContext {
.build();
}
- g = BeanFactory.of(beanFactory, resource)
+ g = BeanFactory
+ .of(beanFactory, resource)
.addBean(SerializerGroup.class, g)
- .createBeanViaMethod(SerializerGroup.class, resource,
"createSerializers", g);
+ .beanCreateMethodFinder(SerializerGroup.class, resource)
+ .find("createSerializers")
+ .withDefault(g)
+ .run();
return g;
}
@@ -4065,10 +4143,13 @@ public class RestContext extends BeanContext {
if (g == null) {
Object[] x = getArrayProperty(REST_parsers,
Object.class);
+
if (x == null)
x =
beanFactory.getBean(Parser[].class).orElse(null);
+
if (x == null)
x = new Parser[0];
+
g = ParserGroup
.create()
.append(x)
@@ -4076,9 +4157,13 @@ public class RestContext extends BeanContext {
.build();
}
- g = BeanFactory.of(beanFactory, resource)
+ g = BeanFactory
+ .of(beanFactory, resource)
.addBean(ParserGroup.class, g)
- .createBeanViaMethod(ParserGroup.class, resource,
"createParsers", g);
+ .beanCreateMethodFinder(ParserGroup.class, resource)
+ .find("createParsers")
+ .withDefault(g)
+ .run();
return g;
}
@@ -4114,17 +4199,27 @@ public class RestContext extends BeanContext {
*/
protected HttpPartSerializer createPartSerializer(Object resource,
BeanFactory beanFactory) throws Exception {
HttpPartSerializer x = null;
+
if (resource instanceof HttpPartSerializer)
x = (HttpPartSerializer)resource;
+
if (x == null)
x = getInstanceProperty(REST_partSerializer,
HttpPartSerializer.class, null, beanFactory);
+
if (x == null)
x =
beanFactory.getBean(HttpPartSerializer.class).orElse(null);
+
if (x == null)
x = new OpenApiSerializer(getPropertyStore());
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(HttpPartSerializer.class, x)
- .createBeanViaMethod(HttpPartSerializer.class,
resource, "createPartSerializer", x);
+ .beanCreateMethodFinder(HttpPartSerializer.class,
resource)
+ .find("createPartSerializer")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -4159,17 +4254,27 @@ public class RestContext extends BeanContext {
*/
protected HttpPartParser createPartParser(Object resource, BeanFactory
beanFactory) throws Exception {
HttpPartParser x = null;
+
if (resource instanceof HttpPartParser)
x = (HttpPartParser)resource;
+
if (x == null)
x = getInstanceProperty(REST_partParser,
HttpPartParser.class, null, beanFactory);
+
if (x == null)
x =
beanFactory.getBean(HttpPartParser.class).orElse(null);
+
if (x == null)
x = new OpenApiParser(getPropertyStore());
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(HttpPartParser.class, x)
- .createBeanViaMethod(HttpPartParser.class, resource,
"createPartParser", x);
+ .beanCreateMethodFinder(HttpPartParser.class, resource)
+ .find("createPartParser")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -4203,13 +4308,21 @@ public class RestContext extends BeanContext {
*/
protected RestMethodParam[] createParamResolvers(Object resource,
BeanFactory beanFactory) throws Exception {
RestMethodParam[] x =
getInstanceArrayProperty(REST_paramResolvers, RestMethodParam.class, null,
beanFactory);
+
if (x == null)
x =
beanFactory.getBean(RestMethodParam[].class).orElse(null);
+
if (x == null)
x = new RestMethodParam[0];
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(RestMethodParam[].class, x)
- .createBeanViaMethod(RestMethodParam[].class, resource,
"createParamResolvers", x);
+ .beanCreateMethodFinder(RestMethodParam[].class,
resource)
+ .find("createParamResolvers")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -4237,11 +4350,18 @@ public class RestContext extends BeanContext {
*/
protected Logger createLogger(Object resource, BeanFactory beanFactory)
throws Exception {
Logger x = beanFactory.getBean(Logger.class).orElse(null);
+
if (x == null)
x = Logger.getLogger(resource.getClass().getName());
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(Logger.class, x)
- .createBeanViaMethod(Logger.class, resource,
"createLogger", x);
+ .beanCreateMethodFinder(Logger.class, resource)
+ .find("createLogger")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -4269,14 +4389,21 @@ public class RestContext extends BeanContext {
*/
protected JsonSchemaGenerator createJsonSchemaGenerator(Object
resource, BeanFactory beanFactory) throws Exception {
JsonSchemaGenerator x =
beanFactory.getBean(JsonSchemaGenerator.class).orElse(null);
+
if (x == null)
x = JsonSchemaGenerator
.create()
.apply(getPropertyStore())
.build();
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(JsonSchemaGenerator.class, x)
- .createBeanViaMethod(JsonSchemaGenerator.class,
resource, "createJsonSchemaGenerator", x);
+ .beanCreateMethodFinder(JsonSchemaGenerator.class,
resource)
+ .find("createJsonSchemaGenerator")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -4304,14 +4431,18 @@ public class RestContext extends BeanContext {
*/
protected VarResolver createVarResolver(Object resource, BeanFactory
beanFactory) throws Exception {
VarResolver x =
beanFactory.getBean(VarResolver.class).orElse(null);
+
if (x == null)
- x = builder.varResolverBuilder
- .vars(createVars(resource,beanFactory))
- .build()
- ;
- x = BeanFactory.of(beanFactory, resource)
+ x =
builder.varResolverBuilder.vars(createVars(resource,beanFactory)).build();
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(VarResolver.class, x)
- .createBeanViaMethod(VarResolver.class, resource,
"createVarResolver", x);
+ .beanCreateMethodFinder(VarResolver.class, resource)
+ .find("createVarResolver")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -4340,6 +4471,7 @@ public class RestContext extends BeanContext {
@SuppressWarnings("unchecked")
protected VarList createVars(Object resource, BeanFactory beanFactory)
throws Exception {
VarList x = beanFactory.getBean(VarList.class).orElse(null);
+
if (x == null)
x = VarList.of(
FileVar.class,
@@ -4358,9 +4490,15 @@ public class RestContext extends BeanContext {
UrlEncodeVar.class,
HtmlWidgetVar.class
);
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(VarList.class, x)
- .createBeanViaMethod(VarList.class, resource,
"createVars", x);
+ .beanCreateMethodFinder(VarList.class, resource)
+ .find("createVars")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -4388,11 +4526,18 @@ public class RestContext extends BeanContext {
*/
protected StackTraceStore createStackTraceStore(Object resource,
BeanFactory beanFactory) throws Exception {
StackTraceStore x =
beanFactory.getBean(StackTraceStore.class).orElse(null);
+
if (x == null)
x = StackTraceStore.GLOBAL;
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(StackTraceStore.class, x)
- .createBeanViaMethod(StackTraceStore.class, resource,
"createStackTraceStore", x);
+ .beanCreateMethodFinder(StackTraceStore.class, resource)
+ .find("createStackTraceStore")
+ .withDefault(x)
+ .run();
+
return x;
}
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 d42ef49..e26f43f 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
@@ -203,8 +203,11 @@ public class RestContextBuilder extends BeanContextBuilder
implements ServletCon
BeanFactory x = null;
if (resource.isPresent()) {
Object r = resource.get();
- BeanFactory bf = new
BeanFactory(parentContext.isPresent() ? parentContext.get().rootBeanFactory :
null, r);
- x = bf.createBeanViaMethod(BeanFactory.class, r,
"createBeanFactory", null);
+ x = BeanFactory
+ .of(parentContext.isPresent() ?
parentContext.get().rootBeanFactory : null, r)
+ .beanCreateMethodFinder(BeanFactory.class,
resource)
+ .find("createBeanFactory")
+ .run();
}
if (x == null && parentContext.isPresent()) {
x = parentContext.get().rootBeanFactory;
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
index ab1b125..9fc8663 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
@@ -32,6 +32,8 @@ import java.util.concurrent.atomic.*;
import javax.servlet.*;
import javax.servlet.http.*;
+import org.apache.http.*;
+import org.apache.http.ParseException;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.collections.*;
@@ -39,6 +41,7 @@ import org.apache.juneau.cp.*;
import org.apache.juneau.encoders.*;
import org.apache.juneau.http.*;
import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.http.annotation.Header;
import org.apache.juneau.httppart.*;
import org.apache.juneau.httppart.bean.*;
import org.apache.juneau.internal.*;
@@ -529,10 +532,9 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
final HttpPartSerializer partSerializer;
final HttpPartParser partParser;
final JsonSchemaGenerator jsonSchemaGenerator;
- final Map<String,Object>
- reqHeaders,
- defaultQuery,
- defaultFormData;
+ final org.apache.http.Header[] defaultRequestHeaders;
+ final NameValuePair[] defaultRequestQuery;
+ final NameValuePair[] defaultRequestFormData;
final OMap reqAttrs;
final String defaultCharset;
final long maxInput;
@@ -624,57 +626,13 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
methodParams = context.findParams(mi, false,
pathMatchers[this.pathMatchers.length-1]);
- Map<String,Object> _reqHeaders = new
TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-
_reqHeaders.putAll(getMapProperty(RESTMETHOD_reqHeaders, Object.class));
+ defaultRequestHeaders = createDefaultRequestHeaders(r,
beanFactory, method);
+ defaultRequestQuery = createDefaultRequestQuery(r,
beanFactory, method);
+ defaultRequestFormData =
createDefaultRequestFormData(r, beanFactory, method);
OMap _reqAttrs = new
OMap(context.getReqAttrs()).appendAll(getMapProperty(RESTMETHOD_reqAttrs,
Object.class));
- Map<String,Object> _defaultQuery = new
LinkedHashMap<>(getMapProperty(RESTMETHOD_defaultQuery, Object.class));
-
- Map<String,Object> _defaultFormData = new
LinkedHashMap<>(getMapProperty(RESTMETHOD_defaultFormData, Object.class));
-
- Type[] pt = method.getGenericParameterTypes();
- Annotation[][] pa = method.getParameterAnnotations();
- for (int i = 0; i < pt.length; i++) {
- for (Annotation a : pa[i]) {
- if (a instanceof Header) {
- Header h = (Header)a;
- String def =
joinnlFirstNonEmptyArray(h._default(), h.df());
- if (def != null) {
- try {
-
_reqHeaders.put(firstNonEmpty(h.name(), h.n(), h.value()), parseAnything(def));
- } catch (ParseException
e) {
- throw new
ConfigException(e, "Malformed @Header annotation");
- }
- }
- } else if (a instanceof Query) {
- Query q = (Query)a;
- String def =
joinnlFirstNonEmptyArray(q._default(), q.df());
- if (def != null) {
- try {
-
_defaultQuery.put(firstNonEmpty(q.name(), q.n(), q.value()),
parseAnything(def));
- } catch (ParseException
e) {
- throw new
ConfigException(e, "Malformed @Query annotation");
- }
- }
- } else if (a instanceof FormData) {
- FormData f = (FormData)a;
- String def =
joinnlFirstNonEmptyArray(f._default(), f.df());
- if (def != null) {
- try {
-
_defaultFormData.put(firstNonEmpty(f.name(), f.value(), f.n()),
parseAnything(def));
- } catch (ParseException
e) {
- throw new
ConfigException(e, "Malformed @FormData annotation");
- }
- }
- }
- }
- }
-
- this.reqHeaders =
Collections.unmodifiableMap(_reqHeaders);
this.reqAttrs = _reqAttrs.unmodifiable();
- this.defaultQuery =
Collections.unmodifiableMap(_defaultQuery);
- this.defaultFormData =
Collections.unmodifiableMap(_defaultFormData);
this.priority = getIntegerProperty(RESTMETHOD_priority,
0);
@@ -742,13 +700,22 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
*/
protected RestConverter[] createConverters(Object resource, BeanFactory
beanFactory) throws Exception {
RestConverter[] x = getInstanceArrayProperty(REST_converters,
RestConverter.class, null, beanFactory);
+
if (x == null)
x =
beanFactory.getBean(RestConverter[].class).orElse(null);
+
if (x == null)
x = new RestConverter[0];
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(RestConverter[].class, x)
- .createBeanViaMethod(RestConverter[].class, resource,
"createConverters", x);
+ .beanCreateMethodFinder(RestConverter[].class, resource)
+ .find("createConverters", Method.class)
+ .thenFind("createConverters")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -784,8 +751,10 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
*/
protected RestGuard[] createGuards(Object resource, BeanFactory
beanFactory) throws Exception {
RestGuard[] x = getInstanceArrayProperty(REST_guards,
RestGuard.class, null, beanFactory);
+
if (x == null)
x = beanFactory.getBean(RestGuard[].class).orElse(null);
+
if (x == null)
x = new RestGuard[0];
@@ -805,9 +774,14 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
x = xl.toArray(new RestGuard[xl.size()]);
- x = BeanFactory.of(beanFactory, resource)
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(RestGuard[].class, x)
- .createBeanViaMethod(RestGuard[].class, resource,
"createGuards", x);
+ .beanCreateMethodFinder(RestGuard[].class, resource)
+ .find("createGuards", Method.class)
+ .thenFind("createGuards")
+ .withDefault(x)
+ .run();
return x;
}
@@ -842,8 +816,10 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
*/
protected RestMatcher[] createMatchers(Object resource, BeanFactory
beanFactory) throws Exception {
RestMatcher[] x = getInstanceArrayProperty(RESTMETHOD_matchers,
RestMatcher.class, null, beanFactory);
+
if (x == null)
x =
beanFactory.getBean(RestMatcher[].class).orElse(null);
+
if (x == null)
x = new RestMatcher[0];
@@ -851,9 +827,13 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
if (clientVersion != null)
x = ArrayUtils.append(x, new
ClientVersionMatcher(context.getClientVersionHeader(), mi));
- x = BeanFactory.of(beanFactory, resource)
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(RestMatcher[].class, x)
- .createBeanViaMethod(RestMatcher[].class, resource,
"createMatchers", x);
+ .beanCreateMethodFinder(RestMatcher[].class, resource)
+ .find("createMatchers", Method.class)
+ .withDefault(x)
+ .run();
return x;
}
@@ -890,8 +870,10 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
*/
protected EncoderGroup createEncoders(Object resource, BeanFactory
beanFactory) throws Exception {
Encoder[] x = getInstanceArrayProperty(REST_encoders,
Encoder.class, null, beanFactory);
+
if (x == null)
x = beanFactory.getBean(Encoder[].class).orElse(null);
+
if (x == null)
x = new Encoder[0];
@@ -901,9 +883,14 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
.append(x)
.build();
- g = BeanFactory.of(beanFactory, resource)
+ g = BeanFactory
+ .of(beanFactory, resource)
.addBean(EncoderGroup.class, g)
- .createBeanViaMethod(EncoderGroup.class, resource,
"createEncoders", g);
+ .beanCreateMethodFinder(EncoderGroup.class, resource)
+ .find("createEncoders", Method.class)
+ .thenFind("createEncoders")
+ .withDefault(g)
+ .run();
return g;
}
@@ -942,10 +929,13 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
if (g == null) {
Object[] x = getArrayProperty(REST_serializers,
Object.class);
+
if (x == null)
x =
beanFactory.getBean(Serializer[].class).orElse(null);
+
if (x == null)
x = new Serializer[0];
+
g = SerializerGroup
.create()
.append(x)
@@ -953,12 +943,14 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
.build();
}
- g = BeanFactory.of(beanFactory, resource)
- .addBean(SerializerGroup.class, g)
- .createBeanViaMethod(SerializerGroup.class, resource,
"createSerializers", g, Method.class);
- g = BeanFactory.of(beanFactory, resource)
+ g = BeanFactory
+ .of(beanFactory, resource)
.addBean(SerializerGroup.class, g)
- .createBeanViaMethod(SerializerGroup.class, resource,
"createSerializers", g);
+ .beanCreateMethodFinder(SerializerGroup.class, resource)
+ .find("createSerializers", Method.class)
+ .thenFind("createSerializers")
+ .withDefault(g)
+ .run();
return g;
}
@@ -997,10 +989,13 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
if (g == null) {
Object[] x = getArrayProperty(REST_parsers,
Object.class);
+
if (x == null)
x =
beanFactory.getBean(Parser[].class).orElse(null);
+
if (x == null)
x = new Parser[0];
+
g = ParserGroup
.create()
.append(x)
@@ -1008,12 +1003,14 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
.build();
}
- g = BeanFactory.of(beanFactory, resource)
+ g = BeanFactory
+ .of(beanFactory, resource)
.addBean(ParserGroup.class, g)
- .createBeanViaMethod(ParserGroup.class, resource,
"createParsers", g, Method.class);
- g = BeanFactory.of(beanFactory, resource)
- .addBean(ParserGroup.class, g)
- .createBeanViaMethod(ParserGroup.class, resource,
"createParsers", g);
+ .beanCreateMethodFinder(ParserGroup.class, resource)
+ .find("createParsers", Method.class)
+ .thenFind("createParsers")
+ .withDefault(g)
+ .run();
return g;
}
@@ -1050,20 +1047,28 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
*/
protected HttpPartSerializer createPartSerializer(Object resource,
BeanFactory beanFactory, PropertyStore ps) throws Exception {
HttpPartSerializer x = null;
+
if (resource instanceof HttpPartSerializer)
x = (HttpPartSerializer)resource;
+
if (x == null)
x = getInstanceProperty(REST_partSerializer,
HttpPartSerializer.class, null, beanFactory);
+
if (x == null)
x =
beanFactory.getBean(HttpPartSerializer.class).orElse(null);
+
if (x == null)
x = new OpenApiSerializer(ps);
- x = BeanFactory.of(beanFactory, resource)
- .addBean(HttpPartSerializer.class, x)
- .createBeanViaMethod(HttpPartSerializer.class,
resource, "createPartSerializer", x, Method.class);
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(HttpPartSerializer.class, x)
- .createBeanViaMethod(HttpPartSerializer.class,
resource, "createPartSerializer", x);
+ .beanCreateMethodFinder(HttpPartSerializer.class,
resource)
+ .find("createPartSerializer", Method.class)
+ .thenFind("createPartSerializer")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -1099,20 +1104,28 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
*/
protected HttpPartParser createPartParser(Object resource, BeanFactory
beanFactory, PropertyStore ps) throws Exception {
HttpPartParser x = null;
+
if (resource instanceof HttpPartParser)
x = (HttpPartParser)resource;
+
if (x == null)
x = getInstanceProperty(REST_partParser,
HttpPartParser.class, null, beanFactory);
+
if (x == null)
x =
beanFactory.getBean(HttpPartParser.class).orElse(null);
+
if (x == null)
x = new OpenApiParser(ps);
- x = BeanFactory.of(beanFactory, resource)
- .addBean(HttpPartParser.class, x)
- .createBeanViaMethod(HttpPartParser.class, resource,
"createPartParser", x, Method.class);
- x = BeanFactory.of(beanFactory, resource)
+
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(HttpPartParser.class, x)
- .createBeanViaMethod(HttpPartParser.class, resource,
"createPartParser", x);
+ .beanCreateMethodFinder(HttpPartParser.class, resource)
+ .find("createPartParser", Method.class)
+ .thenFind("createPartParser")
+ .withDefault(x)
+ .run();
+
return x;
}
@@ -1128,22 +1141,29 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
*/
protected UrlPathMatcher[] createPathMatchers(Object resource,
BeanFactory beanFactory, boolean dotAll) throws Exception {
List<UrlPathMatcher> x = AList.of();
+
for (String p : getArrayProperty(RESTMETHOD_paths,
String.class)) {
if (dotAll && ! p.endsWith("/*"))
p += "/*";
x.add(UrlPathMatcher.of(p));
}
+
if (x.isEmpty()) {
String p = HttpUtils.detectHttpPath(method, true);
if (dotAll && ! p.endsWith("/*"))
p += "/*";
x.add(UrlPathMatcher.of(p));
}
+
UrlPathMatcher[] x2 = x.toArray(new UrlPathMatcher[x.size()]);;
- x2 = BeanFactory.of(beanFactory, resource)
+ x2 = BeanFactory
+ .of(beanFactory, resource)
.addBean(UrlPathMatcher[].class, x2)
- .createBeanViaMethod(UrlPathMatcher[].class, resource,
"createPathMatchers", x2, Method.class);
+ .beanCreateMethodFinder(UrlPathMatcher[].class,
resource)
+ .find("createPathMatchers", Method.class)
+ .withDefault(x2)
+ .run();
return x2;
}
@@ -1159,23 +1179,154 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
*/
protected JsonSchemaGenerator createJsonSchemaGenerator(Object
resource, BeanFactory beanFactory, PropertyStore ps) throws Exception {
JsonSchemaGenerator x = null;
+
if (resource instanceof JsonSchemaGenerator)
x = (JsonSchemaGenerator)resource;
+
if (x == null)
x =
beanFactory.getBean(JsonSchemaGenerator.class).orElse(null);
+
if (x == null)
x = JsonSchemaGenerator.create().apply(ps).build();
- x = BeanFactory.of(beanFactory, resource)
+ x = BeanFactory
+ .of(beanFactory, resource)
.addBean(JsonSchemaGenerator.class, x)
- .createBeanViaMethod(JsonSchemaGenerator.class,
resource, "createJsonSchemaGenerator", x, Method.class);
- x = BeanFactory.of(beanFactory, resource)
- .addBean(JsonSchemaGenerator.class, x)
- .createBeanViaMethod(JsonSchemaGenerator.class,
resource, "createJsonSchemaGenerator", x);
+ .beanCreateMethodFinder(JsonSchemaGenerator.class,
resource)
+ .find("createJsonSchemaGenerator", Method.class)
+ .thenFind("createJsonSchemaGenerator")
+ .withDefault(x)
+ .run();
return x;
}
+ /**
+ * Instantiates the default request headers for this method.
+ *
+ * @param resource The REST resource object.
+ * @param beanFactory The bean factory to use for retrieving and
creating beans.
+ * @param method This Java method.
+ * @return The default request headers for this method.
+ * @throws Exception If default request headers could not be
instantiated.
+ */
+ protected org.apache.http.Header[] createDefaultRequestHeaders(Object
resource, BeanFactory beanFactory, Method method) throws Exception {
+ Map<String,Object> x = new
TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ x.putAll(getMapProperty(RESTMETHOD_reqHeaders, Object.class));
+
+ for (Annotation[] aa : method.getParameterAnnotations()) {
+ for (Annotation a : aa) {
+ if (a instanceof Header) {
+ Header h = (Header)a;
+ String def =
joinnlFirstNonEmptyArray(h._default(), h.df());
+ if (def != null) {
+ try {
+
x.put(firstNonEmpty(h.name(), h.n(), h.value()), parseAnything(def));
+ } catch (ParseException e) {
+ throw new
ConfigException(e, "Malformed @Header annotation");
+ }
+ }
+ }
+ }
+ }
+
+ org.apache.http.Header[] x2 =
x.entrySet().stream().map(e->BasicHeader.of(e.getKey(),e.getValue())).toArray(org.apache.http.Header[]::new);
+
+ x2 = BeanFactory
+ .of(beanFactory, resource)
+ .addBean(org.apache.http.Header[].class, x2)
+ .beanCreateMethodFinder(org.apache.http.Header[].class,
resource)
+ .find("createDefaultRequestHeaders", Method.class)
+ .thenFind("createDefaultRequestHeaders")
+ .withDefault(x2)
+ .run();
+
+ return x2;
+ }
+
+ /**
+ * Instantiates the default query parameters for this method.
+ *
+ * @param resource The REST resource object.
+ * @param beanFactory The bean factory to use for retrieving and
creating beans.
+ * @param method This Java method.
+ * @return The default request query parameters for this method.
+ * @throws Exception If default request query parameters could not be
instantiated.
+ */
+ protected NameValuePair[] createDefaultRequestQuery(Object resource,
BeanFactory beanFactory, Method method) throws Exception {
+ Map<String,Object> x = new
LinkedHashMap<>(getMapProperty(RESTMETHOD_defaultQuery, Object.class));
+
+ for (Annotation[] aa : method.getParameterAnnotations()) {
+ for (Annotation a : aa) {
+ if (a instanceof Query) {
+ Query h = (Query)a;
+ String def =
joinnlFirstNonEmptyArray(h._default(), h.df());
+ if (def != null) {
+ try {
+
x.put(firstNonEmpty(h.name(), h.n(), h.value()), parseAnything(def));
+ } catch (ParseException e) {
+ throw new
ConfigException(e, "Malformed @Query annotation");
+ }
+ }
+ }
+ }
+ }
+
+ NameValuePair[] x2 =
x.entrySet().stream().map(e->BasicNameValuePair.of(e.getKey(),e.getValue())).toArray(NameValuePair[]::new);
+
+ x2 = BeanFactory
+ .of(beanFactory, resource)
+ .addBean(NameValuePair[].class, x2)
+ .beanCreateMethodFinder(NameValuePair[].class, resource)
+ .find("createDefaultRequestQuery", Method.class)
+ .thenFind("createDefaultRequestQuery")
+ .withDefault(x2)
+ .run();
+
+ return x2;
+ }
+
+ /**
+ * Instantiates the default form-data parameters for this method.
+ *
+ * @param resource The REST resource object.
+ * @param beanFactory The bean factory to use for retrieving and
creating beans.
+ * @param method This Java method.
+ * @return The default request form-data parameters for this method.
+ * @throws Exception If default request form-data parameters could not
be instantiated.
+ */
+ protected NameValuePair[] createDefaultRequestFormData(Object resource,
BeanFactory beanFactory, Method method) throws Exception {
+ Map<String,Object> x = new
LinkedHashMap<>(getMapProperty(RESTMETHOD_defaultFormData, Object.class));
+
+ for (Annotation[] aa : method.getParameterAnnotations()) {
+ for (Annotation a : aa) {
+ if (a instanceof FormData) {
+ FormData h = (FormData)a;
+ String def =
joinnlFirstNonEmptyArray(h._default(), h.df());
+ if (def != null) {
+ try {
+
x.put(firstNonEmpty(h.name(), h.n(), h.value()), parseAnything(def));
+ } catch (ParseException e) {
+ throw new
ConfigException(e, "Malformed @FormData annotation");
+ }
+ }
+ }
+ }
+ }
+
+ NameValuePair[] x2 =
x.entrySet().stream().map(e->BasicNameValuePair.of(e.getKey(),e.getValue())).toArray(NameValuePair[]::new);
+
+ x2 = BeanFactory
+ .of(beanFactory, resource)
+ .addBean(NameValuePair[].class, x2)
+ .beanCreateMethodFinder(NameValuePair[].class, resource)
+ .find("createDefaultRequestFormData", Method.class)
+ .thenFind("createDefaultRequestFormData")
+ .withDefault(x2)
+ .run();
+
+ return x2;
+ }
ResponsePartMeta getResponseHeaderMeta(Object o) {
if (o == null)
@@ -1568,9 +1719,9 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
public OMap toMap() {
return super.toMap()
.a("RestMethodContext", new DefaultFilteringOMap()
- .a("defaultFormData", defaultFormData)
- .a("defaultQuery", defaultQuery)
- .a("reqHeaders", reqHeaders)
+ .a("defaultRequestFormData",
defaultRequestFormData)
+ .a("defaultRequestHeaders",
defaultRequestHeaders)
+ .a("defaultRequestQuery", defaultRequestQuery)
.a("httpMethod", httpMethod)
.a("priority", priority)
);
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
index 5f3bc76..c9e325c 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -34,6 +34,7 @@ import java.util.logging.*;
import javax.servlet.*;
import javax.servlet.http.*;
+import org.apache.http.*;
import org.apache.juneau.*;
import org.apache.juneau.config.*;
import org.apache.juneau.cp.*;
@@ -202,10 +203,10 @@ public final class RestRequest extends
HttpServletRequestWrapper {
this.pathParams
.parser(partParserSession);
this.queryParams
- .addDefault(rjm.defaultQuery)
+ .addDefault(rjm.defaultRequestQuery)
.parser(partParserSession);
this.headers
- .addDefault(rjm.reqHeaders)
+ .addDefault(rjm.defaultRequestHeaders)
.addDefault(context.getReqHeaders())
.parser(partParserSession);
this.attrs = new RequestAttributes(this, rjm.reqAttrs);
@@ -605,7 +606,8 @@ public final class RestRequest extends
HttpServletRequestWrapper {
}
}
}
- formData.addDefault(restJavaMethod == null ? null :
restJavaMethod.defaultFormData);
+ if (restJavaMethod != null)
+
formData.addDefault(restJavaMethod.defaultRequestFormData);
return formData;
} catch (Exception e) {
throw new InternalServerError(e);