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 ac54809 REST refactoring.
ac54809 is described below
commit ac548099580d30ddb95e4e4f559522c0472a1313
Author: JamesBognar <[email protected]>
AuthorDate: Sun Jan 24 11:58:08 2021 -0500
REST refactoring.
---
.../org/apache/juneau/cp/BeanFactory_Test.java | 4 +-
.../java/org/apache/juneau/cp/BeanFactory.java | 10 +
.../build-overlay/pom.xml | 18 +-
.../build-overlay/pom.xml | 4 +-
.../juneau-examples-rest-springboot/pom.xml | 4 +-
.../apache/juneau/rest/mock/MockRestClient.java | 2 +-
juneau-rest/juneau-rest-server-springboot/pom.xml | 2 +-
.../rest/annotation/RestAnnotation_Test.java | 27 +-
.../rest/annotation/RestMethodAnnotation_Test.java | 10 +-
.../juneau/rest/annotation/Rest_Context_Test.java | 6 +-
.../juneau/rest/annotation/Restx_Path_Test.java | 6 +-
.../main/java/org/apache/juneau/rest/RestCall.java | 2 +-
...RestMethodsBuilder.java => RestChildMatch.java} | 60 +--
.../java/org/apache/juneau/rest/RestChildren.java | 125 ++++++
.../apache/juneau/rest/RestChildrenBuilder.java | 92 +++++
.../java/org/apache/juneau/rest/RestContext.java | 450 ++++++++++++++++-----
.../org/apache/juneau/rest/RestContextBuilder.java | 90 +++--
.../org/apache/juneau/rest/RestMethodContext.java | 67 ++-
.../juneau/rest/RestMethodContextBuilder.java | 58 ++-
.../java/org/apache/juneau/rest/RestMethods.java | 17 +-
.../org/apache/juneau/rest/RestMethodsBuilder.java | 54 ++-
.../java/org/apache/juneau/rest/RestServlet.java | 4 +-
.../org/apache/juneau/rest/annotation/Rest.java | 64 +--
.../juneau/rest/annotation/RestAnnotation.java | 78 +++-
.../apache/juneau/rest/annotation/RestMethod.java | 4 +-
.../rest/annotation/RestMethodAnnotation.java | 18 +-
pom.xml | 2 +-
27 files changed, 1020 insertions(+), 258 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 1ddd4a7..17fd8c8 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
@@ -39,7 +39,7 @@ public class BeanFactory_Test {
bf.addBean(A.class, new A());
assertBoolean(bf.hasBean(A.class)).isTrue();
assertObject(bf.getBean(A.class)).exists();
- bf = new BeanFactory(bf, null);
+ bf = BeanFactory.of(bf);
assertBoolean(bf.hasBean(A.class)).isTrue();
assertObject(bf.getBean(A.class)).exists();
}
@@ -270,7 +270,7 @@ public class BeanFactory_Test {
public void d01b_createBean_construct_withArgs_inner() throws Exception
{
BeanFactory bf = new BeanFactory();
assertThrown(()->bf.createBean(D1b.class)).stderr().is("Could
not instantiate class "+CNAME+"$D1b: Public constructor found but could not
find prerequisites: BeanFactory_Test,A.");
- BeanFactory bf2 = new BeanFactory(null,this);
+ BeanFactory bf2 = BeanFactory.of(null,this);
assertThrown(()->bf2.createBean(D1b.class)).stderr().is("Could
not instantiate class "+CNAME+"$D1b: Public constructor found but could not
find prerequisites: A.");
bf2.addBean(A.class, new A());
assertObject(bf2.createBean(D1b.class)).exists();
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 8b148af..e0b2bd7 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
@@ -61,6 +61,16 @@ public class BeanFactory {
}
/**
+ * Static creator.
+ *
+ * @param parent Parent bean factory. Can be <jk>null</jk> if this is
the root resource.
+ * @return A new {@link BeanFactory} object.
+ */
+ public static BeanFactory of(BeanFactory parent) {
+ return new BeanFactory(parent, null);
+ }
+
+ /**
* Default constructor.
*/
public BeanFactory() {
diff --git a/juneau-examples/juneau-examples-rest-jetty/build-overlay/pom.xml
b/juneau-examples/juneau-examples-rest-jetty/build-overlay/pom.xml
index 19bc870..cdd1078 100644
--- a/juneau-examples/juneau-examples-rest-jetty/build-overlay/pom.xml
+++ b/juneau-examples/juneau-examples-rest-jetty/build-overlay/pom.xml
@@ -40,7 +40,7 @@
<maven.javadoc.skip>true</maven.javadoc.skip>
<derby.version>${derby.version}</derby.version>
-
<springframework.version>${springframework.version}</springframework.version>
+ <springboot.version>${springboot.version}</springboot.version>
<javax.inject.version>1</javax.inject.version>
<juneau.version>${version}</juneau.version>
<jena.version>${jena.version}</jena.version>
@@ -64,7 +64,7 @@
<artifactId>juneau-marshall-rdf</artifactId>
<version>\${juneau.version}</version>
</dependency>
-
+
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
@@ -88,11 +88,11 @@
<version>\${hibernate.version}</version>
</dependency>
<dependency>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- <version>\${xml.apis.version}</version>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>\${xml.apis.version}</version>
</dependency>
-
+
<!-- Optional RDF support -->
<dependency>
<groupId>org.apache.jena</groupId>
@@ -131,11 +131,11 @@
<target>1.8</target>
</configuration>
</plugin>
-
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
- <version>3.0.2</version>
+ <version>3.0.2</version>
<executions>
<execution>
<id>package-config</id>
@@ -200,5 +200,5 @@
</plugins>
</build>
-
+
</project>
diff --git
a/juneau-examples/juneau-examples-rest-springboot/build-overlay/pom.xml
b/juneau-examples/juneau-examples-rest-springboot/build-overlay/pom.xml
index cf76288..ee67ba8 100644
--- a/juneau-examples/juneau-examples-rest-springboot/build-overlay/pom.xml
+++ b/juneau-examples/juneau-examples-rest-springboot/build-overlay/pom.xml
@@ -37,7 +37,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
- <version>${springframework.version}</version>
+ <version>2.4.2</version>
<relativePath />
</parent>
@@ -52,6 +52,7 @@
<javax.inject.version>${javax.inject.version}</javax.inject.version>
<juneau.version>${version}</juneau.version>
<jena.version>${jena.version}</jena.version>
+ <springboot.version>2.4.2</springboot.version>
</properties>
<dependencies>
@@ -140,6 +141,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${springboot.version}</version>
<executions>
<execution>
<goals>
diff --git a/juneau-examples/juneau-examples-rest-springboot/pom.xml
b/juneau-examples/juneau-examples-rest-springboot/pom.xml
index b9b1b79..e0b414c 100644
--- a/juneau-examples/juneau-examples-rest-springboot/pom.xml
+++ b/juneau-examples/juneau-examples-rest-springboot/pom.xml
@@ -37,7 +37,6 @@
<!-- Java 8 required because Jetty requires it. -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
- <springframework.version>2.0.1.RELEASE</springframework.version>
</properties>
@@ -59,7 +58,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
- <version>${springframework.version}</version>
+ <version>${springboot.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
@@ -87,6 +86,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${springboot.version}</version>
<executions>
<execution>
<goals>
diff --git
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
index 1948382..775ef25 100644
---
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
+++
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
@@ -294,7 +294,7 @@ public class MockRestClient extends RestClient implements
HttpClientConnection {
psb.set(MOCKRESTCLIENT_restBeanCtx, restBeanCtx);
if (servletPath == null)
- servletPath =
toValidContextPath(restBeanCtx.getPath());
+ servletPath =
toValidContextPath(restBeanCtx.getFullPath());
rootUrl = rootUrl + emptyIfNull(contextPath) +
emptyIfNull(servletPath);
diff --git a/juneau-rest/juneau-rest-server-springboot/pom.xml
b/juneau-rest/juneau-rest-server-springboot/pom.xml
index f49dc04..a3da36f 100644
--- a/juneau-rest/juneau-rest-server-springboot/pom.xml
+++ b/juneau-rest/juneau-rest-server-springboot/pom.xml
@@ -39,7 +39,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
- <version>${springframework.version}</version>
+ <version>${springboot.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
diff --git
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestAnnotation_Test.java
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestAnnotation_Test.java
index 67fb3ab..7b43f6b 100644
---
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestAnnotation_Test.java
+++
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestAnnotation_Test.java
@@ -47,7 +47,7 @@ public class RestAnnotation_Test {
.clientVersionHeader("clientVersionHeader")
.config("config")
.consumes("consumes")
- .context(RestContext.class)
+ .contextClass(RestContext.class)
.converters(RestConverter.class)
.debug("debug")
.debugOn("debugOn")
@@ -63,6 +63,7 @@ public class RestAnnotation_Test {
.guards(RestGuard.class)
.infoProvider(BasicRestInfoProvider.class)
.maxInput("maxInput")
+ .methodContextClass(RestMethodContext.class)
.messages("messages")
.on("on")
.onClass(RestAnnotation_Test.class)
@@ -73,6 +74,8 @@ public class RestAnnotation_Test {
.produces("produces")
.renderResponseStackTraces("renderResponseStackTraces")
.responseHandlers(ResponseHandler.class)
+ .restChildrenClass(RestChildren.class)
+ .restMethodsClass(RestMethods.class)
.restParams(RestParam.class)
.roleGuard("roleGuard")
.rolesDeclared("rolesDeclared")
@@ -98,7 +101,7 @@ public class RestAnnotation_Test {
.clientVersionHeader("clientVersionHeader")
.config("config")
.consumes("consumes")
- .context(RestContext.class)
+ .contextClass(RestContext.class)
.converters(RestConverter.class)
.debug("debug")
.debugOn("debugOn")
@@ -114,6 +117,7 @@ public class RestAnnotation_Test {
.guards(RestGuard.class)
.infoProvider(BasicRestInfoProvider.class)
.maxInput("maxInput")
+ .methodContextClass(RestMethodContext.class)
.messages("messages")
.on("on")
.onClass(RestAnnotation_Test.class)
@@ -124,6 +128,8 @@ public class RestAnnotation_Test {
.produces("produces")
.renderResponseStackTraces("renderResponseStackTraces")
.responseHandlers(ResponseHandler.class)
+ .restChildrenClass(RestChildren.class)
+ .restMethodsClass(RestMethods.class)
.restParams(RestParam.class)
.roleGuard("roleGuard")
.rolesDeclared("rolesDeclared")
@@ -140,7 +146,7 @@ public class RestAnnotation_Test {
@Test
public void a01_basic() {
- assertObject(a1).json().is(""
+ assertObject(a1).json().stderr().is(""
+ "{"
+ "allowedHeaderParams:'allowedHeaderParams',"
+ "allowedMethodHeaders:'allowedMethodHeaders',"
@@ -151,7 +157,7 @@ public class RestAnnotation_Test {
+ "clientVersionHeader:'clientVersionHeader',"
+ "config:'config',"
+ "consumes:['consumes'],"
- +
"context:'org.apache.juneau.rest.RestContext',"
+ +
"contextClass:'org.apache.juneau.rest.RestContext',"
+
"converters:['org.apache.juneau.rest.RestConverter'],"
+ "debug:'debug',"
+ "debugOn:'debugOn',"
@@ -169,6 +175,7 @@ public class RestAnnotation_Test {
+
"infoProvider:'org.apache.juneau.rest.BasicRestInfoProvider',"
+ "maxInput:'maxInput',"
+ "messages:'messages',"
+ +
"methodContextClass:'org.apache.juneau.rest.RestMethodContext',"
+ "on:['on'],"
+ "onClass:['"+CNAME+"'],"
+ "parsers:['org.apache.juneau.parser.Parser'],"
@@ -178,6 +185,8 @@ public class RestAnnotation_Test {
+ "produces:['produces'],"
+
"renderResponseStackTraces:'renderResponseStackTraces',"
+
"responseHandlers:['org.apache.juneau.rest.ResponseHandler'],"
+ +
"restChildrenClass:'org.apache.juneau.rest.RestChildren',"
+ +
"restMethodsClass:'org.apache.juneau.rest.RestMethods',"
+
"restParams:['org.apache.juneau.rest.RestParam'],"
+ "roleGuard:'roleGuard',"
+ "rolesDeclared:'rolesDeclared',"
@@ -248,7 +257,7 @@ public class RestAnnotation_Test {
clientVersionHeader="clientVersionHeader",
config="config",
consumes="consumes",
- context=RestContext.class,
+ contextClass=RestContext.class,
converters=RestConverter.class,
debug="debug",
debugOn="debugOn",
@@ -264,6 +273,7 @@ public class RestAnnotation_Test {
guards=RestGuard.class,
infoProvider=BasicRestInfoProvider.class,
maxInput="maxInput",
+ methodContextClass=RestMethodContext.class,
messages="messages",
on="on",
onClass=RestAnnotation_Test.class,
@@ -274,6 +284,8 @@ public class RestAnnotation_Test {
produces="produces",
renderResponseStackTraces="renderResponseStackTraces",
responseHandlers=ResponseHandler.class,
+ restChildrenClass=RestChildren.class,
+ restMethodsClass=RestMethods.class,
restParams=RestParam.class,
roleGuard="roleGuard",
rolesDeclared="rolesDeclared",
@@ -301,7 +313,7 @@ public class RestAnnotation_Test {
clientVersionHeader="clientVersionHeader",
config="config",
consumes="consumes",
- context=RestContext.class,
+ contextClass=RestContext.class,
converters=RestConverter.class,
debug="debug",
debugOn="debugOn",
@@ -317,6 +329,7 @@ public class RestAnnotation_Test {
guards=RestGuard.class,
infoProvider=BasicRestInfoProvider.class,
maxInput="maxInput",
+ methodContextClass=RestMethodContext.class,
messages="messages",
on="on",
onClass=RestAnnotation_Test.class,
@@ -327,6 +340,8 @@ public class RestAnnotation_Test {
produces="produces",
renderResponseStackTraces="renderResponseStackTraces",
responseHandlers=ResponseHandler.class,
+ restChildrenClass=RestChildren.class,
+ restMethodsClass=RestMethods.class,
restParams=RestParam.class,
roleGuard="roleGuard",
rolesDeclared="rolesDeclared",
diff --git
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
index 3e46c26..e0b21c2 100644
---
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
+++
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
@@ -36,7 +36,7 @@ public class RestMethodAnnotation_Test {
RestMethod a1 = RestMethodAnnotation.create()
.clientVersion("clientVersion")
.consumes("consumes")
- .context(RestMethodContext.class)
+ .contextClass(RestMethodContext.class)
.converters(RestConverter.class)
.debug("debug")
.defaultAccept("defaultAccept")
@@ -69,7 +69,7 @@ public class RestMethodAnnotation_Test {
RestMethod a2 = RestMethodAnnotation.create()
.clientVersion("clientVersion")
.consumes("consumes")
- .context(RestMethodContext.class)
+ .contextClass(RestMethodContext.class)
.converters(RestConverter.class)
.debug("debug")
.defaultAccept("defaultAccept")
@@ -105,7 +105,7 @@ public class RestMethodAnnotation_Test {
+ "{"
+ "clientVersion:'clientVersion',"
+ "consumes:['consumes'],"
- +
"context:'org.apache.juneau.rest.RestMethodContext',"
+ +
"contextClass:'org.apache.juneau.rest.RestMethodContext',"
+
"converters:['org.apache.juneau.rest.RestConverter'],"
+ "debug:'debug',"
+ "defaultAccept:'defaultAccept',"
@@ -181,7 +181,7 @@ public class RestMethodAnnotation_Test {
@RestMethod(
clientVersion="clientVersion",
consumes="consumes",
- context=RestMethodContext.class,
+ contextClass=RestMethodContext.class,
converters=RestConverter.class,
debug="debug",
defaultAccept="defaultAccept",
@@ -216,7 +216,7 @@ public class RestMethodAnnotation_Test {
@RestMethod(
clientVersion="clientVersion",
consumes="consumes",
- context=RestMethodContext.class,
+ contextClass=RestMethodContext.class,
converters=RestConverter.class,
debug="debug",
defaultAccept="defaultAccept",
diff --git
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
index cba61b1..4280b10 100644
---
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
+++
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
@@ -42,7 +42,7 @@ public class Rest_Context_Test {
a1.get().run().assertBody().is("RestContext");
}
- @Rest(context=X1.class)
+ @Rest(contextClass=X1.class)
public static class A2 extends A1 {}
@Test
@@ -64,7 +64,7 @@ public class Rest_Context_Test {
public static class A4 extends A1 {
@RestHook(HookEvent.INIT)
public void init(RestContextBuilder builder) throws Exception {
- builder.context(X1.class);
+ builder.contextClass(X1.class);
}
}
@@ -81,7 +81,7 @@ public class Rest_Context_Test {
}
}
- @Rest(context=X2.class)
+ @Rest(contextClass=X2.class)
public static class A5 {
@RestMethod
public String get(RestContext context) {
diff --git
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Path_Test.java
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Path_Test.java
index 46e1d75..abc51f0 100644
---
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Path_Test.java
+++
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Path_Test.java
@@ -30,20 +30,20 @@ public class Restx_Path_Test {
public static class A {
@RestMethod(path="/")
public String a(RestContext c) {
- return "A-" + c.getPath();
+ return "A-" + c.getFullPath();
}
}
@Rest(path="/p1", children={A2.class})
public static class A1 {
@RestMethod(path="/")
public String a(RestContext c) {
- return "A01-" + c.getPath();
+ return "A01-" + c.getFullPath();
}
}
public static class A2a {
@RestMethod(path="/")
public String a(RestContext c) {
- return "A02a-" + c.getPath();
+ return "A02a-" + c.getFullPath();
}
}
@Rest(path="/p2")
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
index 2893ab9..2298946 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
@@ -60,7 +60,7 @@ public class RestCall {
public RestCall(Object resource, RestContext context,
HttpServletRequest req, HttpServletResponse res) {
this.context = context;
this.resource = resource;
- beanFactory = new BeanFactory(context.rootBeanFactory,
resource);
+ beanFactory = BeanFactory.of(context.rootBeanFactory, resource);
beanFactory.addBean(RestContext.class, context);
request(req).response(res);
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodsBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildMatch.java
similarity index 57%
copy from
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodsBuilder.java
copy to
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildMatch.java
index 1c7f97f..23a3ecd 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodsBuilder.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildMatch.java
@@ -12,50 +12,54 @@
//
***************************************************************************************************************************
package org.apache.juneau.rest;
-import java.util.*;
-
-import org.apache.juneau.collections.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.util.*;
/**
- * Builder for {@link RestMethods} object.
+ * Represents a matched {@link Rest}-annotated child on an HTTP request.
*/
-public class RestMethodsBuilder {
+public class RestChildMatch {
+
+ private UrlPathMatch pathMatch;
+ private RestContext childContext;
- TreeMap<String,TreeSet<RestMethodContext>> map = new TreeMap<>();
- Set<RestMethodContext> set = ASet.of();
+ /**
+ * Creator.
+ *
+ * @param pathMatch The path matching results.
+ * @param childContext The child context.
+ * @return A new {@link RestChildMatch} object.
+ */
+ public static RestChildMatch create(UrlPathMatch pathMatch, RestContext
childContext) {
+ return new RestChildMatch(pathMatch, childContext);
+ }
/**
- * Adds a method context to this builder.
+ * Constructor.
*
- * @param mc The REST method context to add.
- * @return Adds a method context to this builder.
+ * @param pathMatch The path matching results.
+ * @param childContext The child context.
*/
- public RestMethodsBuilder add(RestMethodContext mc) {
- return add(mc.getHttpMethod(), mc);
+ protected RestChildMatch(UrlPathMatch pathMatch, RestContext
childContext) {
+ this.pathMatch = pathMatch;
+ this.childContext = childContext;
}
/**
- * Adds a method context to this builder.
+ * Returns the path matching results of the REST child match.
*
- * @param httpMethodName The HTTP method name.
- * @param mc The REST method context to add.
- * @return Adds a method context to this builder.
+ * @return The path matching results of the REST child match.
*/
- public RestMethodsBuilder add(String httpMethodName, RestMethodContext
mc) {
- httpMethodName = httpMethodName.toUpperCase();
- if (! map.containsKey(httpMethodName))
- map.put(httpMethodName, new TreeSet<>());
- map.get(httpMethodName).add(mc);
- set.add(mc);
- return this;
+ public UrlPathMatch getPathMatch() {
+ return pathMatch;
}
/**
- * Creates a new {@link RestMethods} object using the contents of this
builder.
+ * Returns the child context of the REST child match.
*
- * @return A new {@link RestMethods} object.
+ * @return The child context of the REST child match.
*/
- public RestMethods build() {
- return new RestMethods(this);
+ public RestContext getChildContext() {
+ return childContext;
}
-}
\ No newline at end of file
+}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
new file mode 100644
index 0000000..ca054de
--- /dev/null
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
@@ -0,0 +1,125 @@
+//
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright
ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance *
+// * with the License. You may obtain a copy of the License at
*
+// *
*
+// * http://www.apache.org/licenses/LICENSE-2.0
*
+// *
*
+// * Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the *
+// * specific language governing permissions and limitations under the
License. *
+//
***************************************************************************************************************************
+package org.apache.juneau.rest;
+
+import java.util.*;
+
+import javax.servlet.*;
+
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.util.*;
+
+/**
+ * Implements the child resources of a {@link Rest}-annotated class.
+ */
+public class RestChildren {
+
+ /**
+ * Represents a null value for the {@link Rest#restChildrenClass()}
annotation.
+ */
+ @SuppressWarnings("javadoc")
+ public final class Null extends RestChildren {
+ public Null(RestChildrenBuilder builder) throws Exception {
+ super(builder);
+ }
+ }
+
+ private final Map<String,RestContext> children =
Collections.synchronizedMap(new LinkedHashMap<String,RestContext>());
+
+ /**
+ * Creates a new builder for this object.
+ *
+ * @return A new builder for this object.
+ */
+ public static RestChildrenBuilder create() {
+ return new RestChildrenBuilder();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param builder The builder containing the settings for this object.
+ */
+ public RestChildren(RestChildrenBuilder builder) {
+ for (RestContext rc : builder.list)
+ children.put(rc.getPath(), rc);
+ }
+
+ /**
+ * Looks through the registered children of this object and returns the
best match.
+ *
+ * @param call The HTTP call.
+ * @return The child that best matches the call, or an empty {@link
Optional} if a match could not be made.
+ */
+ public Optional<RestChildMatch> findMatch(RestCall call) {
+ String pi = call.getPathInfoUndecoded();
+ if ((! children.isEmpty()) && pi != null && ! pi.equals("/")) {
+ for (RestContext rc : children.values()) {
+ UrlPathMatcher upp = rc.pathMatcher;
+ UrlPathMatch uppm =
upp.match(call.getUrlPath());
+ if (uppm != null) {
+ return
Optional.of(RestChildMatch.create(uppm, rc));
+ }
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Returns the children in this object as a map.
+ *
+ * <p>
+ * The keys are the {@link RestContext#getPath() paths} of the child
contexts.
+ *
+ * @return The children as an unmodifiable map.
+ */
+ public Map<String,RestContext> asMap() {
+ return Collections.unmodifiableMap(children);
+ }
+
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // Lifecycle methods.
+
//-----------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Called during servlet initialization on all children to invoke all
{@link HookEvent#POST_INIT} methods.
+ *
+ * @throws ServletException Error occurred.
+ */
+ public void postInit() throws ServletException {
+ for (RestContext childContext : children.values())
+ childContext.postInit();
+ }
+
+ /**
+ * Called during servlet initialization on all children to invoke all
{@link HookEvent#POST_INIT_CHILD_FIRST} methods.
+ *
+ * @throws ServletException Error occurred.
+ */
+ public void postInitChildFirst() throws ServletException {
+ for (RestContext childContext : children.values())
+ childContext.postInitChildFirst();
+ }
+
+ /**
+ * Called during servlet destruction on all children to invoke all
{@link HookEvent#DESTROY} and {@link Servlet#destroy()} methods.
+ */
+ public void destroy() {
+ for (RestContext r : children.values()) {
+ r.destroy();
+ if (r.getResource() instanceof Servlet)
+ ((Servlet)r.getResource()).destroy();
+ }
+ }
+}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildrenBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildrenBuilder.java
new file mode 100644
index 0000000..25b01a8
--- /dev/null
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildrenBuilder.java
@@ -0,0 +1,92 @@
+//
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright
ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance *
+// * with the License. You may obtain a copy of the License at
*
+// *
*
+// * http://www.apache.org/licenses/LICENSE-2.0
*
+// *
*
+// * Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the *
+// * specific language governing permissions and limitations under the
License. *
+//
***************************************************************************************************************************
+package org.apache.juneau.rest;
+
+import static org.apache.juneau.rest.HttpRuntimeException.*;
+import static org.apache.juneau.internal.ObjectUtils.*;
+
+import java.util.*;
+
+import org.apache.juneau.collections.*;
+import org.apache.juneau.cp.*;
+import org.apache.juneau.http.exception.*;
+
+/**
+ * Builder for {@link RestChildren} objects.
+ */
+public class RestChildrenBuilder {
+
+ final List<RestContext> list = AList.create();
+
+ private BeanFactory beanFactory;
+ private Class<? extends RestChildren> implClass;
+
+ /**
+ * Instantiates a {@link RestChildren} object based on the contents of
this builder.
+ *
+ * @return A new {@link RestChildren} object.
+ */
+ public RestChildren build() {
+ try {
+ Class<? extends RestChildren> ic =
firstNonNull(implClass, RestChildren.class);
+ return
BeanFactory.of(beanFactory).addBean(RestChildrenBuilder.class,
this).createBean(ic);
+ } catch (Exception e) {
+ throw toHttpException(e, InternalServerError.class);
+ }
+ }
+
+ /**
+ * Adds a child resource to this builder.
+ *
+ * @param childContext The REST context of the child resource.
+ * @return This object (for method chaining).
+ */
+ public RestChildrenBuilder add(RestContext childContext) {
+ this.list.add(childContext);
+ return this;
+ }
+
+
+ /**
+ * Specifies a {@link RestChildren} implementation subclass to use.
+ *
+ * <p>
+ * When specified, the {@link #build()} method will create an instance
of that class instead of the default {@link RestChildren}.
+ *
+ * <p>
+ * The subclass must have a public constructor that takes in any of the
following arguments:
+ * <ul>
+ * <li>{@link RestChildrenBuilder} - This object.
+ * <li>Any beans found in the specified {@link
#beanFactory(BeanFactory) bean factory}.
+ * <li>Any {@link Optional} beans that may or may not be found in
the specified {@link #beanFactory(BeanFactory) bean factory}.
+ * </ul>
+ *
+ * @param implClass The implementation class to build.
+ * @return This object (for method chaining).
+ */
+ public RestChildrenBuilder implClass(Class<? extends RestChildren>
implClass) {
+ this.implClass = implClass;
+ return this;
+ }
+
+ /**
+ * Specifies a {@link BeanFactory} to use when resolving constructor
arguments.
+ *
+ * @param beanFactory The bean factory to use for resolving constructor
arguments.
+ * @return This object (for method chaining).
+ */
+ public RestChildrenBuilder beanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ return this;
+ }
+}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 5c3212a..9c103d9 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
@@ -84,7 +84,9 @@ import org.apache.juneau.xml.*;
@ConfigurableContext(nocache=true)
public class RestContext extends BeanContext {
- /** Represents a null value for the {@link Rest#context()} annotation.*/
+ /**
+ * Represents a null value for the {@link Rest#contextClass()}
annotation.
+ */
@SuppressWarnings("javadoc")
public static final class Null extends RestContext {
public Null(RestContextBuilder builder) throws Exception {
@@ -1474,6 +1476,84 @@ public class RestContext extends BeanContext {
public static final String REST_messages = PREFIX + ".messages.lo";
/**
+ * Configuration property: REST method context class.
+ *
+ * <h5 class='section'>Property:</h5>
+ * <ul class='spaced-list'>
+ * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestContext#REST_methodContextClass
REST_methodContextClass}
+ * <li><b>Name:</b> <js>"RestContext.methodContextClass.c"</js>
+ * <li><b>Data type:</b> <c>Class<? extends {@link
org.apache.juneau.rest.RestMethodContext}></c>
+ * <li><b>Default:</b> {@link
org.apache.juneau.rest.RestMethodContext}
+ * <li><b>Session property:</b> <jk>false</jk>
+ * <li><b>Annotations:</b>
+ * <ul>
+ * <li class='ja'>{@link
org.apache.juneau.rest.annotation.Rest#methodContextClass()}
+ * <li class='ja'>{@link
org.apache.juneau.rest.annotation.RestMethod#contextClass()}
+ * </ul>
+ * <li><b>Methods:</b>
+ * <ul>
+ * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#methodContextClass(Class)}
+ * <li class='jm'>{@link
org.apache.juneau.rest.RestMethodContextBuilder#contextClass(Class)}
+ * </ul>
+ * </ul>
+ *
+ * <h5 class='section'>Description:</h5>
+ * <p>
+ * Allows you to extend the {@link RestMethodContext} class to modify
how any of the methods are implemented.
+ *
+ * <p>
+ * The subclass must have a public constructor that takes in any of the
following arguments:
+ * <ul>
+ * <li>{@link RestMethodContextBuilder} - The builder for the
object.
+ * <li>Any beans found in the specified {@link #REST_beanFactory
bean factory}.
+ * <li>Any {@link Optional} beans that may or may not be found in
the specified {@link #REST_beanFactory bean factory}.
+ * </ul>
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode w800'>
+ * <jc>// Our extended context class that adds a request attribute
to all requests.</jc>
+ * <jc>// The attribute value is provided by an injected spring
bean.</jc>
+ * <jk>public</jk> MyRestMethodContext <jk>extends</jk>
RestMethodContext {
+ *
+ * <jk>private final</jk> Optional<? <jk>extends</jk>
Supplier<Object>> <jf>fooSupplier</jf>;
+ *
+ * <jc>// Constructor that takes in builder and optional
injected attribute provider.</jc>
+ * <jk>public</jk>
MyRestMethodContext(RestMethodContextBuilder <jv>builder</jv>,
Optional<AnInjectedFooSupplier> <jv>fooSupplier</jv>) {
+ * <jk>super</jk>(<jv>builder</jv>);
+ * <jk>this</jk>.<jf>fooSupplier</jf> =
<jv>fooSupplier</jv>.orElseGet(()-><jk>null</jk>);
+ * }
+ *
+ * <jc>// Override the method used to create default
request attributes.</jc>
+ * <ja>@Override</ja>
+ * <jk>protected</jk> NamedAttributeList
createDefaultRequestAttributes(Object <jv>resource</jv>, BeanFactory
<jv>beanFactory</jv>, Method <jv>method</jv>, RestContext <jv>context</jv>)
<jk>throws</jk> Exception {
+ * <jk>return super</jk>
+ *
.createDefaultRequestAttributes(<jv>resource</jv>, <jv>beanFactory</jv>,
<jv>method</jv>, <jv>context</jv>)
+ *
.append(NamedAttribute.<jsm>of</jsm>(<js>"foo"</js>,
()-><jf>fooSupplier</jf>.get());
+ * }
+ * }
+ * </p>
+ * <p class='bcode w800'>
+ * <jc>// Option #1 - Defined via annotation.</jc>
+ *
<ja>@Rest</ja>(methodContextClass=MyRestMethodContext.<jk>class</jk>)
+ * <jk>public class</jk> MyResource {
+ * ...
+ *
+ * <jc>// Option #2 - Defined via builder passed in
through init method.</jc>
+ * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
+ *
<jv>builder</jv>.methodContextClass(MyRestMethodContext.<jk>class</jk>);
+ * }
+ *
+ * <ja>@RestMethod</ja>
+ * <jk>public</jk> Object getFoo(RequestAttributes
<jv>attributes</jv>) {
+ * <jk>return</jk>
<jv>attributes</jv>.get(<js>"foo"</js>);
+ * }
+ * }
+ * </p>
+ */
+ public static final String REST_methodContextClass = PREFIX +
".methodContextClass.c";
+
+ /**
* Configuration property: Parsers.
*
* <h5 class='section'>Property:</h5>
@@ -2225,6 +2305,142 @@ public class RestContext extends BeanContext {
public static final String REST_responseHandlers = PREFIX +
".responseHandlers.lo";
/**
+ * Configuration property: REST children class.
+ *
+ * <h5 class='section'>Property:</h5>
+ * <ul class='spaced-list'>
+ * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestContext#REST_restChildrenClass
REST_restChildrenClass}
+ * <li><b>Name:</b> <js>"RestContext.restChildrenClass.c"</js>
+ * <li><b>Data type:</b> <c>Class<? extends {@link
org.apache.juneau.rest.RestChildren}></c>
+ * <li><b>Default:</b> {@link org.apache.juneau.rest.RestChildren}
+ * <li><b>Session property:</b> <jk>false</jk>
+ * <li><b>Annotations:</b>
+ * <ul>
+ * <li class='ja'>{@link
org.apache.juneau.rest.annotation.Rest#restChildrenClass()}
+ * </ul>
+ * <li><b>Methods:</b>
+ * <ul>
+ * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#restChildrenClass(Class)}
+ * </ul>
+ * </ul>
+ *
+ * <h5 class='section'>Description:</h5>
+ * <p>
+ * Allows you to extend the {@link RestChildren} class to modify how
any of the methods are implemented.
+ *
+ * <p>
+ * The subclass must have a public constructor that takes in any of the
following arguments:
+ * <ul>
+ * <li>{@link RestChildrenBuilder} - The builder for the object.
+ * <li>Any beans found in the specified {@link #REST_beanFactory
bean factory}.
+ * <li>Any {@link Optional} beans that may or may not be found in
the specified {@link #REST_beanFactory bean factory}.
+ * </ul>
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode w800'>
+ * <jc>// Our extended context class</jc>
+ * <jk>public</jk> MyRestChildren <jk>extends</jk> RestChildren {
+ * <jk>public</jk> MyRestChildren(RestChildrenBuilder
<jv>builder</jv>, ARequiredSpringBean <jv>bean1</jv>,
Optional<AnOptionalSpringBean> <jv>bean2</jv>) {
+ * <jk>super</jk>(<jv>builder</jv>);
+ * }
+ *
+ * <jc>// Override any methods.</jc>
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> Optional<RestChildMatch>
findMatch(RestCall <jv>call</jv>) {
+ * String <jv>path</jv> =
<jv>call</jv>.getPathInfo();
+ * <jk>if</jk>
(<jv>path</jv>.endsWith(<js>"/foo"</js>)) {
+ * <jc>// Do our own special handling.</jc>
+ * }
+ * <jk>return super</jk>.findMatch(<jv>call</jv>);
+ * }
+ * }
+ * </p>
+ * <p class='bcode w800'>
+ * <jc>// Option #1 - Defined via annotation.</jc>
+ * <ja>@Rest</ja>(restChildrenClass=MyRestChildren.<jk>class</jk>)
+ * <jk>public class</jk> MyResource {
+ * ...
+ *
+ * <jc>// Option #2 - Defined via builder passed in
through init method.</jc>
+ * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
+ *
<jv>builder</jv>.restChildrenClass(MyRestChildren.<jk>class</jk>);
+ * }
+ * }
+ * </p>
+ */
+ public static final String REST_restChildrenClass = PREFIX +
".restChildrenClass.c";
+
+ /**
+ * Configuration property: REST methods class.
+ *
+ * <h5 class='section'>Property:</h5>
+ * <ul class='spaced-list'>
+ * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestContext#REST_restMethodsClass REST_restMethodsClass}
+ * <li><b>Name:</b> <js>"RestContext.restMethodsClass.c"</js>
+ * <li><b>Data type:</b> <c>Class<? extends {@link
org.apache.juneau.rest.RestMethods}></c>
+ * <li><b>Default:</b> {@link org.apache.juneau.rest.RestMethods}
+ * <li><b>Session property:</b> <jk>false</jk>
+ * <li><b>Annotations:</b>
+ * <ul>
+ * <li class='ja'>{@link
org.apache.juneau.rest.annotation.Rest#restMethodsClass()}
+ * </ul>
+ * <li><b>Methods:</b>
+ * <ul>
+ * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#restMethodsClass(Class)}
+ * </ul>
+ * </ul>
+ *
+ * <h5 class='section'>Description:</h5>
+ * <p>
+ * Allows you to extend the {@link RestMethods} class to modify how any
of the methods are implemented.
+ *
+ * <p>
+ * The subclass must have a public constructor that takes in any of the
following arguments:
+ * <ul>
+ * <li>{@link RestMethodsBuilder} - The builder for the object.
+ * <li>Any beans found in the specified {@link #REST_beanFactory
bean factory}.
+ * <li>Any {@link Optional} beans that may or may not be found in
the specified {@link #REST_beanFactory bean factory}.
+ * </ul>
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode w800'>
+ * <jc>// Our extended context class</jc>
+ * <jk>public</jk> MyRestMethods <jk>extends</jk> RestMethods {
+ * <jk>public</jk> MyRestMethods(RestMethodsBuilder
<jv>builder</jv>, ARequiredSpringBean <jv>bean1</jv>,
Optional<AnOptionalSpringBean> <jv>bean2</jv>) {
+ * <jk>super</jk>(<jv>builder</jv>);
+ * }
+ *
+ * <jc>// Override any methods.</jc>
+ *
+ * <ja>@Override</ja>
+ * <jk>public</jk> RestMethodContext findMethod(RestCall
<jv>call</jv>) <jk>throws</jk> MethodNotAllowed, PreconditionFailed, NotFound {
+ * String <jv>path</jv> =
<jv>call</jv>.getPathInfo();
+ * <jk>if</jk>
(<jv>path</jv>.endsWith(<js>"/foo"</js>)) {
+ * <jc>// Do our own special handling.</jc>
+ * }
+ * <jk>return super</jk>.findMethod(<jv>call</jv>);
+ * }
+ * }
+ * </p>
+ * <p class='bcode w800'>
+ * <jc>// Option #1 - Defined via annotation.</jc>
+ * <ja>@Rest</ja>(restMethodsClass=MyRestMethods.<jk>class</jk>)
+ * <jk>public class</jk> MyResource {
+ * ...
+ *
+ * <jc>// Option #2 - Defined via builder passed in
through init method.</jc>
+ * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
+ *
<jv>builder</jv>.restMethodsClass(MyRestMethods.<jk>class</jk>);
+ * }
+ * }
+ * </p>
+ */
+ public static final String REST_restMethodsClass = PREFIX +
".restMethodsClass.c";
+
+ /**
* Configuration property: Java REST method parameter resolvers.
*
* <h5 class='section'>Property:</h5>
@@ -2809,22 +3025,20 @@ public class RestContext extends BeanContext {
/**
* Configuration property: REST context class.
*
- * <review>NEEDS REVIEW</review>
- *
* <h5 class='section'>Property:</h5>
* <ul class='spaced-list'>
- * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestContext#REST_context REST_context}
- * <li><b>Name:</b> <js>"RestContext.context.c"</js>
+ * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestContext#REST_contextClass REST_contextClass}
+ * <li><b>Name:</b> <js>"RestContext.contextClass.c"</js>
* <li><b>Data type:</b> <c>Class<? extends {@link
org.apache.juneau.rest.RestContext}></c>
* <li><b>Default:</b> {@link org.apache.juneau.rest.RestContext}
* <li><b>Session property:</b> <jk>false</jk>
* <li><b>Annotations:</b>
* <ul>
- * <li class='ja'>{@link
org.apache.juneau.rest.annotation.Rest#context()}
+ * <li class='ja'>{@link
org.apache.juneau.rest.annotation.Rest#contextClass()}
* </ul>
* <li><b>Methods:</b>
* <ul>
- * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#context(Class)}
+ * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#contextClass(Class)}
* </ul>
* </ul>
*
@@ -2833,37 +3047,56 @@ public class RestContext extends BeanContext {
* Allows you to extend the {@link RestContext} class to modify how any
of the methods are implemented.
*
* <p>
- * The subclass must provide the following:
+ * The subclass must have a public constructor that takes in any of the
following arguments:
* <ul>
- * <li>A public constructor that takes in one parameter that
should be passed to the super constructor: {@link RestContextBuilder}.
+ * <li>{@link RestContextBuilder} - The builder for the object.
+ * <li>Any beans found in the specified {@link #REST_beanFactory
bean factory}.
+ * <li>Any {@link Optional} beans that may or may not be found in
the specified {@link #REST_beanFactory bean factory}.
* </ul>
*
* <h5 class='section'>Example:</h5>
* <p class='bcode w800'>
- * <jc>// Our extended context class</jc>
+ * <jc>// Our extended context class that adds a request attribute
to all requests.</jc>
+ * <jc>// The attribute value is provided by an injected spring
bean.</jc>
* <jk>public</jk> MyRestContext <jk>extends</jk> RestContext {
- * <jk>public</jk> MyRestContext(RestContextBuilder
<jv>builder</jv>) {
+ *
+ * <jk>private final</jk> Optional<? <jk>extends</jk>
Supplier<Object>> <jf>fooSupplier</jf>;
+ *
+ * <jc>// Constructor that takes in builder and optional
injected attribute provider.</jc>
+ * <jk>public</jk> MyRestContext(RestMethodContextBuilder
<jv>builder</jv>, Optional<AnInjectedFooSupplier> <jv>fooSupplier</jv>) {
* <jk>super</jk>(<jv>builder</jv>);
+ * <jk>this</jk>.<jf>fooSupplier</jf> =
<jv>fooSupplier</jv>.orElseGet(()-><jk>null</jk>);
* }
*
- * <jc>// Override any methods.</jc>
+ * <jc>// Override the method used to create default
request attributes.</jc>
+ * <ja>@Override</ja>
+ * <jk>protected</jk> NamedAttributeList
createDefaultRequestAttributes(Object <jv>resource</jv>, BeanFactory
<jv>beanFactory</jv>) <jk>throws</jk> Exception {
+ * <jk>return super</jk>
+ *
.createDefaultRequestAttributes(<jv>resource</jv>, <jv>beanFactory</jv>)
+ *
.append(NamedAttribute.<jsm>of</jsm>(<js>"foo"</js>,
()-><jf>fooSupplier</jf>.get());
+ * }
* }
* </p>
* <p class='bcode w800'>
* <jc>// Option #1 - Defined via annotation.</jc>
- * <ja>@Rest</ja>(context=MyRestContext.<jk>class</jk>)
+ * <ja>@Rest</ja>(contextClass=MyRestContext.<jk>class</jk>)
* <jk>public class</jk> MyResource {
* ...
*
* <jc>// Option #2 - Defined via builder passed in
through init method.</jc>
* <ja>@RestHook</ja>(<jsf>INIT</jsf>)
* <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
- *
<jv>builder</jv>.context(MyRestContext.<jk>class</jk>);
+ *
<jv>builder</jv>.contextClass(MyRestContext.<jk>class</jk>);
+ * }
+ *
+ * <ja>@RestMethod</ja>
+ * <jk>public</jk> Object getFoo(RequestAttributes
<jv>attributes</jv>) {
+ * <jk>return</jk>
<jv>attributes</jv>.get(<js>"foo"</js>);
* }
* }
* </p>
*/
- public static final String REST_context = PREFIX + ".context.c";
+ public static final String REST_contextClass = PREFIX + ".context.c";
/**
* Configuration property: Resource URI authority path.
@@ -3162,7 +3395,7 @@ public class RestContext extends BeanContext {
clientVersionHeader,
uriAuthority,
uriContext;
- final String fullPath;
+ final String path, fullPath;
final UrlPathMatcher pathMatcher;
private final Set<String> allowedMethodParams, allowedHeaderParams,
allowedMethodHeaders;
@@ -3183,7 +3416,7 @@ public class RestContext extends BeanContext {
private final Config config;
private final VarResolver varResolver;
private final RestMethods restMethods;
- private final Map<String,RestContext> childResources;
+ private final RestChildren restChildren;
private final StackTraceStore stackTraceStore;
private final Logger logger;
private final RestInfoProvider infoProvider;
@@ -3346,14 +3579,13 @@ public class RestContext extends BeanContext {
msgs = createMessages(r);
fullPath = (builder.parentContext == null ? "" :
(builder.parentContext.fullPath + '/')) + builder.getPath();
+ path = builder.getPath();
- String p = builder.getPath();
+ String p = path;
if (! p.endsWith("/*"))
p += "/*";
pathMatcher = UrlPathMatcher.of(p);
- childResources = Collections.synchronizedMap(new
LinkedHashMap<String,RestContext>()); // Not unmodifiable on purpose so that
children can be replaced.
-
startCallMethods =
createStartCallMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);
endCallMethods =
createEndCallMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);
postInitMethods =
createPostInitMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);
@@ -3364,42 +3596,7 @@ public class RestContext extends BeanContext {
postCallMethods =
createPostCallMethods(r).stream().map(this::toRestMethodInvoker).toArray(RestMethodInvoker[]::
new);
restMethods = createRestMethods(r).build();
-
-
- // Initialize our child resources.
- for (Object o : getArrayProperty(REST_children,
Object.class)) {
- String path = null;
-
- if (o instanceof RestChild) {
- RestChild rc = (RestChild)o;
- path = rc.path;
- o = rc.resource;
- }
-
- RestContextBuilder cb = null;
-
- if (o instanceof Class) {
- Class<?> oc = (Class<?>)o;
- // Don't allow specifying yourself as a
child. Causes an infinite loop.
- if (oc == builder.resourceClass)
- continue;
- cb = RestContext.create(this,
builder.inner, oc, null);
- o = new BeanFactory(beanFactory,
r).addBean(RestContextBuilder.class, cb).createBean(oc);
- } else {
- cb = RestContext.create(this,
builder.inner, o.getClass(), o);
- }
-
- if (path != null)
- cb.path(path);
-
- RestContext cc = cb.init(o).build();
-
- MethodInfo mi =
ClassInfo.of(o).getMethod("setContext", RestContext.class);
- if (mi != null)
- mi.accessible().invoke(o, cc);
-
- childResources.put(cb.getPath(), cc);
- }
+ restChildren = createRestChildren(r).build();
infoProvider = createInfoProvider(r, beanFactory);
@@ -3755,7 +3952,7 @@ public class RestContext extends BeanContext {
x = (BeanFactory)resource;
BeanFactory parent = parentContext == null ? null :
parentContext.rootBeanFactory;
- BeanFactory bf = new BeanFactory(parent, resource);
+ BeanFactory bf = BeanFactory.of(parent, resource);
bf.addBean(BeanFactory.class, bf);
if (x == null)
@@ -4555,7 +4752,11 @@ public class RestContext extends BeanContext {
* @throws Exception An error occurred.
*/
protected RestMethodsBuilder createRestMethods(Object resource) throws
Exception {
- RestMethodsBuilder x = new RestMethodsBuilder();
+ RestMethodsBuilder x = RestMethods
+ .create()
+ .beanFactory(rootBeanFactory)
+ .implClass(getClassProperty(REST_restMethodsClass,
RestMethods.class));
+
ClassInfo rci = ClassInfo.of(resource);
for (MethodInfo mi : rci.getPublicMethods()) {
@@ -4575,8 +4776,12 @@ public class RestContext extends BeanContext {
if (mi.isNotPublic())
throw new
RestServletException("@RestMethod method {0}.{1} must be defined as public.",
rci.inner().getName(), mi.getSimpleName());
- RestMethodContextBuilder rmcb = new
RestMethodContextBuilder(mi.inner(), this);
- RestMethodContext rmc = rmcb.build();
+ RestMethodContext rmc =
RestMethodContext
+ .create(mi.inner(), this)
+ .beanFactory(rootBeanFactory)
+
.implClass(getClassProperty(REST_methodContextClass, RestMethodContext.class))
+ .build();
+
String httpMethod = rmc.getHttpMethod();
// RRPC is a special case where a
method returns an interface that we
@@ -4584,9 +4789,11 @@ public class RestContext extends BeanContext {
// We override the CallMethod.invoke()
method to insert our logic.
if ("RRPC".equals(httpMethod)) {
- RestMethodContext smb = new
RestMethodContextBuilder(mi.inner(), this)
+ RestMethodContext smb =
RestMethodContext
+ .create(mi.inner(),
this)
.dotAll()
-
.context(RrpcRestMethodContext.class)
+
.beanFactory(rootBeanFactory)
+
.implClass(RrpcRestMethodContext.class)
.build();
x
.add("GET", smb)
@@ -4605,6 +4812,56 @@ public class RestContext extends BeanContext {
}
/**
+ * Creates the builder for the children of this resource.
+ *
+ * @param resource The REST resource object.
+ * @return The builder for the {@link RestChildren} object.
+ * @throws Exception An error occurred.
+ */
+ protected RestChildrenBuilder createRestChildren(Object resource)
throws Exception {
+ RestChildrenBuilder x = RestChildren
+ .create()
+ .beanFactory(rootBeanFactory)
+ .implClass(getClassProperty(REST_restChildrenClass,
RestChildren.class));
+
+ // Initialize our child resources.
+ for (Object o : getArrayProperty(REST_children, Object.class)) {
+ String path = null;
+
+ if (o instanceof RestChild) {
+ RestChild rc = (RestChild)o;
+ path = rc.path;
+ o = rc.resource;
+ }
+
+ RestContextBuilder cb = null;
+
+ if (o instanceof Class) {
+ Class<?> oc = (Class<?>)o;
+ // Don't allow specifying yourself as a child.
Causes an infinite loop.
+ if (oc == builder.resourceClass)
+ continue;
+ cb = RestContext.create(this, builder.inner,
oc, null);
+ o = BeanFactory.of(beanFactory,
resource).addBean(RestContextBuilder.class, cb).createBean(oc);
+ } else {
+ cb = RestContext.create(this, builder.inner,
o.getClass(), o);
+ }
+
+ if (path != null)
+ cb.path(path);
+
+ RestContext cc = cb.init(o).build();
+
+ MethodInfo mi = ClassInfo.of(o).getMethod("setContext",
RestContext.class);
+ if (mi != null)
+ mi.accessible().invoke(o, cc);
+
+ x.add(cc);
+ }
+ return x;
+ }
+
+ /**
* Instantiates the list of {@link HookEvent#START_CALL} methods.
*
* @param resource The REST resource object.
@@ -4835,7 +5092,7 @@ public class RestContext extends BeanContext {
/**
* Returns the path for this resource as defined by the {@link
Rest#path() @Rest(path)} annotation or
- * {@link RestContextBuilder#path(String)} method concatenated with
those on all parent classes.
+ * {@link RestContextBuilder#path(String)} method.
*
* <p>
* If path is not specified, returns <js>""</js>.
@@ -4847,6 +5104,23 @@ public class RestContext extends BeanContext {
* @return The servlet path.
*/
public String getPath() {
+ return path;
+ }
+
+ /**
+ * Returns the path for this resource as defined by the {@link
Rest#path() @Rest(path)} annotation or
+ * {@link RestContextBuilder#path(String)} method concatenated with
those on all parent classes.
+ *
+ * <p>
+ * If path is not specified, returns <js>""</js>.
+ *
+ * <ul class='seealso'>
+ * <li class='jf'>{@link #REST_path}
+ * </ul>
+ *
+ * @return The full path.
+ */
+ public String getFullPath() {
return fullPath;
}
@@ -4938,7 +5212,7 @@ public class RestContext extends BeanContext {
* Keys are the {@link Rest#path() @Rest(path)} annotation defined
on the child resource.
*/
public Map<String,RestContext> getChildResources() {
- return Collections.unmodifiableMap(childResources);
+ return restChildren.asMap();
}
/**
@@ -5351,7 +5625,7 @@ public class RestContext extends BeanContext {
List<ClassInfo> pt = mi.getParamTypes();
RestParam[] rp = new RestParam[pt.size()];
- beanFactory = new BeanFactory(beanFactory, getResource());
+ beanFactory = BeanFactory.of(beanFactory, getResource());
for (int i = 0; i < pt.size(); i++) {
ParamInfo pi = mi.getParam(i);
@@ -5384,7 +5658,7 @@ public class RestContext extends BeanContext {
List<ClassInfo> pt = mi.getParamTypes();
RestParam[] rp = new RestParam[pt.size()];
- beanFactory = new BeanFactory(beanFactory, getResource());
+ beanFactory = BeanFactory.of(beanFactory, getResource());
for (int i = 0; i < pt.size(); i++) {
ParamInfo pi = mi.getParam(i);
@@ -5499,24 +5773,20 @@ public class RestContext extends BeanContext {
}
// If this resource has child resources, try to
recursively call them.
- String pi = call.getPathInfoUndecoded();
- if ((! childResources.isEmpty()) && pi != null && !
pi.equals("/")) {
- for (RestContext rc :
getChildResources().values()) {
- UrlPathMatcher upp = rc.pathMatcher;
- UrlPathMatch uppm =
upp.match(call.getUrlPath());
- if (uppm != null) {
- if (! uppm.hasEmptyVars()) {
-
call.pathVars(uppm.getVars());
- HttpServletRequest
childRequest = new OverrideableHttpServletRequest(call.getRequest())
-
.pathInfo(nullIfEmpty(urlDecode(uppm.getSuffix())))
-
.servletPath(call.getServletPath() + uppm.getPrefix());
-
rc.execute(rc.getResource(), childRequest, call.getResponse()); // TODO -
resource needs to be dynamically retrieved.
- } else {
-
call.debug(isDebug(call)).status(SC_NOT_FOUND).finish();
- }
- return;
- }
+ Optional<RestChildMatch> childMatch =
restChildren.findMatch(call);
+ if (childMatch.isPresent()) {
+ UrlPathMatch uppm =
childMatch.get().getPathMatch();
+ RestContext rc =
childMatch.get().getChildContext();
+ if (! uppm.hasEmptyVars()) {
+ call.pathVars(uppm.getVars());
+ HttpServletRequest childRequest = new
OverrideableHttpServletRequest(call.getRequest())
+
.pathInfo(nullIfEmpty(urlDecode(uppm.getSuffix())))
+
.servletPath(call.getServletPath() + uppm.getPrefix());
+ rc.execute(rc.getResource(),
childRequest, call.getResponse());
+ } else {
+
call.debug(isDebug(call)).status(SC_NOT_FOUND).finish();
}
+ return;
}
if (isDebug(call))
@@ -5835,8 +6105,7 @@ public class RestContext extends BeanContext {
throw new ServletException(e.unwrap());
}
}
- for (RestContext childContext : this.childResources.values())
- childContext.postInit();
+ restChildren.postInit();
return this;
}
@@ -5849,8 +6118,7 @@ public class RestContext extends BeanContext {
public RestContext postInitChildFirst() throws ServletException {
if (initialized.get())
return this;
- for (RestContext childContext : this.childResources.values())
- childContext.postInitChildFirst();
+ restChildren.postInitChildFirst();
for (MethodInvoker x : postInitChildFirstMethods) {
try {
x.invokeUsingFactory(beanFactory,
getResource());
@@ -5863,7 +6131,7 @@ public class RestContext extends BeanContext {
}
/**
- * Called during servlet initialization to invoke all {@link
HookEvent#DESTROY} methods.
+ * Called during servlet destruction to invoke all {@link
HookEvent#DESTROY} methods.
*/
protected void destroy() {
for (MethodInvoker x : destroyMethods) {
@@ -5874,11 +6142,7 @@ public class RestContext extends BeanContext {
}
}
- for (RestContext r : childResources.values()) {
- r.destroy();
- if (r.getResource() instanceof Servlet)
- ((Servlet)r.getResource()).destroy();
- }
+ restChildren.destroy();
}
/**
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 5b60ff0..be2f879 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
@@ -184,8 +184,8 @@ public class RestContextBuilder extends BeanContextBuilder
implements ServletCon
public RestContext build() {
try {
PropertyStore ps = getPropertyStore();
- Class<? extends RestContext> c =
ps.getClassProperty(REST_context, RestContext.class, RestContext.class);
- BeanFactory bf = new BeanFactory(beanFactory, resource);
+ Class<? extends RestContext> c =
ps.getClassProperty(REST_contextClass, RestContext.class, RestContext.class);
+ BeanFactory bf = BeanFactory.of(beanFactory, resource);
bf.addBean(RestContextBuilder.class, this);
return bf.createBean(c);
} catch (Exception e) {
@@ -214,7 +214,7 @@ public class RestContextBuilder extends BeanContextBuilder
implements ServletCon
if (x == null && parentContext.isPresent()) {
x = parentContext.get().rootBeanFactory;
}
- return new BeanFactory(x, resource.orElse(null));
+ return BeanFactory.of(x, resource.orElse(null));
}
/**
@@ -745,41 +745,19 @@ public class RestContextBuilder extends
BeanContextBuilder implements ServletCon
/**
* <i><l>RestContext</l> configuration property: </i> REST
context class.
*
- * <review>NEEDS REVIEW</review>
* <p>
* Allows you to extend the {@link RestContext} class to modify how any
of the methods are implemented.
*
- * <p>
- * The subclass must provide the following:
- * <ul>
- * <li>A public constructor that takes in one parameter that
should be passed to the super constructor: {@link RestContextBuilder}.
+ * <ul class='seealso'>
+ * <li class='jf'>{@link RestContext#REST_contextClass}
* </ul>
*
- * <h5 class='section'>Example:</h5>
- * <p class='bcode w800'>
- * <jc>// Our REST class</jc>
- * <ja>@Rest</ja>(context=MyRestContext.<jk>class</jk>)
- * <jk>public class</jk> MyResource {
- * ...
- * }
- * </p>
- * <p class='bcode w800'>
- * <ja>@Rest</ja>
- * <jk>public class</jk> MyResource {
- * ...
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
- * <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
- *
<jv>builder</jv>.context(MyRestContext.<jk>class</jk>);
- * }
- * }
- * </p>
- *
* @param value The new value for this setting.
* @return This object (for method chaining).
*/
@FluentSetter
- public RestContextBuilder context(Class<? extends RestContext> value) {
- return set(REST_context, value);
+ public RestContextBuilder contextClass(Class<? extends RestContext>
value) {
+ return set(REST_contextClass, value);
}
/**
@@ -1371,6 +1349,24 @@ public class RestContextBuilder extends
BeanContextBuilder implements ServletCon
}
/**
+ * <i><l>RestContext</l> configuration property: </i> REST method
context class.
+ *
+ * <p>
+ * Allows you to extend the {@link RestMethodContext} class to modify
how any of the methods are implemented.
+ *
+ * <ul class='seealso'>
+ * <li class='jf'>{@link RestContext#REST_methodContextClass}
+ * </ul>
+ *
+ * @param value The new value for this setting.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public RestContextBuilder methodContextClass(Class<? extends
RestMethodContext> value) {
+ return set(REST_methodContextClass, value);
+ }
+
+ /**
* <i><l>RestContext</l> configuration property: </i> Parser
listener.
*
* <p>
@@ -1628,6 +1624,42 @@ public class RestContextBuilder extends
BeanContextBuilder implements ServletCon
}
/**
+ * <i><l>RestContext</l> configuration property: </i> REST
children class.
+ *
+ * <p>
+ * Allows you to extend the {@link RestChildren} class to modify how
any of the methods are implemented.
+ *
+ * <ul class='seealso'>
+ * <li class='jf'>{@link RestContext#REST_restChildrenClass}
+ * </ul>
+ *
+ * @param value The new value for this setting.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public RestContextBuilder restChildrenClass(Class<? extends
RestChildren> value) {
+ return set(REST_restChildrenClass, value);
+ }
+
+ /**
+ * <i><l>RestContext</l> configuration property: </i> REST
methods class.
+ *
+ * <p>
+ * Allows you to extend the {@link RestMethods} class to modify how any
of the methods are implemented.
+ *
+ * <ul class='seealso'>
+ * <li class='jf'>{@link RestContext#REST_restMethodsClass}
+ * </ul>
+ *
+ * @param value The new value for this setting.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public RestContextBuilder restMethodsClass(Class<? extends RestMethods>
value) {
+ return set(REST_restMethodsClass, value);
+ }
+
+ /**
* <i><l>RestContext</l> configuration property: </i> Java method
parameter resolvers.
*
* <p>
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 1f1d218..59ec1cc 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
@@ -65,7 +65,7 @@ import org.apache.juneau.utils.*;
@ConfigurableContext(nocache=true)
public class RestMethodContext extends BeanContext implements
Comparable<RestMethodContext> {
- /** Represents a null value for the {@link RestMethod#context()}
annotation.*/
+ /** Represents a null value for the {@link RestMethod#contextClass()}
annotation.*/
@SuppressWarnings("javadoc")
public static final class Null extends RestMethodContext {
public Null(RestMethodContextBuilder builder) throws Exception {
@@ -168,18 +168,20 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
* Configuration property: REST method context class.
*
* <ul class='spaced-list'>
- * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestMethodContext#RESTMETHOD_context RESTMETHOD_context}
- * <li><b>Name:</b> <js>"RestMethodContext.context.c"</js>
+ * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestMethodContext#RESTMETHOD_contextClass
RESTMETHOD_contextClass}
+ * <li><b>Name:</b> <js>"RestMethodContext.contextClass.c"</js>
* <li><b>Data type:</b> <c>Class<? extends {@link
org.apache.juneau.rest.RestMethodContext}></c>
* <li><b>Default:</b> {@link
org.apache.juneau.rest.RestMethodContext}
* <li><b>Session property:</b> <jk>false</jk>
* <li><b>Annotations:</b>
* <ul>
- * <li class='ja'>{@link
org.apache.juneau.rest.annotation.RestMethod#context()}
+ * <li class='ja'>{@link
org.apache.juneau.rest.annotation.Rest#methodContextClass()}
+ * <li class='ja'>{@link
org.apache.juneau.rest.annotation.RestMethod#contextClass()}
* </ul>
* <li><b>Methods:</b>
* <ul>
- * <li class='jm'>{@link
org.apache.juneau.rest.RestMethodContextBuilder#context(Class)}
+ * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#methodContextClass(Class)}
+ * <li class='jm'>{@link
org.apache.juneau.rest.RestMethodContextBuilder#contextClass(Class)}
* </ul>
* </ul>
*
@@ -188,12 +190,48 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
* Allows you to extend the {@link RestMethodContext} class to modify
how any of the functions are implemented.
*
* <p>
- * The subclass must provide the following:
+ * The subclass must have a public constructor that takes in any of the
following arguments:
* <ul>
- * <li>A public constructor that takes in one parameter that
should be passed to the super constructor: {@link RestMethodContextBuilder}.
+ * <li>{@link RestMethodContextBuilder} - The builder for the
object.
+ * <li>Any beans found in the specified {@link #REST_beanFactory
bean factory}.
+ * <li>Any {@link Optional} beans that may or may not be found in
the specified {@link #REST_beanFactory bean factory}.
* </ul>
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode w800'>
+ * <jc>// Our extended context class that adds a request attribute
to all requests.</jc>
+ * <jc>// The attribute value is provided by an injected spring
bean.</jc>
+ * <jk>public</jk> MyRestMethodContext <jk>extends</jk>
RestMethodContext {
+ *
+ * <jk>private final</jk> Optional<? <jk>extends</jk>
Supplier<Object>> <jf>fooSupplier</jf>;
+ *
+ * <jc>// Constructor that takes in builder and optional
injected attribute provider.</jc>
+ * <jk>public</jk>
MyRestMethodContext(RestMethodContextBuilder <jv>builder</jv>,
Optional<AnInjectedFooSupplier> <jv>fooSupplier</jv>) {
+ * <jk>super</jk>(<jv>builder</jv>);
+ * <jk>this</jk>.<jf>fooSupplier</jf> =
<jv>fooSupplier</jv>.orElseGet(()-><jk>null</jk>);
+ * }
+ *
+ * <jc>// Override the method used to create default
request attributes.</jc>
+ * <ja>@Override</ja>
+ * <jk>protected</jk> NamedAttributeList
createDefaultRequestAttributes(Object <jv>resource</jv>, BeanFactory
<jv>beanFactory</jv>, Method <jv>method</jv>, RestContext <jv>context</jv>)
<jk>throws</jk> Exception {
+ * <jk>return super</jk>
+ *
.createDefaultRequestAttributes(<jv>resource</jv>, <jv>beanFactory</jv>,
<jv>method</jv>, <jv>context</jv>)
+ *
.append(NamedAttribute.<jsm>of</jsm>(<js>"foo"</js>,
()-><jf>fooSupplier</jf>.get());
+ * }
+ * }
+ * </p>
+ * <p class='bcode w800'>
+ * <ja>@Rest</ja>
+ * <jk>public class</jk> MyResource {
+ * ...
+ *
<ja>@RestMethod</ja>(contextClass=MyRestMethodContext.<jk>class</jk>)
+ * <jk>public</jk> Object getFoo(RequestAttributes
<jv>attributes</jv>) {
+ * <jk>return</jk>
<jv>attributes</jv>.get(<js>"foo"</js>);
+ * }
+ * }
+ * </p>
*/
- public static final String RESTMETHOD_context = PREFIX + ".context.c";
+ public static final String RESTMETHOD_contextClass = PREFIX +
".contextClass.c";
/**
* Configuration property: Debug mode.
@@ -675,6 +713,17 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
final int hierarchyDepth;
/**
+ * Creator.
+ *
+ * @param method The Java method this context belongs to.
+ * @param context The Java class context.
+ * @return A new builder.
+ */
+ public static RestMethodContextBuilder create(java.lang.reflect.Method
method, RestContext context) {
+ return new RestMethodContextBuilder(method, context);
+ }
+
+ /**
* Context constructor.
*
* @param builder The builder for this object.
@@ -693,7 +742,7 @@ public class RestMethodContext extends BeanContext
implements Comparable<RestMet
mi = MethodInfo.of(method).accessible();
Object r = context.getResource();
- beanFactory = new BeanFactory(context.rootBeanFactory,
r)
+ beanFactory = BeanFactory.of(context.rootBeanFactory, r)
.addBean(RestMethodContext.class, this)
.addBean(Method.class, method)
.addBean(PropertyStore.class, ps);
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
index 02824cd..a542074 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContextBuilder.java
@@ -39,23 +39,29 @@ public class RestMethodContextBuilder extends
BeanContextBuilder {
RestContext restContext;
Method restMethod;
+ private BeanFactory beanFactory;
+ private Class<? extends RestMethodContext> implClass;
+
@Override /* BeanContextBuilder */
public RestMethodContext build() {
try {
PropertyStore ps = getPropertyStore();
- Class<? extends RestMethodContext> c =
ps.getClassProperty(RESTMETHOD_context, RestMethodContext.class,
RestMethodContext.class);
- BeanFactory bf = new
BeanFactory(restContext.rootBeanFactory, restContext.getResource());
- bf.addBean(RestMethodContextBuilder.class, this);
- return bf.createBean(c);
+
+ Class<? extends RestMethodContext> ic = implClass;
+ if (ic == null)
+ ic =
ps.getClassProperty(RESTMETHOD_contextClass, RestMethodContext.class,
RestMethodContext.class);
+
+ return
BeanFactory.of(beanFactory).addBean(RestMethodContextBuilder.class,
this).createBean(ic);
} catch (Exception e) {
throw toHttpException(e, InternalServerError.class);
}
}
- RestMethodContextBuilder(java.lang.reflect.Method method, RestContext
context) throws RestServletException {
+ RestMethodContextBuilder(java.lang.reflect.Method method, RestContext
context) {
this.restContext = context;
this.restMethod = method;
+ this.beanFactory = context.rootBeanFactory;
String sig = method.getDeclaringClass().getName() + '.' +
method.getName();
MethodInfo mi = MethodInfo.of(context.getResource().getClass(),
method);
@@ -81,10 +87,8 @@ public class RestMethodContextBuilder extends
BeanContextBuilder {
applyAnnotations(mi.getAnnotationList(ConfigAnnotationFilter.INSTANCE), vrs);
- } catch (RestServletException e) {
- throw e;
} catch (Exception e) {
- throw new RestServletException(e, "Exception occurred
while initializing method ''{0}''", sig);
+ throw toHttpException(e, InternalServerError.class);
}
}
@@ -98,6 +102,40 @@ public class RestMethodContextBuilder extends
BeanContextBuilder {
return this;
}
+
+ /**
+ * Specifies a {@link RestMethodContext} implementation subclass to use.
+ *
+ * <p>
+ * When specified, the {@link #build()} method will create an instance
of that class instead of the default {@link RestMethodContext}.
+ *
+ * <p>
+ * The subclass must have a public constructor that takes in any of the
following arguments:
+ * <ul>
+ * <li>{@link RestMethodContextBuilder} - This object.
+ * <li>Any beans found in the specified {@link
#beanFactory(BeanFactory) bean factory}.
+ * <li>Any {@link Optional} beans that may or may not be found in
the specified {@link #beanFactory(BeanFactory) bean factory}.
+ * </ul>
+ *
+ * @param implClass The implementation class to build.
+ * @return This object (for method chaining).
+ */
+ public RestMethodContextBuilder implClass(Class<? extends
RestMethodContext> implClass) {
+ this.implClass = implClass;
+ return this;
+ }
+
+ /**
+ * Specifies a {@link BeanFactory} to use when resolving constructor
arguments.
+ *
+ * @param beanFactory The bean factory to use for resolving constructor
arguments.
+ * @return This object (for method chaining).
+ */
+ public RestMethodContextBuilder beanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ return this;
+ }
+
//----------------------------------------------------------------------------------------------------
// Properties
//----------------------------------------------------------------------------------------------------
@@ -135,8 +173,8 @@ public class RestMethodContextBuilder extends
BeanContextBuilder {
* @return This object (for method chaining).
*/
@FluentSetter
- public RestMethodContextBuilder context(Class<? extends
RestMethodContext> value) {
- return set(RESTMETHOD_context, value);
+ public RestMethodContextBuilder contextClass(Class<? extends
RestMethodContext> value) {
+ return set(RESTMETHOD_contextClass, value);
}
/**
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethods.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethods.java
index 2690e28..f9558ce 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethods.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethods.java
@@ -23,6 +23,16 @@ import org.apache.juneau.rest.annotation.*;
*/
public class RestMethods {
+ /**
+ * Represents a null value for the {@link Rest#restMethodsClass()}
annotation.
+ */
+ @SuppressWarnings("javadoc")
+ public final class Null extends RestMethods {
+ public Null(RestMethodsBuilder builder) throws Exception {
+ super(builder);
+ }
+ }
+
private final Map<String,List<RestMethodContext>> map;
private List<RestMethodContext> list;
@@ -35,7 +45,12 @@ public class RestMethods {
return new RestMethodsBuilder();
}
- RestMethods(RestMethodsBuilder builder) {
+ /**
+ * Constructor.
+ *
+ * @param builder The builder containing the settings for this object.
+ */
+ public RestMethods(RestMethodsBuilder builder) {
AMap<String,List<RestMethodContext>> m = AMap.create();
for (Map.Entry<String,TreeSet<RestMethodContext>> e :
builder.map.entrySet())
m.put(e.getKey(), AList.of(e.getValue()));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodsBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodsBuilder.java
index 1c7f97f..ef47f57 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodsBuilder.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodsBuilder.java
@@ -12,9 +12,14 @@
//
***************************************************************************************************************************
package org.apache.juneau.rest;
+import static org.apache.juneau.internal.ObjectUtils.*;
+import static org.apache.juneau.rest.HttpRuntimeException.*;
+
import java.util.*;
import org.apache.juneau.collections.*;
+import org.apache.juneau.cp.*;
+import org.apache.juneau.http.exception.*;
/**
* Builder for {@link RestMethods} object.
@@ -24,6 +29,23 @@ public class RestMethodsBuilder {
TreeMap<String,TreeSet<RestMethodContext>> map = new TreeMap<>();
Set<RestMethodContext> set = ASet.of();
+ private BeanFactory beanFactory;
+ private Class<? extends RestMethods> implClass;
+
+ /**
+ * Instantiates a {@link RestMethods} object based on the contents of
this builder.
+ *
+ * @return A new {@link RestMethods} object.
+ */
+ public RestMethods build() {
+ try {
+ Class<? extends RestMethods> ic =
firstNonNull(implClass, RestMethods.class);
+ return
BeanFactory.of(beanFactory).addBean(RestMethodsBuilder.class,
this).createBean(ic);
+ } catch (Exception e) {
+ throw toHttpException(e, InternalServerError.class);
+ }
+ }
+
/**
* Adds a method context to this builder.
*
@@ -51,11 +73,35 @@ public class RestMethodsBuilder {
}
/**
- * Creates a new {@link RestMethods} object using the contents of this
builder.
+ * Specifies a {@link RestMethods} implementation subclass to use.
*
- * @return A new {@link RestMethods} object.
+ * <p>
+ * When specified, the {@link #build()} method will create an instance
of that class instead of the default {@link RestMethods}.
+ *
+ * <p>
+ * The subclass must have a public constructor that takes in any of the
following arguments:
+ * <ul>
+ * <li>{@link RestMethodsBuilder} - This object.
+ * <li>Any beans found in the specified {@link
#beanFactory(BeanFactory) bean factory}.
+ * <li>Any {@link Optional} beans that may or may not be found in
the specified {@link #beanFactory(BeanFactory) bean factory}.
+ * </ul>
+ *
+ * @param implClass The implementation class to build.
+ * @return This object (for method chaining).
*/
- public RestMethods build() {
- return new RestMethods(this);
+ public RestMethodsBuilder implClass(Class<? extends RestMethods>
implClass) {
+ this.implClass = implClass;
+ return this;
+ }
+
+ /**
+ * Specifies a {@link BeanFactory} to use when resolving constructor
arguments.
+ *
+ * @param beanFactory The bean factory to use for resolving constructor
arguments.
+ * @return This object (for method chaining).
+ */
+ public RestMethodsBuilder beanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ return this;
}
}
\ No newline at end of file
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
index 05187e2..bff6623 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
@@ -74,7 +74,7 @@ public abstract class RestServlet extends HttpServlet {
* @return A new bean factory.
*/
public BeanFactory createBeanFactory(Optional<BeanFactory> parent) {
- return new BeanFactory(parent.orElse(null), this);
+ return BeanFactory.of(parent.orElse(null), this);
}
/**
@@ -101,7 +101,7 @@ public abstract class RestServlet extends HttpServlet {
public synchronized String getPath() {
RestContext context = this.context.get();
if (context != null)
- return context.getPath();
+ return context.getFullPath();
ClassInfo ci = ClassInfo.of(getClass());
String path = "";
for (Rest rr : ci.getAnnotations(Rest.class))
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
index b1eedd1..ec3470e 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
@@ -271,39 +271,16 @@ public @interface Rest {
String[] consumes() default {};
/**
- * Allows you to extend the {@link RestContext} class to modify how any
of the methods are implemented.
+ * REST context class.
*
- * <review>NEEDS REVIEW</review>
* <p>
- * The subclass must provide the following:
- * <ul>
- * <li>A public constructor that takes in one parameter that
should be passed to the super constructor: {@link RestContextBuilder}.
- * </ul>
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode w800'>
- * <jc>// Our extended context class</jc>
- * <jk>public</jk> MyRestContext <jk>extends</jk> RestContext {
- * <jk>public</jk> MyRestContext(RestContextBuilder
<jv>builder</jv>) {
- * <jk>super</jk>(<jv>builder</jv>);
- * }
- *
- * // Override any methods.
- * }
- * </p>
- * <p class='bcode w800'>
- * <jc>// Our REST class</jc>
- * <ja>@Rest</ja>(context=MyRestContext.<jk>class</jk>)
- * <jk>public class</jk> MyResource {
- * ...
- * }
- * </p>
+ * Allows you to extend the {@link RestContext} class to modify how any
of the methods are implemented.
*
* <ul class='seealso'>
- * <li class='jm'>{@link RestContextBuilder#context(Class)}
+ * <li class='jm'>{@link RestContext#REST_contextClass}
* </ul>
*/
- Class<? extends RestContext> context() default RestContext.Null.class;
+ Class<? extends RestContext> contextClass() default
RestContext.Null.class;
/**
* Class-level response converters.
@@ -730,6 +707,15 @@ public @interface Rest {
String messages() default "";
/**
+ * Allows you to extend the {@link RestMethodContext} class to modify
how any of the methods are implemented.
+ *
+ * <ul class='seealso'>
+ * <li class='jf'>{@link RestContext#REST_methodContextClass}
+ * </ul>
+ */
+ Class<? extends RestMethodContext> methodContextClass() default
RestMethodContext.Null.class;
+
+ /**
* Dynamically apply this annotation to the specified classes.
*
* <ul class='seealso'>
@@ -974,6 +960,30 @@ public @interface Rest {
Class<? extends ResponseHandler>[] responseHandlers() default {};
/**
+ * REST children class.
+ *
+ * <p>
+ * Allows you to extend the {@link RestChildren} class to modify how
any of the methods are implemented.
+ *
+ * <ul class='seealso'>
+ * <li class='jf'>{@link RestContext#REST_restChildrenClass}
+ * </ul>
+ */
+ Class<? extends RestChildren> restChildrenClass() default
RestChildren.Null.class;
+
+ /**
+ * REST methods class.
+ *
+ * <p>
+ * Allows you to extend the {@link RestMethods} class to modify how any
of the methods are implemented.
+ *
+ * <ul class='seealso'>
+ * <li class='jf'>{@link RestContext#REST_restMethodsClass}
+ * </ul>
+ */
+ Class<? extends RestMethods> restMethodsClass() default
RestMethods.Null.class;
+
+ /**
* Java method parameter resolvers.
*
* <p>
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
index 8e7f88b..f0cb789 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
@@ -90,12 +90,15 @@ public class RestAnnotation {
Class<? extends StaticFiles> staticFiles =
StaticFiles.Null.class;
Class<? extends ResponseHandler>[] responseHandlers = new
Class[0];
Class<? extends RestLogger> callLogger = RestLogger.Null.class;
- Class<? extends RestContext> context = RestContext.Null.class;
+ Class<? extends RestContext> contextClass =
RestContext.Null.class;
Class<? extends RestConverter>[] converters = new Class[0];
Class<? extends RestGuard>[] guards = new Class[0];
Class<? extends RestInfoProvider>
infoProvider=RestInfoProvider.Null.class;
Class<? extends RestParam>[] restParams = new Class[0];
Class<? extends BeanFactory> beanFactory =
BeanFactory.Null.class;
+ Class<? extends RestMethodContext> methodContextClass =
RestMethodContext.Null.class;
+ Class<? extends RestChildren> restChildrenClass =
RestChildren.Null.class;
+ Class<? extends RestMethods> restMethodsClass =
RestMethods.Null.class;
Class<?>[] children={}, parsers={}, serializers={};
ResourceSwagger swagger = ResourceSwaggerAnnotation.DEFAULT;
String disableAllowBodyParam="", allowedHeaderParams="",
allowedMethodHeaders="", allowedMethodParams="", clientVersionHeader="",
config="", debug="", debugOn="", defaultAccept="", defaultCharset="",
defaultContentType="", maxInput="", messages="", path="",
renderResponseStackTraces="", roleGuard="", rolesDeclared="", siteName="",
uriAuthority="", uriContext="", uriRelativity="", uriResolution="";
@@ -228,13 +231,13 @@ public class RestAnnotation {
}
/**
- * Sets the {@link Rest#context()} property on this annotation.
+ * Sets the {@link Rest#contextClass()} property on this
annotation.
*
* @param value The new value for this property.
* @return This object (for method chaining).
*/
- public Builder context(Class<? extends RestContext> value) {
- this.context = value;
+ public Builder contextClass(Class<? extends RestContext> value)
{
+ this.contextClass = value;
return this;
}
@@ -415,6 +418,17 @@ public class RestAnnotation {
}
/**
+ * Sets the {@link Rest#methodContextClass()} property on this
annotation.
+ *
+ * @param value The new value for this property.
+ * @return This object (for method chaining).
+ */
+ public Builder methodContextClass(Class<? extends
RestMethodContext> value) {
+ this.methodContextClass = value;
+ return this;
+ }
+
+ /**
* Sets the {@link Rest#parsers()} property on this annotation.
*
* @param value The new value for this property.
@@ -492,6 +506,28 @@ public class RestAnnotation {
}
/**
+ * Sets the {@link Rest#restChildrenClass()} property on this
annotation.
+ *
+ * @param value The new value for this property.
+ * @return This object (for method chaining).
+ */
+ public Builder restChildrenClass(Class<? extends RestChildren>
value) {
+ this.restChildrenClass = value;
+ return this;
+ }
+
+ /**
+ * Sets the {@link Rest#restMethodsClass()} property on this
annotation.
+ *
+ * @param value The new value for this property.
+ * @return This object (for method chaining).
+ */
+ public Builder restMethodsClass(Class<? extends RestMethods>
value) {
+ this.restMethodsClass = value;
+ return this;
+ }
+
+ /**
* Sets the {@link Rest#restParams()} property on this
annotation.
*
* @param value The new value for this property.
@@ -655,12 +691,15 @@ public class RestAnnotation {
private final Class<? extends StaticFiles> staticFiles;
private final Class<? extends ResponseHandler>[]
responseHandlers;
private final Class<? extends RestLogger> callLogger;
- private final Class<? extends RestContext> context;
+ private final Class<? extends RestContext> contextClass;
private final Class<? extends RestConverter>[] converters;
private final Class<? extends RestGuard>[] guards;
private final Class<? extends RestInfoProvider> infoProvider;
private final Class<? extends RestParam>[] restParams;
private final Class<? extends BeanFactory> beanFactory;
+ private final Class<? extends RestMethodContext>
methodContextClass;
+ private final Class<? extends RestChildren> restChildrenClass;
+ private final Class<? extends RestMethods> restMethodsClass;
private final Class<?>[] children, parsers, serializers;
private final ResourceSwagger swagger;
private final String disableAllowBodyParam,
allowedHeaderParams, allowedMethodHeaders, allowedMethodParams,
clientVersionHeader, config, debug, debugOn, defaultAccept, defaultCharset,
defaultContentType, maxInput, messages, path, renderResponseStackTraces,
roleGuard, rolesDeclared, siteName, uriAuthority, uriContext, uriRelativity,
uriResolution;
@@ -678,7 +717,7 @@ public class RestAnnotation {
this.clientVersionHeader = b.clientVersionHeader;
this.config = b.config;
this.consumes = copyOf(b.consumes);
- this.context = b.context;
+ this.contextClass = b.contextClass;
this.converters = copyOf(b.converters);
this.debug = b.debug;
this.debugOn = b.debugOn;
@@ -695,6 +734,9 @@ public class RestAnnotation {
this.infoProvider = b.infoProvider;
this.maxInput = b.maxInput;
this.messages = b.messages;
+ this.methodContextClass = b.methodContextClass;
+ this.restChildrenClass = b.restChildrenClass;
+ this.restMethodsClass = b.restMethodsClass;
this.restParams = copyOf(b.restParams);
this.parsers = copyOf(b.parsers);
this.partParser = b.partParser;
@@ -768,8 +810,8 @@ public class RestAnnotation {
}
@Override /* Rest */
- public Class<? extends RestContext> context() {
- return context;
+ public Class<? extends RestContext> contextClass() {
+ return contextClass;
}
@Override /* Rest */
@@ -853,6 +895,11 @@ public class RestAnnotation {
}
@Override /* Rest */
+ public Class<? extends RestMethodContext> methodContextClass() {
+ return methodContextClass;
+ }
+
+ @Override /* Rest */
public Class<?>[] parsers() {
return parsers;
}
@@ -888,6 +935,16 @@ public class RestAnnotation {
}
@Override /* Rest */
+ public Class<? extends RestChildren> restChildrenClass() {
+ return restChildrenClass;
+ }
+
+ @Override /* Rest */
+ public Class<? extends RestMethods> restMethodsClass() {
+ return restMethodsClass;
+ }
+
+ @Override /* Rest */
public Class<? extends RestParam>[] restParams() {
return restParams;
}
@@ -985,7 +1042,7 @@ public class RestAnnotation {
psb.prependTo(REST_guards, reverse(a.guards()));
psb.prependTo(REST_children, a.children());
psb.prependTo(REST_restParams, a.restParams());
- psb.setIf(a.context() != RestContext.Null.class,
REST_context, a.context());
+ psb.setIf(a.contextClass() != RestContext.Null.class,
REST_contextClass, a.contextClass());
psb.setIfNotEmpty(REST_uriContext,
string(a.uriContext()));
psb.setIfNotEmpty(REST_uriAuthority,
string(a.uriAuthority()));
psb.setIfNotEmpty(REST_uriRelativity,
string(a.uriRelativity()));
@@ -998,6 +1055,9 @@ public class RestAnnotation {
psb.setIf(a.beanFactory() != BeanFactory.Null.class,
REST_beanFactory, a.beanFactory());
psb.setIf(a.callLogger() != RestLogger.Null.class,
REST_callLogger, a.callLogger());
psb.setIf(a.infoProvider() !=
RestInfoProvider.Null.class, REST_infoProvider, a.infoProvider());
+ psb.setIf(a.methodContextClass() !=
RestMethodContext.Null.class, REST_methodContextClass, a.methodContextClass());
+ psb.setIf(a.restChildrenClass() !=
RestChildren.Null.class, REST_restChildrenClass, a.restChildrenClass());
+ psb.setIf(a.restMethodsClass() !=
RestMethods.Null.class, REST_restMethodsClass, a.restMethodsClass());
psb.setIfNotEmpty(REST_disableAllowBodyParam,
bool(a.disableAllowBodyParam()));
psb.setIfNotEmpty(REST_allowedHeaderParams,
string(a.allowedHeaderParams()));
psb.setIfNotEmpty(REST_allowedMethodHeaders,
string(a.allowedMethodHeaders()));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index 7f0ed4a..7b9c113 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -126,10 +126,10 @@ public @interface RestMethod {
* </ul>
*
* <ul class='seealso'>
- * <li class='jm'>{@link RestMethodContextBuilder#context(Class)}
+ * <li class='jm'>{@link
RestMethodContextBuilder#contextClass(Class)}
* </ul>
*/
- Class<? extends RestMethodContext> context() default
RestMethodContext.Null.class;
+ Class<? extends RestMethodContext> contextClass() default
RestMethodContext.Null.class;
/**
* Class-level response converters.
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
index db221bf..9db07dd 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
@@ -61,7 +61,7 @@ public class RestMethodAnnotation {
Class<? extends RestConverter>[] converters = new Class[0];
Class<? extends RestGuard>[] guards = new Class[0];
Class<? extends RestMatcher>[] matchers = new Class[0];
- Class<? extends RestMethodContext> context =
RestMethodContext.Null.class;
+ Class<? extends RestMethodContext> contextClass =
RestMethodContext.Null.class;
Class<?>[] encoders=new Class<?>[0], parsers=new Class<?>[0],
serializers=new Class<?>[0];
int priority = 0;
MethodSwagger swagger = MethodSwaggerAnnotation.DEFAULT;
@@ -107,13 +107,13 @@ public class RestMethodAnnotation {
}
/**
- * Sets the {@link RestMethod#context()} property on this
annotation.
+ * Sets the {@link RestMethod#contextClass()} property on this
annotation.
*
* @param value The new value for this property.
* @return This object (for method chaining).
*/
- public Builder context(Class<? extends RestMethodContext>
value) {
- this.context = value;
+ public Builder contextClass(Class<? extends RestMethodContext>
value) {
+ this.contextClass = value;
return this;
}
@@ -425,7 +425,7 @@ public class RestMethodAnnotation {
private final Class<? extends RestConverter>[] converters;
private final Class<? extends RestGuard>[] guards;
private final Class<? extends RestMatcher>[] matchers;
- private final Class<? extends RestMethodContext> context;
+ private final Class<? extends RestMethodContext> contextClass;
private final Class<?>[] encoders, parsers, serializers;
private final int priority;
private final MethodSwagger swagger;
@@ -436,7 +436,7 @@ public class RestMethodAnnotation {
super(b);
this.clientVersion = b.clientVersion;
this.consumes = copyOf(b.consumes);
- this.context = b.context;
+ this.contextClass = b.contextClass;
this.converters = copyOf(b.converters);
this.debug = b.debug;
this.defaultAccept = b.defaultAccept;
@@ -477,8 +477,8 @@ public class RestMethodAnnotation {
}
@Override /* RestMethod */
- public Class<? extends RestMethodContext> context() {
- return context;
+ public Class<? extends RestMethodContext> contextClass() {
+ return contextClass;
}
@Override /* RestMethod */
@@ -634,7 +634,7 @@ public class RestMethodAnnotation {
psb.set(REST_serializers,
merge(ConverterUtils.toType(psb.peek(REST_serializers), Object[].class),
a.serializers()));
psb.set(REST_parsers,
merge(ConverterUtils.toType(psb.peek(REST_parsers), Object[].class),
a.parsers()));
psb.set(REST_encoders,
merge(ConverterUtils.toType(psb.peek(REST_encoders), Object[].class),
a.encoders()));
- psb.setIf(a.context() != RestMethodContext.Null.class,
RESTMETHOD_context, a.context());
+ psb.setIf(a.contextClass() !=
RestMethodContext.Null.class, RESTMETHOD_contextClass, a.contextClass());
psb.setIfNotEmpty(REST_produces,
stringList(a.produces()));
psb.setIfNotEmpty(REST_consumes,
stringList(a.consumes()));
stringStream(a.defaultRequestHeaders()).map(x ->
BasicHeader.ofPair(x)).forEach(x ->
psb.appendTo(RESTMETHOD_defaultRequestHeaders, x));
diff --git a/pom.xml b/pom.xml
index 3813479..c8f3260 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,7 @@
<derby.version>10.10.2.0</derby.version>
<hibernate.version>5.0.9.Final</hibernate.version>
<javax.inject.version>1</javax.inject.version>
- <springframework.version>2.0.1.RELEASE</springframework.version>
+ <springboot.version>2.4.2</springboot.version>
<xml.apis.version>1.4.01</xml.apis.version>
</properties>