You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2018/11/21 20:10:43 UTC
[juneau] branch master updated: Allow RestResourceResolver to
resolve all beans in RestServlet.
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 9d2c50f Allow RestResourceResolver to resolve all beans in RestServlet.
9d2c50f is described below
commit 9d2c50ff9e95ce5bbf74d692dd2a774c31ec6bd8
Author: JamesBognar <ja...@apache.org>
AuthorDate: Wed Nov 21 15:10:30 2018 -0500
Allow RestResourceResolver to resolve all beans in RestServlet.
---
.../org/apache/juneau/BasicResourceResolver.java | 28 +++------
.../src/main/java/org/apache/juneau/Context.java | 40 +++++--------
.../org/apache/juneau/FuzzyResourceResolver.java | 28 +++------
.../main/java/org/apache/juneau/PropertyStore.java | 69 ++++++++++++----------
.../java/org/apache/juneau/ResourceResolver.java | 51 +++++++++-------
juneau-doc/docs/ReleaseNotes/8.0.0.html | 3 +
.../springboot/SpringRestResourceResolver.java | 6 +-
.../org/apache/juneau/rest/client/RestClient.java | 4 +-
.../juneau/rest/BasicRestResourceResolver.java | 14 ++---
.../java/org/apache/juneau/rest/RestContext.java | 30 +++++-----
.../org/apache/juneau/rest/RestContextBuilder.java | 2 +-
.../apache/juneau/rest/RestResourceResolver.java | 6 +-
12 files changed, 132 insertions(+), 149 deletions(-)
diff --git a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicResourceResolver.java
similarity index 68%
copy from juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicResourceResolver.java
index 029ef85..d3839ec 100644
--- a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicResourceResolver.java
@@ -10,31 +10,21 @@
// * "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.examples.rest.springboot;
+package org.apache.juneau;
-import org.apache.juneau.rest.*;
-import org.springframework.context.ApplicationContext;
+import org.apache.juneau.internal.*;
/**
- * Implementation of a {@link RestResourceResolver} for resolving REST resources using Spring.
+ * Basic implementation of a resource resolver.
*/
-public class SpringRestResourceResolver extends BasicRestResourceResolver {
+public class BasicResourceResolver implements ResourceResolver {
- private ApplicationContext appContext;
-
- public SpringRestResourceResolver(ApplicationContext appContext) {
- this.appContext = appContext;
- }
-
- @Override
- public Object resolve(Object parent, Class<?> type, RestContextBuilder builder) throws Exception {
+ @Override /* ResourceResolver */
+ public <T> T resolve(Object parent, Class<T> c, Object...args) {
try {
- Object o = appContext.getBean(type);
- if (o != null)
- return o;
- } catch(Exception e) {
- // Ignore
+ return ClassUtils.newInstanceFromOuter(parent, c, c, false, args);
+ } catch (Exception e) {
+ throw new BeanRuntimeException(e, c, "Could not instantiate resource class");
}
- return super.resolve(parent, type, builder);
}
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index b8eab62..73dc315 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -337,17 +337,15 @@ public abstract class Context {
* @param def
* The default value if the property doesn't exist.
* <br>Can either be an instance of <code>T</code>, or a <code>Class<? <jk>extends</jk> T></code>.
- * @param fuzzyArgs
- * Use fuzzy constructor arg matching.
- * <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
- * <br>No-arg constructors are also used if no other constructors are found.
+ * @param resolver
+ * The resolver to use for instantiating objects.
* @param args
* Arguments to pass to the constructor.
* Constructors matching the arguments are always used before no-arg constructors.
* @return A new property instance.
*/
- public <T> T getInstanceProperty(String key, Class<T> type, Object def, boolean fuzzyArgs, Object...args) {
- return propertyStore.getInstanceProperty(key, type, def, fuzzyArgs, args);
+ public <T> T getInstanceProperty(String key, Class<T> type, Object def, ResourceResolver resolver, Object...args) {
+ return propertyStore.getInstanceProperty(key, type, def, resolver, args);
}
/**
@@ -359,17 +357,15 @@ public abstract class Context {
* @param def
* The default value if the property doesn't exist.
* <br>Can either be an instance of <code>T</code>, or a <code>Class<? <jk>extends</jk> T></code>.
- * @param fuzzyArgs
- * Use fuzzy constructor arg matching.
- * <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
- * <br>No-arg constructors are also used if no other constructors are found.
+ * @param resolver
+ * The resolver to use for instantiating objects.
* @param args
* Arguments to pass to the constructor.
* Constructors matching the arguments are always used before no-arg constructors.
* @return A new property instance.
*/
- public <T> T getInstanceProperty(String key, Object outer, Class<T> type, Object def, boolean fuzzyArgs, Object...args) {
- return propertyStore.getInstanceProperty(key, outer, type, def, fuzzyArgs, args);
+ public <T> T getInstanceProperty(String key, Object outer, Class<T> type, Object def, ResourceResolver resolver, Object...args) {
+ return propertyStore.getInstanceProperty(key, outer, type, def, resolver, args);
}
/**
@@ -390,17 +386,15 @@ public abstract class Context {
* @param key The property name.
* @param type The class type of the property.
* @param def The default object to return if the property doesn't exist.
- * @param fuzzyArgs
- * Use fuzzy constructor arg matching.
- * <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
- * <br>No-arg constructors are also used if no other constructors are found.
+ * @param resolver
+ * The resolver to use for instantiating objects.
* @param args
* Arguments to pass to the constructor.
* Constructors matching the arguments are always used before no-arg constructors.
* @return A new property instance.
*/
- public <T> T[] getInstanceArrayProperty(String key, Class<T> type, T[] def, boolean fuzzyArgs, Object...args) {
- return propertyStore.getInstanceArrayProperty(key, type, def, fuzzyArgs, args);
+ public <T> T[] getInstanceArrayProperty(String key, Class<T> type, T[] def, ResourceResolver resolver, Object...args) {
+ return propertyStore.getInstanceArrayProperty(key, type, def, resolver, args);
}
/**
@@ -410,17 +404,15 @@ public abstract class Context {
* @param outer The outer object if the class we're instantiating is an inner class.
* @param type The class type of the property.
* @param def The default object to return if the property doesn't exist.
- * @param fuzzyArgs
- * Use fuzzy constructor arg matching.
- * <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
- * <br>No-arg constructors are also used if no other constructors are found.
+ * @param resolver
+ * The resolver to use for instantiating objects.
* @param args
* Arguments to pass to the constructor.
* Constructors matching the arguments are always used before no-arg constructors.
* @return A new property instance.
*/
- public <T> T[] getInstanceArrayProperty(String key, Object outer, Class<T> type, T[] def, boolean fuzzyArgs, Object...args) {
- return propertyStore.getInstanceArrayProperty(key, outer, type, def, fuzzyArgs, args);
+ public <T> T[] getInstanceArrayProperty(String key, Object outer, Class<T> type, T[] def, ResourceResolver resolver, Object...args) {
+ return propertyStore.getInstanceArrayProperty(key, outer, type, def, resolver, args);
}
/**
diff --git a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/FuzzyResourceResolver.java
similarity index 68%
copy from juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/FuzzyResourceResolver.java
index 029ef85..c5abed3 100644
--- a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/FuzzyResourceResolver.java
@@ -10,31 +10,21 @@
// * "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.examples.rest.springboot;
+package org.apache.juneau;
-import org.apache.juneau.rest.*;
-import org.springframework.context.ApplicationContext;
+import org.apache.juneau.internal.*;
/**
- * Implementation of a {@link RestResourceResolver} for resolving REST resources using Spring.
+ * Basic implementation of a resource resolver.
*/
-public class SpringRestResourceResolver extends BasicRestResourceResolver {
+public class FuzzyResourceResolver implements ResourceResolver {
- private ApplicationContext appContext;
-
- public SpringRestResourceResolver(ApplicationContext appContext) {
- this.appContext = appContext;
- }
-
- @Override
- public Object resolve(Object parent, Class<?> type, RestContextBuilder builder) throws Exception {
+ @Override /* ResourceResolver */
+ public <T> T resolve(Object parent, Class<T> c, Object...args) {
try {
- Object o = appContext.getBean(type);
- if (o != null)
- return o;
- } catch(Exception e) {
- // Ignore
+ return ClassUtils.newInstanceFromOuter(parent, c, c, true, args);
+ } catch (Exception e) {
+ throw new BeanRuntimeException(e, c, "Could not instantiate resource class ''{0}''");
}
- return super.resolve(parent, type, builder);
}
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
index 354736a..7189e8f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
@@ -489,7 +489,7 @@ public final class PropertyStore {
* @return A new property instance.
*/
public <T> T getInstanceProperty(String key, Class<T> type, Object def) {
- return getInstanceProperty(key, type, def, false);
+ return getInstanceProperty(key, type, def, ResourceResolver.BASIC);
}
/**
@@ -500,17 +500,15 @@ public final class PropertyStore {
* @param def
* The default value if the property doesn't exist.
* <br>Can either be an instance of <code>T</code>, or a <code>Class<? <jk>extends</jk> T></code>.
- * @param fuzzyArgs
- * Use fuzzy constructor arg matching.
- * <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
- * <br>No-arg constructors are also used if no other constructors are found.
+ * @param resolver
+ * The resolver to use for instantiating objects.
* @param args
* Arguments to pass to the constructor.
* Constructors matching the arguments are always used before no-arg constructors.
* @return A new property instance.
*/
- public <T> T getInstanceProperty(String key, Class<T> type, Object def, boolean fuzzyArgs, Object...args) {
- return getInstanceProperty(key, null, type, def, fuzzyArgs, args);
+ public <T> T getInstanceProperty(String key, Class<T> type, Object def, ResourceResolver resolver, Object...args) {
+ return getInstanceProperty(key, null, type, def, resolver, args);
}
/**
@@ -522,23 +520,21 @@ public final class PropertyStore {
* @param def
* The default value if the property doesn't exist.
* <br>Can either be an instance of <code>T</code>, or a <code>Class<? <jk>extends</jk> T></code>.
- * @param fuzzyArgs
- * Use fuzzy constructor arg matching.
- * <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
- * <br>No-arg constructors are also used if no other constructors are found.
+ * @param resolver
+ * The resolver to use for instantiating objects.
* @param args
* Arguments to pass to the constructor.
* Constructors matching the arguments are always used before no-arg constructors.
* @return A new property instance.
*/
- public <T> T getInstanceProperty(String key, Object outer, Class<T> type, Object def, boolean fuzzyArgs, Object...args) {
+ public <T> T getInstanceProperty(String key, Object outer, Class<T> type, Object def, ResourceResolver resolver, Object...args) {
Property p = findProperty(key);
if (p != null)
- return p.asInstance(outer, type, fuzzyArgs, args);
+ return p.asInstance(outer, type, resolver, args);
if (def == null)
return null;
if (def instanceof Class)
- return ClassUtils.newInstance(type, def, fuzzyArgs, args);
+ return resolver.resolve(outer, (Class<T>)def, args);
if (type.isInstance(def))
return (T)def;
throw new ConfigException("Could not instantiate property ''{0}'' as type ''{1}'' with default value ''{2}''", key, type, def);
@@ -553,7 +549,7 @@ public final class PropertyStore {
* @return A new property instance.
*/
public <T> T[] getInstanceArrayProperty(String key, Class<T> type, T[] def) {
- return getInstanceArrayProperty(key, type, def, false);
+ return getInstanceArrayProperty(key, type, def, ResourceResolver.BASIC);
}
/**
@@ -562,17 +558,15 @@ public final class PropertyStore {
* @param key The property name.
* @param type The class type of the property.
* @param def The default object to return if the property doesn't exist.
- * @param fuzzyArgs
- * Use fuzzy constructor arg matching.
- * <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
- * <br>No-arg constructors are also used if no other constructors are found.
+ * @param resolver
+ * The resolver to use for instantiating objects.
* @param args
* Arguments to pass to the constructor.
* Constructors matching the arguments are always used before no-arg constructors.
* @return A new property instance.
*/
- public <T> T[] getInstanceArrayProperty(String key, Class<T> type, T[] def, boolean fuzzyArgs, Object...args) {
- return getInstanceArrayProperty(key, null, type, def, fuzzyArgs, args);
+ public <T> T[] getInstanceArrayProperty(String key, Class<T> type, T[] def, ResourceResolver resolver, Object...args) {
+ return getInstanceArrayProperty(key, null, type, def, resolver, args);
}
/**
@@ -582,18 +576,16 @@ public final class PropertyStore {
* @param outer The outer object if the class we're instantiating is an inner class.
* @param type The class type of the property.
* @param def The default object to return if the property doesn't exist.
- * @param fuzzyArgs
- * Use fuzzy constructor arg matching.
- * <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
- * <br>No-arg constructors are also used if no other constructors are found.
+ * @param resolver
+ * The resolver to use for instantiating objects.
* @param args
* Arguments to pass to the constructor.
* Constructors matching the arguments are always used before no-arg constructors.
* @return A new property instance.
*/
- public <T> T[] getInstanceArrayProperty(String key, Object outer, Class<T> type, T[] def, boolean fuzzyArgs, Object...args) {
+ public <T> T[] getInstanceArrayProperty(String key, Object outer, Class<T> type, T[] def, ResourceResolver resolver, Object...args) {
Property p = findProperty(key);
- return p == null ? def : p.asInstanceArray(outer, type, fuzzyArgs, args);
+ return p == null ? def : p.asInstanceArray(outer, type, resolver, args);
}
/**
@@ -859,15 +851,20 @@ public final class PropertyStore {
}
}
- public <T> T asInstance(Object outer, Class<T> iType, boolean fuzzyArgs, Object...args) {
+ public <T> T asInstance(Object outer, Class<T> iType, ResourceResolver resolver, Object...args) {
+ if (value == null)
+ return null;
if (type == STRING)
return ClassUtils.fromString(iType, value.toString());
- else if (type == OBJECT || type == CLASS)
- return ClassUtils.newInstanceFromOuter(outer, iType, value, fuzzyArgs, args);
+ else if (type == OBJECT || type == CLASS) {
+ T t = instantiate(resolver, outer, iType, value, args);
+ if (t != null)
+ return t;
+ }
throw new ConfigException("Invalid property instantiation ''{0}'' to ''{1}'' on property ''{2}''", type, iType, name);
}
- public <T> T[] asInstanceArray(Object outer, Class<T> eType, boolean fuzzyArgs, Object...args) {
+ public <T> T[] asInstanceArray(Object outer, Class<T> eType, ResourceResolver resolver, Object...args) {
if (value instanceof Collection) {
Collection<?> l = (Collection<?>)value;
Object t = Array.newInstance(eType, l.size());
@@ -879,7 +876,7 @@ public final class PropertyStore {
else if (type == SET_STRING || type == LIST_STRING)
o2 = ClassUtils.fromString(eType, o.toString());
else if (type == SET_CLASS || type == LIST_CLASS || type == LIST_OBJECT)
- o2 = ClassUtils.newInstanceFromOuter(outer, eType, o, fuzzyArgs, args);
+ o2 = instantiate(resolver, outer, eType, o, args);
if (o2 == null)
throw new ConfigException("Invalid property conversion ''{0}'' to ''{1}[]'' on property ''{2}''", type, eType, name);
Array.set(t, i++, o2);
@@ -910,6 +907,14 @@ public final class PropertyStore {
// Utility methods
//-------------------------------------------------------------------------------------------------------------------
+ static <T> T instantiate(ResourceResolver resolver, Object outer, Class<T> c, Object value, Object...args) {
+ if (ClassUtils.isParentClass(c, value.getClass()))
+ return (T)value;
+ if (ClassUtils.isParentClass(Class.class, value.getClass()))
+ return resolver.resolve(outer, (Class<T>)value, args);
+ return null;
+ }
+
private static String group(String key) {
if (key == null || key.indexOf('.') == -1 || key.charAt(key.length()-1) == '.')
throw new ConfigException("Invalid property name specified: ''{0}''", key);
diff --git a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ResourceResolver.java
similarity index 59%
copy from juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ResourceResolver.java
index 029ef85..a96c864 100644
--- a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ResourceResolver.java
@@ -10,31 +10,38 @@
// * "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.examples.rest.springboot;
-
-import org.apache.juneau.rest.*;
-import org.springframework.context.ApplicationContext;
+package org.apache.juneau;
/**
- * Implementation of a {@link RestResourceResolver} for resolving REST resources using Spring.
+ * Class used to resolve {@link Class} objects to instances.
*/
-public class SpringRestResourceResolver extends BasicRestResourceResolver {
-
- private ApplicationContext appContext;
+public interface ResourceResolver {
+
+ /**
+ * Look for constructors where the arguments passed in must match exactly.
+ */
+ public static final ResourceResolver BASIC = new BasicResourceResolver();
- public SpringRestResourceResolver(ApplicationContext appContext) {
- this.appContext = appContext;
- }
+ /**
+ * Look for constructors where arguments may or may not exist in any order.
+ */
+ public static final ResourceResolver FUZZY = new FuzzyResourceResolver();
- @Override
- public Object resolve(Object parent, Class<?> type, RestContextBuilder builder) throws Exception {
- try {
- Object o = appContext.getBean(type);
- if (o != null)
- return o;
- } catch(Exception e) {
- // Ignore
- }
- return super.resolve(parent, type, builder);
- }
+ /**
+ * Resolves the specified class to a resource object.
+ *
+ * <p>
+ * Subclasses can override this method to provide their own custom resolution.
+ *
+ * <p>
+ * The default implementation simply creates a new class instance using {@link Class#newInstance()}.
+ *
+ * @param parent
+ * The parent resource.
+ * @param c The class to resolve.
+ * @param builder The initialization configuration for the resource.
+ * @param args Optional arguments to pass to constructor
+ * @return The instance of that class.
+ */
+ <T> T resolve(Object parent, Class<T> c, Object...args);
}
diff --git a/juneau-doc/docs/ReleaseNotes/8.0.0.html b/juneau-doc/docs/ReleaseNotes/8.0.0.html
index 0f19fb2..e3a314d 100644
--- a/juneau-doc/docs/ReleaseNotes/8.0.0.html
+++ b/juneau-doc/docs/ReleaseNotes/8.0.0.html
@@ -39,6 +39,9 @@
<li class='jm'>{@link oajr.RestServlet#setRestResourceResolver(RestResourceResolver) setRestResourceResolver(RestResourceResolver)}
<li class='jm'>{@link oajr.RestServlet#getPath() getPath()}
</ul>
+ <li>
+ The registered resource resolver is now used to instantiate objects of classes defined via <ja>@RestResource</ja>.
+ <br>This allows for any of those instance to be injectable beans.
</ul>
<h5 class='topic w800'>juneau-microservice-server</h5>
diff --git a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java b/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
index 029ef85..1a12c1c 100644
--- a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
+++ b/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/SpringRestResourceResolver.java
@@ -27,12 +27,12 @@ public class SpringRestResourceResolver extends BasicRestResourceResolver {
}
@Override
- public Object resolve(Object parent, Class<?> type, RestContextBuilder builder) throws Exception {
+ public <T> T resolve(Object parent, Class<T> type, RestContextBuilder builder, Object...args) {
try {
- Object o = appContext.getBean(type);
+ T o = appContext.getBean(type);
if (o != null)
return o;
- } catch(Exception e) {
+ } catch (Exception e) {
// Ignore
}
return super.resolve(parent, type, builder);
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index bae6b20..e47b84f 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -520,8 +520,8 @@ public class RestClient extends BeanContext implements Closeable {
}
this.urlEncodingSerializer = new SerializerBuilder(ps).build(UrlEncodingSerializer.class);
- this.partSerializer = getInstanceProperty(RESTCLIENT_partSerializer, HttpPartSerializer.class, OpenApiSerializer.class, true, ps);
- this.partParser = getInstanceProperty(RESTCLIENT_partParser, HttpPartParser.class, OpenApiParser.class, true, ps);
+ this.partSerializer = getInstanceProperty(RESTCLIENT_partSerializer, HttpPartSerializer.class, OpenApiSerializer.class, ResourceResolver.FUZZY, ps);
+ this.partParser = getInstanceProperty(RESTCLIENT_partParser, HttpPartParser.class, OpenApiParser.class, ResourceResolver.FUZZY, ps);
this.executorService = getInstanceProperty(RESTCLIENT_executorService, ExecutorService.class, null);
RestCallInterceptor[] rci = getInstanceArrayProperty(RESTCLIENT_interceptors, RestCallInterceptor.class, new RestCallInterceptor[0]);
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestResourceResolver.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestResourceResolver.java
index 2b377ed..110f412 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestResourceResolver.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestResourceResolver.java
@@ -12,6 +12,7 @@
// ***************************************************************************************************************************
package org.apache.juneau.rest;
+import org.apache.juneau.*;
import org.apache.juneau.internal.*;
/**
@@ -36,17 +37,10 @@ import org.apache.juneau.internal.*;
* <li class='link'>{@doc juneau-rest-server.Instantiation.ResourceResolvers}
* </ul>
*/
-public class BasicRestResourceResolver implements RestResourceResolver {
+public class BasicRestResourceResolver extends FuzzyResourceResolver implements RestResourceResolver {
@Override /* RestResourceResolver */
- public Object resolve(Object parent, Class<?> c, RestContextBuilder builder) throws Exception {
- try {
- Object r = ClassUtils.newInstanceFromOuter(parent, Object.class, c, true, builder);
- if (r != null)
- return r;
- } catch (Exception e) {
- throw new RestServletException("Could not instantiate resource class ''{0}''", c.getName()).initCause(e);
- }
- throw new RestServletException("Could not find public constructor for class ''{0}''.", c);
+ public <T> T resolve(Object parent, Class<T> c, RestContextBuilder builder, Object...args) {
+ return resolve(parent, c, ArrayUtils.append(args, builder));
}
}
\ No newline at end of file
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 159b1e6..e1967df 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
@@ -3095,6 +3095,7 @@ public final class RestContext extends BeanContext {
this.resource = builder.resource;
this.builder = builder;
this.parentContext = builder.parentContext;
+ resourceResolver = getInstanceProperty(REST_resourceResolver, resource, RestResourceResolver.class, parentContext == null ? BasicRestResourceResolver.class : parentContext.resourceResolver, ResourceResolver.FUZZY, this);
PropertyStore ps = getPropertyStore().builder().add(builder.properties).build();
Class<?> resourceClass = resource.getClass();
@@ -3114,12 +3115,12 @@ public final class RestContext extends BeanContext {
maxInput = getLongProperty(REST_maxInput, 100_000_000l);
clientVersionHeader = getStringProperty(REST_clientVersionHeader, "X-Client-Version");
- converters = getInstanceArrayProperty(REST_converters, resource, RestConverter.class, new RestConverter[0], true, this);
- guards = getInstanceArrayProperty(REST_guards, resource, RestGuard.class, new RestGuard[0], true, this);
- responseHandlers = getInstanceArrayProperty(REST_responseHandlers, resource, ResponseHandler.class, new ResponseHandler[0], true, this);
+ converters = getInstanceArrayProperty(REST_converters, resource, RestConverter.class, new RestConverter[0], resourceResolver, this);
+ guards = getInstanceArrayProperty(REST_guards, resource, RestGuard.class, new RestGuard[0], resourceResolver, this);
+ responseHandlers = getInstanceArrayProperty(REST_responseHandlers, resource, ResponseHandler.class, new ResponseHandler[0], resourceResolver, this);
Map<Class<?>,RestMethodParam> _paramResolvers = new HashMap<>();
- for (RestMethodParam rp : getInstanceArrayProperty(REST_paramResolvers, RestMethodParam.class, new RestMethodParam[0], true, this))
+ for (RestMethodParam rp : getInstanceArrayProperty(REST_paramResolvers, RestMethodParam.class, new RestMethodParam[0], resourceResolver, this))
_paramResolvers.put(rp.forClass(), rp);
paramResolvers = unmodifiableMap(_paramResolvers);
@@ -3130,7 +3131,7 @@ public final class RestContext extends BeanContext {
defaultResponseHeaders = getMapProperty(REST_defaultResponseHeaders, Object.class);
staticFileResponseHeaders = getMapProperty(REST_staticFileResponseHeaders, Object.class);
- logger = getInstanceProperty(REST_logger, resource, RestLogger.class, NoOpRestLogger.class, true, this);
+ logger = getInstanceProperty(REST_logger, resource, RestLogger.class, NoOpRestLogger.class, resourceResolver, this);
if (debug)
logger.setLevel(Level.FINE);
@@ -3158,18 +3159,18 @@ public final class RestContext extends BeanContext {
config = builder.config.resolving(this.varResolver.createSession());
properties = builder.properties;
- serializers = SerializerGroup.create().append(getInstanceArrayProperty(REST_serializers, Serializer.class, new Serializer[0], true, resource, ps)).build();
- parsers = ParserGroup.create().append(getInstanceArrayProperty(REST_parsers, Parser.class, new Parser[0], true, resource, ps)).build();
- partSerializer = getInstanceProperty(REST_partSerializer, HttpPartSerializer.class, OpenApiSerializer.class, true, resource, ps);
- partParser = getInstanceProperty(REST_partParser, HttpPartParser.class, OpenApiParser.class, true, resource, ps);
- encoders = new EncoderGroupBuilder().append(getInstanceArrayProperty(REST_encoders, Encoder.class, new Encoder[0], true, resource, ps)).build();
+ serializers = SerializerGroup.create().append(getInstanceArrayProperty(REST_serializers, Serializer.class, new Serializer[0], resourceResolver, resource, ps)).build();
+ parsers = ParserGroup.create().append(getInstanceArrayProperty(REST_parsers, Parser.class, new Parser[0], resourceResolver, resource, ps)).build();
+ partSerializer = getInstanceProperty(REST_partSerializer, HttpPartSerializer.class, OpenApiSerializer.class, resourceResolver, resource, ps);
+ partParser = getInstanceProperty(REST_partParser, HttpPartParser.class, OpenApiParser.class, resourceResolver, resource, ps);
+ encoders = new EncoderGroupBuilder().append(getInstanceArrayProperty(REST_encoders, Encoder.class, new Encoder[0], resourceResolver, resource, ps)).build();
beanContext = BeanContext.create().apply(ps).build();
mimetypesFileTypeMap = new ExtendedMimetypesFileTypeMap();
for (String mimeType : getArrayProperty(REST_mimeTypes, String.class))
mimetypesFileTypeMap.addMimeTypes(mimeType);
- ClasspathResourceFinder rf = getInstanceProperty(REST_classpathResourceFinder, ClasspathResourceFinder.class, ClasspathResourceFinderBasic.class, true, this);
+ ClasspathResourceFinder rf = getInstanceProperty(REST_classpathResourceFinder, ClasspathResourceFinder.class, ClasspathResourceFinderBasic.class, resourceResolver, this);
useClasspathResourceCaching = getProperty(REST_useClasspathResourceCaching, boolean.class, true);
staticResourceManager = new ClasspathResourceManager(resourceClass, rf, useClasspathResourceCaching);
@@ -3196,7 +3197,7 @@ public final class RestContext extends BeanContext {
this.childResources = Collections.synchronizedMap(new LinkedHashMap<String,RestContext>()); // Not unmodifiable on purpose so that children can be replaced.
Map<String,Widget> _widgets = new LinkedHashMap<>();
- for (Widget w : getInstanceArrayProperty(REST_widgets, resource, Widget.class, new Widget[0], true, ps))
+ for (Widget w : getInstanceArrayProperty(REST_widgets, resource, Widget.class, new Widget[0], resourceResolver, ps))
_widgets.put(w.getName(), w);
this.widgets = unmodifiableMap(_widgets);
@@ -3398,7 +3399,6 @@ public final class RestContext extends BeanContext {
this.callRouters = unmodifiableMap(_callRouters);
// Initialize our child resources.
- resourceResolver = getInstanceProperty(REST_resourceResolver, resource, RestResourceResolver.class, parentContext == null ? BasicRestResourceResolver.class : parentContext.resourceResolver, true, this);
for (Object o : getArrayProperty(REST_children, Object.class)) {
String path = null;
Object r = null;
@@ -3438,8 +3438,8 @@ public final class RestContext extends BeanContext {
childResources.put(path, rc2);
}
- callHandler = getInstanceProperty(REST_callHandler, resource, RestCallHandler.class, BasicRestCallHandler.class, true, this);
- infoProvider = getInstanceProperty(REST_infoProvider, resource, RestInfoProvider.class, BasicRestInfoProvider.class, true, this);
+ callHandler = getInstanceProperty(REST_callHandler, resource, RestCallHandler.class, BasicRestCallHandler.class, resourceResolver, this);
+ infoProvider = getInstanceProperty(REST_infoProvider, resource, RestInfoProvider.class, BasicRestInfoProvider.class, resourceResolver, this);
} catch (RestException e) {
_initException = e;
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 7c66905..dfaab03 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
@@ -280,7 +280,7 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
// We want to do that here so that we can update the script/style properties while they're still modifiable.
HtmlDocBuilder hdb = getHtmlDocBuilder();
PropertyStore ps = getPropertyStore();
- Widget[] widgets = ps.getInstanceArrayProperty(REST_widgets, Widget.class, new Widget[0], true, ps, resource);
+ Widget[] widgets = ps.getInstanceArrayProperty(REST_widgets, Widget.class, new Widget[0], ResourceResolver.FUZZY, ps, resource);
for (Widget w : widgets) {
hdb.script("INHERIT", "$W{"+w.getName()+".script}");
hdb.style("INHERIT", "$W{"+w.getName()+".style}");
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java
index 24396be..649a57e 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java
@@ -12,6 +12,7 @@
// ***************************************************************************************************************************
package org.apache.juneau.rest;
+import org.apache.juneau.*;
import org.apache.juneau.rest.annotation.*;
/**
@@ -40,7 +41,7 @@ import org.apache.juneau.rest.annotation.*;
* <li class='link'>{@doc juneau-rest-server.Instantiation.ResourceResolvers}
* </ul>
*/
-public interface RestResourceResolver {
+public interface RestResourceResolver extends ResourceResolver {
/**
* Represents no RestResourceResolver.
@@ -64,8 +65,9 @@ public interface RestResourceResolver {
* The parent resource (i.e. the instance whose class has the {@link RestResource#children() @RestResource(children)} annotation.
* @param c The class to resolve.
* @param builder The initialization configuration for the resource.
+ * @param args Optional arguments to pass to constructor
* @return The instance of that class.
* @throws Exception If class could not be resolved.
*/
- Object resolve(Object parent, Class<?> c, RestContextBuilder builder) throws Exception;
+ <T> T resolve(Object parent, Class<T> c, RestContextBuilder builder, Object...args) throws Exception;
}