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 4ba1b00  REST refactoring.
4ba1b00 is described below

commit 4ba1b00b4d3934dfc97c1fd2dc51584171c98c15
Author: JamesBognar <[email protected]>
AuthorDate: Fri Jan 8 14:56:59 2021 -0500

    REST refactoring.
---
 .../juneau/http/SerializedHttpEntity_Test.java     |    2 +-
 .../org/apache/juneau/http/remote/Remote_Test.java |    4 +-
 .../java/org/apache/juneau/cp/BeanFactory.java     |  143 +++
 .../juneau/examples/rest/HelloWorldResource.java   |    3 +-
 .../juneau/examples/rest/RequestEchoResource.java  |    2 +-
 .../client/BasicHttpRequestRetryHandler_Test.java  |    2 +-
 .../juneau/rest/client/RestCallException_Test.java |    2 +-
 .../rest/client/RestClient_BasicCalls_Test.java    |    2 +-
 .../juneau/rest/client/RestClient_Body_Test.java   |    2 +-
 .../client/RestClient_Config_BeanContext_Test.java |    4 +-
 .../client/RestClient_Config_Context_Test.java     |    2 +-
 .../client/RestClient_Config_OpenApi_Test.java     |    2 +-
 .../rest/client/RestClient_Config_Parser_Test.java |    2 +-
 .../client/RestClient_Config_RestClient_Test.java  |    4 +-
 .../client/RestClient_Config_Serializer_Test.java  |    2 +-
 .../rest/client/RestClient_FormData_Test.java      |    2 +-
 .../rest/client/RestClient_Headers_Test.java       |    2 +-
 .../rest/client/RestClient_Logging_Test.java       |    2 +-
 .../rest/client/RestClient_Marshalls_Test.java     |    2 +-
 .../juneau/rest/client/RestClient_Paths_Test.java  |    2 +-
 .../juneau/rest/client/RestClient_Query_Test.java  |    2 +-
 .../rest/client/RestClient_Response_Body_Test.java |    2 +-
 .../client/RestClient_Response_Headers_Test.java   |    2 +-
 .../rest/client/RestClient_Response_Test.java      |    6 +-
 .../apache/juneau/rest/client/RestClient_Test.java |    4 +-
 .../rest/springboot/BasicSpringRestServlet.java}   |   70 +-
 .../springboot/BasicSpringRestServletGroup.java}   |   20 +-
 .../juneau/rest/springboot/SpringBeanFactory.java} |   91 +-
 .../juneau/rest/springboot/SpringRestServlet.java} |   78 +-
 .../juneau/rest/annotation/Rest_Debug_Test.java    |    2 +-
 .../org/apache/juneau/rest/BasicRestObject.java    |   83 ++
 ...sicRestGroup.java => BasicRestObjectGroup.java} |    2 +-
 .../org/apache/juneau/rest/BasicRestServlet.java   |   62 --
 .../java/org/apache/juneau/rest/RestContext.java   |   22 +-
 .../org/apache/juneau/rest/RestContextBuilder.java |    4 +-
 .../rest/{BasicRest.java => RestObject.java}       | 1096 ++++++++++----------
 .../java/org/apache/juneau/rest/RestServlet.java   |   64 +-
 .../org/apache/juneau/rest/annotation/Rest.java    |   14 +-
 38 files changed, 951 insertions(+), 861 deletions(-)

diff --git 
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
 
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
index b8bc079..935f5ae 100644
--- 
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
+++ 
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
@@ -38,7 +38,7 @@ import org.junit.*;
 public class SerializedHttpEntity_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public String[] 
postCheckHeader(org.apache.juneau.rest.RestRequest req) {
                        return req.getHeaders().get(req.getHeader("Check"));
diff --git 
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
 
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
index 4c51368..7f04a11 100644
--- 
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
+++ 
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
@@ -518,7 +518,7 @@ public class Remote_Test {
        
//-----------------------------------------------------------------------------------------------------------------
 
        @Rest
-       public static class F extends BasicRest {
+       public static class F extends BasicRestObject {
                @RestMethod
                public String[] getHeaders(org.apache.juneau.rest.RestRequest 
req) {
                        return req.getHeaders().get(req.getHeader("Check"));
@@ -566,7 +566,7 @@ public class Remote_Test {
        
//-----------------------------------------------------------------------------------------------------------------
 
        @Rest
-       public static class G extends BasicRest {}
+       public static class G extends BasicRestObject {}
 
        @Remote
        public static interface G1 {
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
new file mode 100644
index 0000000..d635e12
--- /dev/null
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
@@ -0,0 +1,143 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                
                                              *
+// *                                                                           
                                              *
+// *  http://www.apache.org/licenses/LICENSE-2.0                               
                                              *
+// *                                                                           
                                              *
+// * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the 
License.                                              *
+// 
***************************************************************************************************************************
+package org.apache.juneau.cp;
+
+import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.reflect.ReflectFlags.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.reflect.*;
+
+/**
+ * Factory for creating beans.
+ */
+public class BeanFactory {
+
+       private final Map<Class<?>,Object> beanMap = new ConcurrentHashMap<>();
+       private final BeanFactory parent;
+       private final Object outer;
+
+       /**
+        * Default constructor.
+        */
+       public BeanFactory() {
+               this.parent = null;
+               this.outer = null;
+       }
+
+       /**
+        * Constructor.
+        *
+        * @param parent - Optional parent bean factory.
+        * @param outer Outer bean context to use when instantiating local 
classes.
+        */
+       public BeanFactory(BeanFactory parent, Object outer) {
+               this.parent = parent;
+               this.outer = outer;
+       }
+
+       /**
+        * Returns the bean of the specified type.
+        *
+        * @param <T> The type of bean to return.
+        * @param c The type of bean to return.
+        * @return The bean.
+        */
+       @SuppressWarnings("unchecked")
+       public <T> Optional<T> getBean(Class<T> c) {
+               T t = (T)beanMap.get(c);
+               if (t == null && parent != null)
+                       return parent.getBean(c);
+               return Optional.ofNullable(t);
+       }
+
+
+       /**
+        * Adds a bean of the specified type to this factory.
+        *
+        * @param <T> The class to associate this bean with.
+        * @param c The class to associate this bean with.
+        * @param t The bean.
+        * @return This object (for method chaining).
+        */
+       public <T> BeanFactory addBean(Class<T> c, T t) {
+               beanMap.put(c, t);
+               return this;
+       }
+
+       /**
+        * Returns <jk>true</jk> if this factory contains the specified bean 
type instance.
+        *
+        * @param <T> The bean type to check.
+        * @param c The bean type to check.
+        * @return <jk>true</jk> if this factory contains the specified bean 
type instance.
+        */
+       public <T> boolean hasBean(Class<T> c) {
+               return getBean(c).isPresent();
+       }
+
+       /**
+        * Creates a bean of the specified type.
+        *
+        * @param <T> The bean type to create.
+        * @param c The bean type to create.
+        * @return A newly-created bean.
+        * @throws ExecutableException If bean could not be created.
+        */
+       public <T> T createBean(Class<T> c) throws ExecutableException {
+
+               ClassInfo ci = ClassInfo.of(c);
+
+               for (MethodInfo m : ci.getPublicMethods()) {
+                       if (m.isAll(STATIC, NOT_DEPRECATED) && 
m.hasReturnType(c) && hasAllParamTypes(m.getParamTypes())) {
+                               String n = m.getSimpleName();
+                               if (isOneOf(n, "create","getInstance"))
+                                       return m.invoke(null, 
getParams(m.getParamTypes()));
+                       }
+               }
+
+               if (ci.isInterface())
+                       throw new ExecutableException("Could not instantiate 
class {0} because it is an interface.", c.getName());
+               if (ci.isAbstract())
+                       throw new ExecutableException("Could not instantiate 
class {0} because it is abstract.", c.getName());
+
+               for (ConstructorInfo cc : ci.getPublicConstructors())
+                       if (hasAllParamTypes(cc.getParamTypes()))
+                               return cc.invoke(getParams(cc.getParamTypes()));
+
+               throw new ExecutableException("Could not instantiate class {0}. 
 Constructor or creator not found.", c.getName());
+       }
+
+       private boolean hasAllParamTypes(List<ClassInfo> paramTypes) {
+               for (ClassInfo ci : paramTypes)
+                       if (! hasBean(ci.inner()))
+                               if (outer == null || ! 
ci.inner().isInstance(outer))
+                                       return false;
+               return true;
+       }
+
+       private Object[] getParams(List<ClassInfo> paramTypes) {
+               Object[] o = new Object[paramTypes.size()];
+               for (int i = 0; i < paramTypes.size(); i++) {
+                       ClassInfo pt = paramTypes.get(i);
+                       if (i == 0 && pt.inner().isInstance(outer))
+                               o[i] = outer;
+                       else
+                               o[i] = getBean(paramTypes.get(i).inner());
+               }
+               return o;
+       }
+}
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
index 4c23d56..318fd57 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
@@ -17,7 +17,6 @@ import static org.apache.juneau.http.HttpMethod.*;
 import org.apache.juneau.html.annotation.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.config.*;
 
 /**
  * Sample REST resource that prints out a simple "Hello world!" message.
@@ -39,7 +38,7 @@ import org.apache.juneau.rest.config.*;
                "</div>"
        }
 )
-public class HelloWorldResource extends BasicRest implements 
BasicUniversalRest {
+public class HelloWorldResource extends BasicRestObject {
 
        /**
         * GET request handler.
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
index 4485ce8..4a5a616 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
@@ -77,7 +77,7 @@ import org.apache.juneau.transforms.*;
 @Bean(on="HttpServletRequest",interfaceClass=HttpServletRequest.class)
 @Bean(on="HttpSession",interfaceClass=HttpSession.class)
 @Bean(on="ServletContext",interfaceClass=ServletContext.class)
-public class RequestEchoResource extends BasicRest {
+public class RequestEchoResource extends BasicRestObject {
 
        /**
         * GET request handler.
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/BasicHttpRequestRetryHandler_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/BasicHttpRequestRetryHandler_Test.java
index 659ff5b..a52434b 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/BasicHttpRequestRetryHandler_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/BasicHttpRequestRetryHandler_Test.java
@@ -29,7 +29,7 @@ import org.junit.*;
 public class BasicHttpRequestRetryHandler_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public Ok get() {
                        return Ok.OK;
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestCallException_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestCallException_Test.java
index eec81d1..8f39bfb 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestCallException_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestCallException_Test.java
@@ -43,7 +43,7 @@ public class RestCallException_Test {
        }
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public InputStream postEcho(InputStream is) {
                        return is;
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
index c4f697a..6428872 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
@@ -52,7 +52,7 @@ public class RestClient_BasicCalls_Test {
        private static ABean bean = ABean.get();
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/bean")
                public ABean getBean() {
                        return bean;
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
index 871dab4..312ea51 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
@@ -33,7 +33,7 @@ import org.junit.*;
 public class RestClient_Body_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public Reader post(org.apache.juneau.rest.RestRequest req, 
org.apache.juneau.rest.RestResponse res) throws IOException {
                        for (Map.Entry<String,String[]> e : 
req.getHeaders().entrySet()) {
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
index c43135b..53b2d59 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
@@ -34,7 +34,7 @@ import org.junit.*;
 public class RestClient_Config_BeanContext_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/echoBody")
                public Reader postEchoBody(org.apache.juneau.rest.RestRequest 
req) throws IOException {
                        return req.getBody().getReader();
@@ -87,7 +87,7 @@ public class RestClient_Config_BeanContext_Test {
        }
 
        @Rest
-       public static class A2b extends BasicRest {
+       public static class A2b extends BasicRestObject {
                @RestMethod
                public Reader postTest(org.apache.juneau.rest.RestRequest 
req,org.apache.juneau.rest.RestResponse res) throws IOException {
                        res.setHeader("X",req.getHeaders().getString("X"));
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
index 0e77869..ca37bde 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
@@ -36,7 +36,7 @@ import org.junit.*;
 public class RestClient_Config_Context_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/echoBody")
                public Reader postEchoBody(org.apache.juneau.rest.RestRequest 
req) throws IOException {
                        return req.getBody().getReader();
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
index 0fc4135..7d6d618 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
@@ -29,7 +29,7 @@ import org.junit.*;
 public class RestClient_Config_OpenApi_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/echoBody")
                public Reader postEchoBody(org.apache.juneau.rest.RestRequest 
req) throws IOException {
                        return req.getBody().getReader();
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Parser_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Parser_Test.java
index f9969fb..69c42f9 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Parser_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Parser_Test.java
@@ -27,7 +27,7 @@ import org.junit.*;
 public class RestClient_Config_Parser_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/echoBody")
                public Reader postEchoBody(org.apache.juneau.rest.RestRequest 
req) throws IOException {
                        return req.getBody().getReader();
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
index 6cc813e..227f0ef 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
@@ -62,7 +62,7 @@ public class RestClient_Config_RestClient_Test {
        private static ABean bean = ABean.get();
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/bean")
                public ABean getBean() {
                        return bean;
@@ -441,7 +441,7 @@ public class RestClient_Config_RestClient_Test {
        }
 
        @Rest(partSerializer=A12a.class,partParser=A12b.class)
-       public static class A12 extends BasicRest {
+       public static class A12 extends BasicRestObject {
                @RestMethod(path="/")
                public Ok get(@Header(name="Foo",multi=true) ABean[] 
foo,org.apache.juneau.rest.RestRequest req,org.apache.juneau.rest.RestResponse 
res) throws Exception {
                        assertEquals(2,foo.length);
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Serializer_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Serializer_Test.java
index 229cadd..2ec2961 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Serializer_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Serializer_Test.java
@@ -41,7 +41,7 @@ public class RestClient_Config_Serializer_Test {
        private static ABean bean = ABean.get();
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/echoBody")
                public Reader postEchoBody(org.apache.juneau.rest.RestRequest 
req) throws IOException {
                        return req.getBody().getReader();
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_FormData_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_FormData_Test.java
index 7c75d67..07f45a4 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_FormData_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_FormData_Test.java
@@ -38,7 +38,7 @@ import org.junit.*;
 public class RestClient_FormData_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public Reader postFormData(org.apache.juneau.rest.RestRequest 
req) {
                        return new 
StringReader(req.getFormData().asQueryString());
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Headers_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Headers_Test.java
index aa45750..e193b17 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Headers_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Headers_Test.java
@@ -55,7 +55,7 @@ public class RestClient_Headers_Test {
        private static ABean bean = ABean.get();
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public String[] getHeaders(org.apache.juneau.rest.RestRequest 
req) {
                        return req.getHeaders().get(req.getHeader("Check"));
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Logging_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Logging_Test.java
index 8f0d509..e2fd9f3 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Logging_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Logging_Test.java
@@ -40,7 +40,7 @@ public class RestClient_Logging_Test {
        private static ABean bean = ABean.get();
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public ABean postBean(@Body ABean b) {
                        return b;
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java
index 6f15000..5d96f7c 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java
@@ -49,7 +49,7 @@ public class RestClient_Marshalls_Test {
        public static Bean bean = Bean.create();
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public Bean postA01(@Body Bean b, @Header("Accept") String 
accept, @Header("Content-Type") String ct, @Header("X-Accept") String xaccept, 
@Header("X-Content-Type") String xct) {
                        assertEquals("Accept doesn't 
match",nn(xaccept),nn(accept));
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Paths_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Paths_Test.java
index 604982a..90277c9 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Paths_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Paths_Test.java
@@ -28,7 +28,7 @@ import org.junit.*;
 public class RestClient_Paths_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/echo/*")
                public String getEcho(org.apache.juneau.rest.RestRequest req) {
                        return req.toString();
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Query_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Query_Test.java
index 4798937..220a0de 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Query_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Query_Test.java
@@ -37,7 +37,7 @@ import org.junit.*;
 public class RestClient_Query_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public Reader getQuery(org.apache.juneau.rest.RestRequest req) {
                        return new StringReader(req.getQuery().asQueryString());
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
index 77a2b84..1ab9d0a 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
@@ -53,7 +53,7 @@ public class RestClient_Response_Body_Test {
        private static ABean bean = ABean.get();
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public InputStream postEcho(InputStream is) {
                        return is;
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
index 0de6d24..9232345 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
@@ -33,7 +33,7 @@ import org.junit.*;
 public class RestClient_Response_Headers_Test {
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod
                public String getEcho(org.apache.juneau.rest.RestRequest req, 
org.apache.juneau.rest.RestResponse res) {
                        String c = req.getHeader("Check");
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Test.java
index 02f7059..782800a 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Test.java
@@ -55,7 +55,7 @@ public class RestClient_Response_Test {
        }
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/bean")
                public ABean getBean() {
                        return bean;
@@ -146,7 +146,7 @@ public class RestClient_Response_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Rest
-       public static class C extends BasicRest {
+       public static class C extends BasicRestObject {
                @RestMethod(path="/")
                public String getHeader(org.apache.juneau.rest.RestRequest req, 
org.apache.juneau.rest.RestResponse res) {
                        String n = req.getHeader("Check");
@@ -225,7 +225,7 @@ public class RestClient_Response_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Rest
-       public static class D extends BasicRest {
+       public static class D extends BasicRestObject {
                @RestMethod
                public ABean postBean(@Body ABean bean) {
                        return bean;
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Test.java
index b35213e..31a3efa 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Test.java
@@ -59,7 +59,7 @@ public class RestClient_Test {
        private static ABean bean = ABean.get();
 
        @Rest
-       public static class A extends BasicRest {
+       public static class A extends BasicRestObject {
                @RestMethod(path="/bean")
                public ABean getBean() {
                        return bean;
@@ -331,7 +331,7 @@ public class RestClient_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Rest
-       public static class D extends BasicRest {
+       public static class D extends BasicRestObject {
                @RestMethod
                public String 
getEcho(@org.apache.juneau.http.annotation.Header("Authorization") String auth, 
org.apache.juneau.rest.RestResponse res) throws IOException {
                        if (auth == null) {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
 
b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
similarity index 71%
copy from 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
copy to 
juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
index 9cfcec7..dc5059c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
+++ 
b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
@@ -10,13 +10,10 @@
 // * "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;
+package org.apache.juneau.rest.springboot;
 
 import java.util.*;
 
-import javax.inject.*;
-
-import org.apache.juneau.cp.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.html.*;
 import org.apache.juneau.html.annotation.*;
@@ -26,16 +23,16 @@ import org.apache.juneau.http.exception.*;
 import org.apache.juneau.jso.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.plaintext.*;
+import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.config.*;
-import org.apache.juneau.rest.logging.*;
 import org.apache.juneau.soap.*;
 import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
 
 /**
- * Subclass of {@link RestServlet} with default serializers and parsers 
defined.
+ * Subclass of {@link SpringRestServlet} with default serializers and parsers 
defined.
  *
  * <p>
  * Supports the following request <c>Accept</c> header values with the 
resulting response <c>Content-Type</c>:
@@ -169,13 +166,9 @@ import org.apache.juneau.xml.*;
                "stats: servlet:/stats"
        }
 )
-public abstract class BasicRestServlet extends RestServlet implements 
BasicUniversalRest, BasicRestMethods {
+public abstract class BasicSpringRestServlet extends SpringRestServlet 
implements BasicUniversalRest, BasicRestMethods {
        private static final long serialVersionUID = 1L;
 
-       @Inject Optional<FileFinder> fileFinder;
-       @Inject Optional<StaticFiles> staticFiles;
-       @Inject Optional<RestLogger> callLogger;
-
        
//-----------------------------------------------------------------------------------------------------------------
        // BasicRestConfig methods
        
//-----------------------------------------------------------------------------------------------------------------
@@ -207,59 +200,4 @@ public abstract class BasicRestServlet extends RestServlet 
implements BasicUnive
        public RestContextStats getStats(RestRequest req) {
                return req.getContext().getStats();
        }
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Context methods.
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       /**
-        * Instantiates the file finder to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
FileFinder} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createFileFinder()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_fileFinder}.
-        * </ul>
-        *
-        * @return The file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public FileFinder createFileFinder() {
-               return fileFinder == null ? null : fileFinder.orElse(null);
-       }
-
-       /**
-        * Instantiates the static file finder to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
StaticFiles} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createStaticFiles()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_staticFiles}.
-        * </ul>
-        *
-        * @return The static file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public StaticFiles createStaticFiles() {
-               return staticFiles == null ? null : staticFiles.orElse(null);
-       }
-
-       /**
-        * Instantiates the call logger to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
RestLogger} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createCallLogger()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_callLogger}.
-        * </ul>
-        *
-        * @return The call logger to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public RestLogger createCallLogger() {
-               return callLogger == null ? null : callLogger.orElse(null);
-       }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
 
b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServletGroup.java
similarity index 75%
copy from 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
copy to 
juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServletGroup.java
index 352732d..83a6361 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
+++ 
b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServletGroup.java
@@ -1,3 +1,4 @@
+package org.apache.juneau.rest.springboot;
 // 
***************************************************************************************************************************
 // * 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        *
@@ -10,24 +11,31 @@
 // * "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.http.HttpMethod.*;
 
-import javax.servlet.http.*;
+import static org.apache.juneau.http.HttpMethod.*;
 
+import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.helper.*;
 
 /**
- * Identical to {@link BasicRestServletGroup} but doesn't extend from {@link 
HttpServlet}.
+ * Specialized subclass of {@link BasicSpringRestServlet} for showing "group" 
pages.
+ *
+ * <p>
+ * Group pages consist of simple lists of child resource URLs and their labels.
+ * They're meant to be used as jumping-off points for child resources.
+ *
+ * <p>
+ * Child resources are specified using the {@link Rest#children() 
@Rest(children)} annotation.
  *
  * <ul class='seealso'>
- *     <li class='link'>{@doc BasicRestGroup}
+ *     <li class='link'>{@doc BasicRestServletGroup}
  * </ul>
  */
 @Rest
-public abstract class BasicRestGroup extends BasicRest {
+public abstract class BasicSpringRestServletGroup extends 
BasicSpringRestServlet {
+       private static final long serialVersionUID = 1L;
 
        /**
         * [GET /] - Get child resources.
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
 
b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanFactory.java
similarity index 66%
copy from 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
copy to 
juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanFactory.java
index 352732d..cfceaf0 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
+++ 
b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanFactory.java
@@ -1,43 +1,48 @@
-// 
***************************************************************************************************************************
-// * 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.http.HttpMethod.*;
-
-import javax.servlet.http.*;
-
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.helper.*;
-
-/**
- * Identical to {@link BasicRestServletGroup} but doesn't extend from {@link 
HttpServlet}.
- *
- * <ul class='seealso'>
- *     <li class='link'>{@doc BasicRestGroup}
- * </ul>
- */
-@Rest
-public abstract class BasicRestGroup extends BasicRest {
-
-       /**
-        * [GET /] - Get child resources.
-        *
-        * @param req The HTTP request.
-        * @return The bean containing links to the child resources.
-        */
-       @RestMethod(method=GET, path="/", summary="Navigation page")
-       public ChildResourceDescriptions getChildren(RestRequest req) {
-               return new ChildResourceDescriptions(req);
-       }
-}
-
+// 
***************************************************************************************************************************
+// * 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.springboot;
+
+import java.util.*;
+
+import org.apache.juneau.cp.BeanFactory;
+import org.springframework.context.*;
+
+/**
+ * A bean factory that uses Spring bean resolution to find beans if they're 
not already in this factory.
+ */
+public class SpringBeanFactory extends BeanFactory {
+
+       private final ApplicationContext appContext;
+
+       /**
+        * Constructor.
+        *
+        * @param appContext The Spring application context used to resolve 
beans.
+        */
+       public SpringBeanFactory(ApplicationContext appContext) {
+               this.appContext = appContext;
+       }
+
+       @Override
+       public <T> Optional<T> getBean(Class<T> c) {
+               Optional<T> o = super.getBean(c);
+               if (o.isPresent())
+                       return o;
+               try {
+                       T t = appContext.getBean(c);
+                       return Optional.of(t);
+               } catch (Exception e) {
+                       return Optional.empty();
+               }
+       }
+}
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
 
b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringRestServlet.java
similarity index 66%
copy from 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
copy to 
juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringRestServlet.java
index 352732d..7d5abeb 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
+++ 
b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringRestServlet.java
@@ -1,43 +1,35 @@
-// 
***************************************************************************************************************************
-// * 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.http.HttpMethod.*;
-
-import javax.servlet.http.*;
-
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.helper.*;
-
-/**
- * Identical to {@link BasicRestServletGroup} but doesn't extend from {@link 
HttpServlet}.
- *
- * <ul class='seealso'>
- *     <li class='link'>{@doc BasicRestGroup}
- * </ul>
- */
-@Rest
-public abstract class BasicRestGroup extends BasicRest {
-
-       /**
-        * [GET /] - Get child resources.
-        *
-        * @param req The HTTP request.
-        * @return The bean containing links to the child resources.
-        */
-       @RestMethod(method=GET, path="/", summary="Navigation page")
-       public ChildResourceDescriptions getChildren(RestRequest req) {
-               return new ChildResourceDescriptions(req);
-       }
-}
-
+// 
***************************************************************************************************************************
+// * 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.springboot;
+
+import javax.inject.*;
+
+import org.apache.juneau.cp.*;
+import org.apache.juneau.rest.*;
+import org.springframework.context.*;
+
+/**
+ * Subclass of a {@link RestServlet} meant for use as deployed top-level REST 
beans.
+ */
+public abstract class SpringRestServlet extends RestServlet {
+
+       private static final long serialVersionUID = 1L;
+
+       @Inject
+       private ApplicationContext appContext;
+
+       @Override
+       protected BeanFactory createBeanFactory() {
+               return new SpringBeanFactory(appContext);
+       }
+}
diff --git 
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Debug_Test.java
 
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Debug_Test.java
index 8092c9f..8c77b97 100644
--- 
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Debug_Test.java
+++ 
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Debug_Test.java
@@ -125,7 +125,7 @@ public class Rest_Debug_Test {
        }
 
        @Rest(callLogger=CaptureLogger.class)
-       public static class A1a extends BasicRest {
+       public static class A1a extends BasicRestObject {
                @RestMethod
                public boolean a(RestRequest req) {
                        return req.isDebug();
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObject.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObject.java
new file mode 100644
index 0000000..32efa29
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObject.java
@@ -0,0 +1,83 @@
+// 
***************************************************************************************************************************
+// * 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.http.*;
+
+import org.apache.juneau.dto.swagger.*;
+import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.http.exception.*;
+
+/**
+ * Identical to {@link BasicRestServlet} but doesn't extend from {@link 
HttpServlet}.
+ *
+ * <p>
+ * This is particularly useful in Spring Boot environments that auto-detect 
servlets to deploy in servlet containers,
+ * but you want this resource to be deployed as a child instead.
+ *
+ * <ul class='seealso'>
+ *     <li class='link'>{@doc BasicRest}
+ * </ul>
+ */
+@Rest(
+       // Allow OPTIONS requests to be simulated using ?method=OPTIONS query 
parameter.
+       allowedMethodParams="OPTIONS"
+)
+@HtmlDocConfig(
+       // Basic page navigation links.
+       navlinks={
+               "up: request:/..",
+               "options: servlet:/?method=OPTIONS",
+               "stats: servlet:/stats"
+       }
+)
+public abstract class BasicRestObject extends RestObject implements 
BasicUniversalRest, BasicRestMethods {
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // BasicRestConfig methods
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       @Override /* BasicRestConfig */
+       public Swagger getApi(RestRequest req) {
+               try {
+                       return getSwagger(req);
+               } catch (Exception e) {
+                       throw new InternalServerError(e);
+               }
+       }
+
+       @Override /* BasicRestConfig */
+       public HttpResource getHtdoc(@Path("/*") String path, Locale locale) 
throws NotFound {
+               return getContext().getStaticFiles().resolve(path, 
locale).orElseThrow(NotFound::new);
+       }
+
+       @Override /* BasicRestConfig */
+       public HttpResource getFavIcon() {
+               String favIcon = 
getContext().getConfig().getString("REST/favicon", "images/juneau.png");
+               return getHtdoc(favIcon, null);
+       }
+
+       @Override /* BasicRestConfig */
+       public void error() {}
+
+       @Override /* BasicRestConfig */
+       public RestContextStats getStats(RestRequest req) {
+               return req.getContext().getStats();
+       }
+}
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObjectGroup.java
similarity index 95%
rename from 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
rename to 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObjectGroup.java
index 352732d..31cc1e9 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestGroup.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObjectGroup.java
@@ -27,7 +27,7 @@ import org.apache.juneau.rest.helper.*;
  * </ul>
  */
 @Rest
-public abstract class BasicRestGroup extends BasicRest {
+public abstract class BasicRestObjectGroup extends BasicRestObject {
 
        /**
         * [GET /] - Get child resources.
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
index 9cfcec7..4ed81cc 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
@@ -14,9 +14,6 @@ package org.apache.juneau.rest;
 
 import java.util.*;
 
-import javax.inject.*;
-
-import org.apache.juneau.cp.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.html.*;
 import org.apache.juneau.html.annotation.*;
@@ -28,7 +25,6 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.config.*;
-import org.apache.juneau.rest.logging.*;
 import org.apache.juneau.soap.*;
 import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
@@ -172,10 +168,6 @@ import org.apache.juneau.xml.*;
 public abstract class BasicRestServlet extends RestServlet implements 
BasicUniversalRest, BasicRestMethods {
        private static final long serialVersionUID = 1L;
 
-       @Inject Optional<FileFinder> fileFinder;
-       @Inject Optional<StaticFiles> staticFiles;
-       @Inject Optional<RestLogger> callLogger;
-
        
//-----------------------------------------------------------------------------------------------------------------
        // BasicRestConfig methods
        
//-----------------------------------------------------------------------------------------------------------------
@@ -208,58 +200,4 @@ public abstract class BasicRestServlet extends RestServlet 
implements BasicUnive
                return req.getContext().getStats();
        }
 
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Context methods.
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       /**
-        * Instantiates the file finder to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
FileFinder} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createFileFinder()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_fileFinder}.
-        * </ul>
-        *
-        * @return The file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public FileFinder createFileFinder() {
-               return fileFinder == null ? null : fileFinder.orElse(null);
-       }
-
-       /**
-        * Instantiates the static file finder to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
StaticFiles} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createStaticFiles()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_staticFiles}.
-        * </ul>
-        *
-        * @return The static file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public StaticFiles createStaticFiles() {
-               return staticFiles == null ? null : staticFiles.orElse(null);
-       }
-
-       /**
-        * Instantiates the call logger to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
RestLogger} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createCallLogger()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_callLogger}.
-        * </ul>
-        *
-        * @return The call logger to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public RestLogger createCallLogger() {
-               return callLogger == null ? null : callLogger.orElse(null);
-       }
 }
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 0602e47..78073f0 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
@@ -452,10 +452,6 @@ public class RestContext extends BeanContext {
         *              The resource class itself will be used if it implements 
the {@link RestLogger} interface and not
         *              explicitly overridden via this annotation.
         *      <li>
-        *              The {@link RestServlet} and {@link BasicRest} classes 
implement the {@link RestLogger} interface with the same
-        *              that gets used if not overridden by this annotation.
-        *              <br>Subclasses can also alter the behavior by 
overriding these methods.
-        *      <li>
         *              When defined as a class, the implementation must have 
one of the following constructors:
         *              <ul>
         *                      <li><code><jk>public</jk> T(RestContext)</code>
@@ -1036,7 +1032,7 @@ public class RestContext extends BeanContext {
         *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestContextBuilder#fileFinder(Class)}
         *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestContextBuilder#fileFinder(FileFinder)}
         *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestContext#createFileFinder()}
-        *                      <li class='jm'>{@link 
org.apache.juneau.rest.BasicRest#createFileFinder()}
+        *                      <li class='jm'>{@link 
org.apache.juneau.rest.BasicRestObject#createFileFinder()}
         *                      <li class='jm'>{@link 
org.apache.juneau.rest.BasicRestServlet#createFileFinder()}
         *              </ul>
         * </ul>
@@ -1062,7 +1058,7 @@ public class RestContext extends BeanContext {
         *      <li>Returns the resource class itself if it's an instance of 
{@link FileFinder}.
         *      <li>Looks for {@link #REST_fileFinder} setting.
         *      <li>Looks for a public <c>createFileFinder()</> method on the 
resource class with an optional {@link RestContext} argument.
-        *              <br>Note that the {@link BasicRest#createFileFinder()} 
and {@link BasicRestServlet#createFileFinder()} methods are implemented
+        *              <br>Note that the {@link RestObject#createFileFinder()} 
and {@link RestServlet#createFileFinder()} methods are implemented
         *              to automatically look for injected beans of type {@link 
FileFinder} allowing preconfigured file finders to be
         *              defined in a Spring configuration class.
         *      <li>Instantiates the default file finder as specified via 
{@link #REST_fileFinderDefault}.
@@ -1327,10 +1323,6 @@ public class RestContext extends BeanContext {
         *              The resource class itself will be used if it implements 
the {@link RestInfoProvider} interface and not
         *              explicitly overridden via this annotation.
         *      <li>
-        *              The{@link RestServlet} and {@link BasicRest} classes 
implement the {@link RestInfoProvider} interface with the same
-        *              functionality as {@link BasicRestInfoProvider} that 
gets used if not overridden by this annotation.
-        *              <br>Subclasses can also alter the behavior by 
overriding these methods.
-        *      <li>
         *              When defined as a class, the implementation must have 
one of the following constructors:
         *              <ul>
         *                      <li><code><jk>public</jk> T(RestContext)</code>
@@ -2267,10 +2259,6 @@ public class RestContext extends BeanContext {
         *              The resource class itself will be used if it implements 
the {@link RestResourceResolver} interface and not
         *              explicitly overridden via this annotation.
         *      <li>
-        *              The {@link RestServlet} and {@link BasicRest} classes 
implement the {@link RestResourceResolver} interface with the same
-        *              functionality as {@link BasicRestResourceResolver} that 
gets used if not overridden by this annotation.
-        *              <br>Subclasses can also alter the behavior by 
overriding these methods.
-        *      <li>
         *              When defined as a class, the implementation must have 
one of the following constructors:
         *              <ul>
         *                      <li><code><jk>public</jk> T(RestContext)</code>
@@ -2625,7 +2613,7 @@ public class RestContext extends BeanContext {
         *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestContextBuilder#staticFiles(Class)}
         *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestContextBuilder#staticFiles(StaticFiles)}
         *                      <li class='jm'>{@link 
org.apache.juneau.rest.RestContext#createStaticFiles()}
-        *                      <li class='jm'>{@link 
org.apache.juneau.rest.BasicRest#createStaticFiles()}
+        *                      <li class='jm'>{@link 
org.apache.juneau.rest.BasicRestObject#createStaticFiles()}
         *                      <li class='jm'>{@link 
org.apache.juneau.rest.BasicRestServlet#createStaticFiles()}
         *              </ul>
         * </ul>
@@ -2635,7 +2623,7 @@ public class RestContext extends BeanContext {
         * Used to retrieve localized files to be served up as static files 
through the REST API via the following
         * predefined methods:
         * <ul class='javatree'>
-        *      <li class='jm'>{@link BasicRest#getHtdoc(String, Locale)}.
+        *      <li class='jm'>{@link BasicRestObject#getHtdoc(String, Locale)}.
         *      <li class='jm'>{@link BasicRestServlet#getHtdoc(String, 
Locale)}.
         * </ul>
         *
@@ -2653,7 +2641,7 @@ public class RestContext extends BeanContext {
         *      <li>Returns the resource class itself is an instance of {@link 
StaticFiles}.
         *      <li>Looks in {@link #REST_staticFiles} setting.
         *      <li>Looks for a public <c>createStaticFiles()</> method on the 
resource class with an optional {@link RestContext} argument.
-        *              <br>Note that the {@link BasicRest#createStaticFiles()} 
and {@link BasicRestServlet#createStaticFiles()} methhods are implemented
+        *              <br>Note that the {@link 
RestObject#createStaticFiles()} and {@link RestServlet#createStaticFiles()} 
methhods are implemented
         *              to automatically look for injected beans of type {@link 
StaticFiles} allowing preconfigured static file finders to be
         *              defined in a Spring configuration class.
         *      <li>Instantiates a {@link BasicStaticFiles} which provides 
basic support for finding localized
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 836b580..5ecbbe1 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
@@ -1890,7 +1890,7 @@ public class RestContextBuilder extends 
BeanContextBuilder implements ServletCon
         * Used to retrieve localized files to be served up as static files 
through the REST API via the following
         * predefined methods:
         * <ul class='javatree'>
-        *      <li class='jm'>{@link BasicRest#getHtdoc(String, Locale)}.
+        *      <li class='jm'>{@link BasicRestObject#getHtdoc(String, Locale)}.
         *      <li class='jm'>{@link BasicRestServlet#getHtdoc(String, 
Locale)}.
         * </ul>
         *
@@ -1913,7 +1913,7 @@ public class RestContextBuilder extends 
BeanContextBuilder implements ServletCon
         * Used to retrieve localized files to be served up as static files 
through the REST API via the following
         * predefined methods:
         * <ul class='javatree'>
-        *      <li class='jm'>{@link BasicRest#getHtdoc(String, Locale)}.
+        *      <li class='jm'>{@link BasicRestObject#getHtdoc(String, Locale)}.
         *      <li class='jm'>{@link BasicRestServlet#getHtdoc(String, 
Locale)}.
         * </ul>
         *
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestObject.java
similarity index 87%
rename from 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRest.java
rename to 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestObject.java
index bd1c959..e45c2b4 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestObject.java
@@ -1,575 +1,521 @@
-// 
***************************************************************************************************************************
-// * 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.annotation.HookEvent.*;
-
-import java.lang.reflect.Method;
-import java.text.*;
-import java.util.*;
-import java.util.function.*;
-import java.util.logging.*;
-
-import javax.inject.*;
-import javax.servlet.*;
-import javax.servlet.http.*;
-
-import org.apache.juneau.cp.*;
-import org.apache.juneau.dto.swagger.*;
-import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.internal.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.config.*;
-import org.apache.juneau.rest.logging.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.exception.*;
-
-/**
- * Identical to {@link BasicRestServlet} but doesn't extend from {@link 
HttpServlet}.
- *
- * <p>
- * This is particularly useful in Spring Boot environments that auto-detect 
servlets to deploy in servlet containers,
- * but you want this resource to be deployed as a child instead.
- *
- * <ul class='seealso'>
- *     <li class='link'>{@doc BasicRest}
- * </ul>
- */
-@Rest(
-       // Allow OPTIONS requests to be simulated using ?method=OPTIONS query 
parameter.
-       allowedMethodParams="OPTIONS"
-)
-@HtmlDocConfig(
-       // Basic page navigation links.
-       navlinks={
-               "up: request:/..",
-               "options: servlet:/?method=OPTIONS",
-               "stats: servlet:/stats"
-       }
-)
-public abstract class BasicRest implements BasicUniversalRest, 
BasicRestMethods, RestInfoProvider {
-
-       private Logger logger = Logger.getLogger(getClass().getName());
-       private volatile RestContext context;
-       private RestInfoProvider infoProvider;
-
-       @Inject Optional<FileFinder> fileFinder;
-       @Inject Optional<StaticFiles> staticFiles;
-       @Inject Optional<RestLogger> callLogger;
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // BasicRestConfig methods
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       @Override /* BasicRestConfig */
-       public Swagger getApi(RestRequest req) {
-               try {
-                       return getSwagger(req);
-               } catch (Exception e) {
-                       throw new InternalServerError(e);
-               }
-       }
-
-       @Override /* BasicRestConfig */
-       public HttpResource getHtdoc(@Path("/*") String path, Locale locale) 
throws NotFound {
-               return context.getStaticFiles().resolve(path, 
locale).orElseThrow(NotFound::new);
-       }
-
-       @Override /* BasicRestConfig */
-       public HttpResource getFavIcon() {
-               String favIcon = 
getContext().getConfig().getString("REST/favicon", "images/juneau.png");
-               return getHtdoc(favIcon, null);
-       }
-
-       @Override /* BasicRestConfig */
-       public void error() {}
-
-       @Override /* BasicRestConfig */
-       public RestContextStats getStats(RestRequest req) {
-               return req.getContext().getStats();
-       }
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Context methods.
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       /**
-        * Returns the read-only context object that contains all the 
configuration information about this resource.
-        *
-        * @return The context information on this servlet.
-        */
-       protected synchronized RestContext getContext() {
-               if (context == null)
-                       throw new InternalServerError("RestContext object not 
set on resource.");
-               return context;
-       }
-
-       /**
-        * Instantiates the file finder to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
FileFinder} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createFileFinder()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_fileFinder}.
-        * </ul>
-        *
-        * @return The file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public FileFinder createFileFinder() {
-               return fileFinder == null ? null : fileFinder.orElse(null);
-       }
-
-       /**
-        * Instantiates the static file finder to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
StaticFiles} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createStaticFiles()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_staticFiles}.
-        * </ul>
-        *
-        * @return The static file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public StaticFiles createStaticFiles() {
-               return staticFiles == null ? null : staticFiles.orElse(null);
-       }
-
-       /**
-        * Instantiates the call logger to use for this REST resource.
-        *
-        * <p>
-        * Default implementation looks for an injected bean of type {@link 
RestLogger} or else returns <jk>null</jk>
-        * which results in the default lookup logic as defined in {@link 
RestContext#createCallLogger()}.
-        *
-        * <ul class='seealso'>
-        *      <li class='link'>{@link RestContext#REST_callLogger}.
-        * </ul>
-        *
-        * @return The call logger to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
-        */
-       public RestLogger createCallLogger() {
-               return callLogger == null ? null : callLogger.orElse(null);
-       }
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Convenience logger methods
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       /**
-        * Log a message at {@link Level#INFO} level.
-        *
-        * <p>
-        * Subclasses can intercept the handling of these messages by 
overriding {@link #doLog(Level, Throwable, Supplier)}.
-        *
-        * @param msg The message to log.
-        */
-       public void log(String msg) {
-               doLog(Level.INFO, null, () -> msg);
-       }
-
-       /**
-        * Log a message.
-        *
-        * <p>
-        * Subclasses can intercept the handling of these messages by 
overriding {@link #doLog(Level, Throwable, Supplier)}.
-        *
-        * @param msg The message to log.
-        * @param cause The cause.
-        */
-       public void log(String msg, Throwable cause) {
-               doLog(Level.INFO, null, () -> msg);
-       }
-
-       /**
-        * Log a message.
-        *
-        * <p>
-        * Subclasses can intercept the handling of these messages by 
overriding {@link #doLog(Level, Throwable, Supplier)}.
-        *
-        * @param level The log level.
-        * @param msg The message to log.
-        * @param args Optional {@link MessageFormat}-style arguments.
-        */
-       public void log(Level level, String msg, Object...args) {
-               doLog(level, null, () -> StringUtils.format(msg, args));
-       }
-
-       /**
-        * Log a message.
-        *
-        * <p>
-        * Subclasses can intercept the handling of these messages by 
overriding {@link #doLog(Level, Throwable, Supplier)}.
-        *
-        * @param level The log level.
-        * @param cause The cause.
-        * @param msg The message to log.
-        * @param args Optional {@link MessageFormat}-style arguments.
-        */
-       public void log(Level level, Throwable cause, String msg, 
Object...args) {
-               doLog(level, cause, () -> StringUtils.format(msg, args));
-       }
-
-       /**
-        * Main logger method.
-        *
-        * <p>
-        * The default behavior logs a message to the Java logger of the class 
name.
-        *
-        * <p>
-        * Subclasses can override this method to implement their own logger 
handling.
-        *
-        * @param level The log level.
-        * @param cause Optional throwable.
-        * @param msg The message to log.
-        */
-       protected void doLog(Level level, Throwable cause, Supplier<String> 
msg) {
-               logger.log(level, cause, msg);
-       }
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Hook events
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       /**
-        * Method that gets called during servlet initialization.
-        *
-        * <p>
-        * This method is called from within the {@link 
Servlet#init(ServletConfig)} method after the {@link RestContextBuilder}
-        * object has been created and initialized with the annotations defined 
on the class, but before the
-        * {@link RestContext} object has been created.
-        *
-        * <p>
-        * An example of this is the <c>PetStoreResource</c> class that uses an 
init method to perform initialization
-        * of an internal data structure.
-        *
-        * <h5 class='figure'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <ja>@Rest</ja>(...)
-        *      <jk>public class</jk> PetStoreResource <jk>extends</jk> 
ResourceJena {
-        *
-        *              <jc>// Our database.</jc>
-        *              <jk>private</jk> Map&lt;Integer,Pet&gt; <jf>petDB</jf>;
-        *
-        *              <ja>@Override</ja>
-        *              <jk>public void</jk> onInit(RestContextBuilder builder) 
<jk>throws</jk> Exception {
-        *                      <jc>// Load our database from a local JSON 
file.</jc>
-        *                      <jf>petDB</jf> = 
JsonParser.<jsf>DEFAULT</jsf>.parse(getClass().getResourceAsStream(<js>"PetStore.json"</js>),
 LinkedHashMap.<jk>class</jk>, Integer.<jk>class</jk>, Pet.<jk>class</jk>);
-        *              }
-        *      }
-        * </p>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              The default implementation of this method is a no-op.
-        *      <li>
-        *              Multiple INIT methods can be defined on a class.
-        *              <br>INIT methods on parent classes are invoked before 
INIT methods on child classes.
-        *              <br>The order of INIT method invocations within a class 
is alphabetical, then by parameter count, then by parameter types.
-        *      <li>
-        *              The method can throw any exception causing 
initialization of the servlet to fail.
-        * </ul>
-        *
-        * @param builder Context builder which can be used to configure the 
servlet.
-        * @throws Exception Any exception thrown will cause servlet to fail 
startup.
-        */
-       @RestHook(INIT)
-       public void onInit(RestContextBuilder builder) throws Exception {}
-
-       /**
-        * Method that gets called immediately after servlet initialization.
-        *
-        * <p>
-        * This method is called from within the {@link 
Servlet#init(ServletConfig)} method after the {@link RestContext}
-        * object has been created.
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              The default implementation of this method is a no-op.
-        *      <li>
-        *              Multiple POST_INIT methods can be defined on a class.
-        *              <br>POST_INIT methods on parent classes are invoked 
before POST_INIT methods on child classes.
-        *              <br>The order of POST_INIT method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
-        *      <li>
-        *              The method can throw any exception causing 
initialization of the servlet to fail.
-        * </ul>
-        *
-        * @param context The initialized context object.
-        * @throws Exception Any exception thrown will cause servlet to fail 
startup.
-        */
-       @RestHook(POST_INIT)
-       public void onPostInit(RestContext context) throws Exception {
-               this.context = context;
-               this.infoProvider = new BasicRestInfoProvider(context);
-       }
-
-       /**
-        * Identical to {@link #onPostInit(RestContext)} except the order of 
execution is child-resources first.
-        *
-        * <p>
-        * Use this method if you need to perform any kind of initialization on 
child resources before the parent resource.
-        *
-        * <p>
-        * This method is called from within the {@link 
Servlet#init(ServletConfig)} method after the {@link RestContext}
-        * object has been created and after the {@link HookEvent#POST_INIT} 
methods have been called.
-        *
-        * <p>
-        * The only valid parameter type for this method is {@link RestContext} 
which can be used to retrieve information
-        * about the servlet.
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              The default implementation of this method is a no-op.
-        *      <li>
-        *              Multiple POST_INIT_CHILD_FIRST methods can be defined 
on a class.
-        *              <br>POST_INIT_CHILD_FIRST methods on parent classes are 
invoked before POST_INIT_CHILD_FIRST methods on child classes.
-        *              <br>The order of POST_INIT_CHILD_FIRST method 
invocations within a class is alphabetical, then by parameter count, then by 
parameter types.
-        *      <li>
-        *              The method can throw any exception causing 
initialization of the servlet to fail.
-        * </ul>
-        *
-        * @param context The initialized context object.
-        * @throws Exception Any exception thrown will cause servlet to fail 
startup.
-        */
-       @RestHook(POST_INIT_CHILD_FIRST)
-       public void onPostInitChildFirst(RestContext context) throws Exception 
{}
-
-       /**
-        * Method that gets called during servlet destroy.
-        *
-        * <p>
-        * This method is called from within the {@link Servlet#destroy()}.
-        *
-        * <h5 class='figure'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <ja>@Rest</ja>(...)
-        *      <jk>public class</jk> PetStoreResource <jk>extends</jk> 
ResourceJena {
-        *
-        *              <jc>// Our database.</jc>
-        *              <jk>private</jk> Map&lt;Integer,Pet&gt; <jf>petDB</jf>;
-        *
-        *              <ja>@Override</ja>
-        *              <jk>public void</jk> onDestroy(RestContext context) {
-        *                      <jf>petDB</jf> = <jk>null</jk>;
-        *              }
-        *      }
-        * </p>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              The default implementation of this method is a no-op.
-        *      <li>
-        *              Multiple DESTROY methods can be defined on a class.
-        *              <br>DESTROY methods on child classes are invoked before 
DESTROY methods on parent classes.
-        *              <br>The order of DESTROY method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
-        *      <li>
-        *              In general, destroy methods should not throw any 
exceptions, although if any are thrown, the stack trace will be
-        *              printed to <c>System.err</c>.
-        * </ul>
-        *
-        * @param context The initialized context object.
-        * @throws Exception Any exception thrown will cause stack trace to be 
printed to <c>System.err</c>.
-        */
-       @RestHook(DESTROY)
-       public void onDestroy(RestContext context) throws Exception {}
-
-       /**
-        * A method that is called immediately after the 
<c>HttpServlet.service(HttpServletRequest, HttpServletResponse)</c>
-        * method is called.
-        *
-        * <p>
-        * Note that you only have access to the raw request and response 
objects at this point.
-        *
-        * <h5 class='figure'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <ja>@Rest</ja>(...)
-        *      <jk>public class</jk> MyResource <jk>extends</jk> 
BasicRestServlet {
-        *
-        *              <jc>// Add a request attribute to all incoming 
requests.</jc>
-        *              <ja>@Override</ja>
-        *              <jk>public void</jk> onStartCall(HttpServletRequest 
req, HttpServletResponse res) {
-        *                      req.setAttribute(<js>"foobar"</js>, 
<jk>new</jk> FooBar());
-        *              }
-        *      }
-        * </p>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              The default implementation of this method is a no-op.
-        *      <li>
-        *              Multiple START_CALL methods can be defined on a class.
-        *              <br>START_CALL methods on parent classes are invoked 
before START_CALL methods on child classes.
-        *              <br>The order of START_CALL method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
-        *      <li>
-        *              The method can throw any exception.
-        *              <br>{@link HttpException HttpExceptions} can be thrown 
to cause a particular HTTP error status code.
-        *              <br>All other exceptions cause an HTTP 500 error status 
code.
-        * </ul>
-        *
-        * @param req The HTTP servlet request object.
-        * @param res The HTTP servlet response object.
-        * @throws Exception Any exception.
-        */
-       @RestHook(START_CALL)
-       public void onStartCall(HttpServletRequest req, HttpServletResponse 
res) throws Exception {}
-
-       /**
-        * Method that gets called immediately before the <ja>@RestMethod</ja> 
annotated method gets called.
-        *
-        * <p>
-        * At this point, the {@link RestRequest} object has been fully 
initialized, and all {@link RestGuard} and
-        * {@link RestMatcher} objects have been called.
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              The default implementation of this method is a no-op.
-        *      <li>
-        *              Multiple PRE_CALL methods can be defined on a class.
-        *              <br>PRE_CALL methods on parent classes are invoked 
before PRE_CALL methods on child classes.
-        *              <br>The order of PRE_CALL method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
-        *      <li>
-        *              The method can throw any exception.
-        *              <br>{@link HttpException HttpExceptions} can be thrown 
to cause a particular HTTP error status code.
-        *              <br>All other exceptions cause an HTTP 500 error status 
code.
-        *      <li>
-        *              It's advisable not to mess around with the HTTP body 
itself since you may end up consuming the body
-        *              before the actual REST method has a chance to use it.
-        * </ul>
-        *
-        * @param req The request object.
-        * @param res The response object.
-        * @throws Exception Any exception.
-        */
-       @RestHook(PRE_CALL)
-       public void onPreCall(RestRequest req, RestResponse res) throws 
Exception {}
-
-       /**
-        * Method that gets called immediately after the <ja>@RestMethod</ja> 
annotated method gets called.
-        *
-        * <p>
-        * At this point, the output object returned by the method call has 
been set on the response, but
-        * {@link RestConverter RestConverters} have not yet been executed and 
the response has not yet been written.
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              The default implementation of this method is a no-op.
-        *      <li>
-        *              Multiple POST_CALL methods can be defined on a class.
-        *              <br>POST_CALL methods on parent classes are invoked 
before POST_CALL methods on child classes.
-        *              <br>The order of POST_CALL method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
-        *      <li>
-        *              The method can throw any exception, although at this 
point it is too late to set an HTTP error status code.
-        * </ul>
-        *
-        * @param req The request object.
-        * @param res The response object.
-        * @throws Exception Any exception.
-        */
-       @RestHook(POST_CALL)
-       public void onPostCall(RestRequest req, RestResponse res) throws 
Exception {}
-
-       /**
-        * Method that gets called right before we exit the servlet service 
method.
-        *
-        * <p>
-        * At this point, the output has been written and flushed.
-        *
-        * <p>
-        * The following attributes are set on the {@link HttpServletRequest} 
object that can be useful for logging purposes:
-        * <ul>
-        *      <li><js>"Exception"</js> - Any exceptions thrown during the 
request.
-        *      <li><js>"ExecTime"</js> - Execution time of the request.
-        * </ul>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              The default implementation of this method is a no-op.
-        *      <li>
-        *              Multiple END_CALL methods can be defined on a class.
-        *              <br>END_CALL methods on parent classes are invoked 
before END_CALL methods on child classes.
-        *              <br>The order of END_CALL method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
-        *      <li>
-        *              The method can throw any exception, although at this 
point it is too late to set an HTTP error status code.
-        *      <li>
-        *              Note that if you override a parent method, you probably 
need to call <code><jk>super</jk>.parentMethod(...)</code>.
-        *              <br>The method is still considered part of the parent 
class for ordering purposes even though it's
-        *              overridden by the child class.
-        * </ul>
-        *
-        * @param req The HTTP servlet request object.
-        * @param res The HTTP servlet response object.
-        * @throws Exception Any exception.
-        */
-       @RestHook(END_CALL)
-       public void onEndCall(HttpServletRequest req, HttpServletResponse res) 
throws Exception {}
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Other methods.
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       /**
-        * Returns the current HTTP request.
-        *
-        * @return The current HTTP request, or <jk>null</jk> if it wasn't 
created.
-        */
-       public synchronized RestRequest getRequest() {
-               return getContext().getRequest();
-       }
-
-       /**
-        * Returns the current HTTP response.
-        *
-        * @return The current HTTP response, or <jk>null</jk> if it wasn't 
created.
-        */
-       public synchronized RestResponse getResponse() {
-               return getContext().getResponse();
-       }
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // RestInfoProvider
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       @Override /* RestInfoProvider */
-       public Swagger getSwagger(RestRequest req) throws Exception {
-               return infoProvider.getSwagger(req);
-       }
-
-       @Override /* RestInfoProvider */
-       public String getSiteName(RestRequest req) throws Exception {
-               return infoProvider.getSiteName(req);
-       }
-
-       @Override /* RestInfoProvider */
-       public String getTitle(RestRequest req) throws Exception {
-               return infoProvider.getTitle(req);
-       }
-
-       @Override /* RestInfoProvider */
-       public String getDescription(RestRequest req) throws Exception {
-               return infoProvider.getDescription(req);
-       }
-
-       @Override /* RestInfoProvider */
-       public String getMethodSummary(Method method, RestRequest req) throws 
Exception {
-               return infoProvider.getMethodSummary(method, req);
-       }
-
-       @Override /* RestInfoProvider */
-       public String getMethodDescription(Method method, RestRequest req) 
throws Exception {
-               return infoProvider.getMethodDescription(method, req);
-       }
-}
+// 
***************************************************************************************************************************
+// * 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.annotation.HookEvent.*;
+
+import java.lang.reflect.Method;
+import java.text.*;
+import java.util.function.*;
+import java.util.logging.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.cp.*;
+import org.apache.juneau.dto.swagger.*;
+import org.apache.juneau.http.exception.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.logging.*;
+
+/**
+ * Identical to {@link RestServlet} but doesn't extend from {@link 
HttpServlet}.
+ *
+ * <p>
+ * This is particularly useful in Spring Boot environments that auto-detect 
servlets to deploy in servlet containers,
+ * but you want this resource to be deployed as a child instead.
+ *
+ * <ul class='seealso'>
+ *     <li class='link'>{@doc BasicRest}
+ * </ul>
+ */
+public abstract class RestObject implements RestInfoProvider {
+
+       private Logger logger = Logger.getLogger(getClass().getName());
+       private volatile RestContext context;
+       private RestInfoProvider infoProvider;
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Context methods.
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Returns the read-only context object that contains all the 
configuration information about this resource.
+        *
+        * @return The context information on this servlet.
+        */
+       protected synchronized RestContext getContext() {
+               if (context == null)
+                       throw new InternalServerError("RestContext object not 
set on resource.");
+               return context;
+       }
+
+       /**
+        * Instantiates the file finder to use for this REST resource.
+        *
+        * <p>
+        * Default implementation returns <jk>null</jk>
+        * which results in the default lookup logic as defined in {@link 
RestContext#createFileFinder()}.
+        *
+        * <ul class='seealso'>
+        *      <li class='link'>{@link RestContext#REST_fileFinder}.
+        * </ul>
+        *
+        * @return The file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
+        */
+       public FileFinder createFileFinder() {
+               return null;
+       }
+
+       /**
+        * Instantiates the static file finder to use for this REST resource.
+        *
+        * <p>
+        * Default implementation returns <jk>null</jk>
+        * which results in the default lookup logic as defined in {@link 
RestContext#createStaticFiles()}.
+        *
+        * <ul class='seealso'>
+        *      <li class='link'>{@link RestContext#REST_staticFiles}.
+        * </ul>
+        *
+        * @return The static file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
+        */
+       public StaticFiles createStaticFiles() {
+               return null;
+       }
+
+       /**
+        * Instantiates the call logger to use for this REST resource.
+        *
+        * <p>
+        * Default implementation returns <jk>null</jk>
+        * which results in the default lookup logic as defined in {@link 
RestContext#createCallLogger()}.
+        *
+        * <ul class='seealso'>
+        *      <li class='link'>{@link RestContext#REST_callLogger}.
+        * </ul>
+        *
+        * @return The call logger to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
+        */
+       public RestLogger createCallLogger() {
+               return null;
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Convenience logger methods
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Log a message at {@link Level#INFO} level.
+        *
+        * <p>
+        * Subclasses can intercept the handling of these messages by 
overriding {@link #doLog(Level, Throwable, Supplier)}.
+        *
+        * @param msg The message to log.
+        */
+       public void log(String msg) {
+               doLog(Level.INFO, null, () -> msg);
+       }
+
+       /**
+        * Log a message.
+        *
+        * <p>
+        * Subclasses can intercept the handling of these messages by 
overriding {@link #doLog(Level, Throwable, Supplier)}.
+        *
+        * @param msg The message to log.
+        * @param cause The cause.
+        */
+       public void log(String msg, Throwable cause) {
+               doLog(Level.INFO, null, () -> msg);
+       }
+
+       /**
+        * Log a message.
+        *
+        * <p>
+        * Subclasses can intercept the handling of these messages by 
overriding {@link #doLog(Level, Throwable, Supplier)}.
+        *
+        * @param level The log level.
+        * @param msg The message to log.
+        * @param args Optional {@link MessageFormat}-style arguments.
+        */
+       public void log(Level level, String msg, Object...args) {
+               doLog(level, null, () -> StringUtils.format(msg, args));
+       }
+
+       /**
+        * Log a message.
+        *
+        * <p>
+        * Subclasses can intercept the handling of these messages by 
overriding {@link #doLog(Level, Throwable, Supplier)}.
+        *
+        * @param level The log level.
+        * @param cause The cause.
+        * @param msg The message to log.
+        * @param args Optional {@link MessageFormat}-style arguments.
+        */
+       public void log(Level level, Throwable cause, String msg, 
Object...args) {
+               doLog(level, cause, () -> StringUtils.format(msg, args));
+       }
+
+       /**
+        * Main logger method.
+        *
+        * <p>
+        * The default behavior logs a message to the Java logger of the class 
name.
+        *
+        * <p>
+        * Subclasses can override this method to implement their own logger 
handling.
+        *
+        * @param level The log level.
+        * @param cause Optional throwable.
+        * @param msg The message to log.
+        */
+       protected void doLog(Level level, Throwable cause, Supplier<String> 
msg) {
+               logger.log(level, cause, msg);
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Hook events
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Method that gets called during servlet initialization.
+        *
+        * <p>
+        * This method is called from within the {@link 
Servlet#init(ServletConfig)} method after the {@link RestContextBuilder}
+        * object has been created and initialized with the annotations defined 
on the class, but before the
+        * {@link RestContext} object has been created.
+        *
+        * <p>
+        * An example of this is the <c>PetStoreResource</c> class that uses an 
init method to perform initialization
+        * of an internal data structure.
+        *
+        * <h5 class='figure'>Example:</h5>
+        * <p class='bcode w800'>
+        *      <ja>@Rest</ja>(...)
+        *      <jk>public class</jk> PetStoreResource <jk>extends</jk> 
ResourceJena {
+        *
+        *              <jc>// Our database.</jc>
+        *              <jk>private</jk> Map&lt;Integer,Pet&gt; <jf>petDB</jf>;
+        *
+        *              <ja>@Override</ja>
+        *              <jk>public void</jk> onInit(RestContextBuilder builder) 
<jk>throws</jk> Exception {
+        *                      <jc>// Load our database from a local JSON 
file.</jc>
+        *                      <jf>petDB</jf> = 
JsonParser.<jsf>DEFAULT</jsf>.parse(getClass().getResourceAsStream(<js>"PetStore.json"</js>),
 LinkedHashMap.<jk>class</jk>, Integer.<jk>class</jk>, Pet.<jk>class</jk>);
+        *              }
+        *      }
+        * </p>
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              The default implementation of this method is a no-op.
+        *      <li>
+        *              Multiple INIT methods can be defined on a class.
+        *              <br>INIT methods on parent classes are invoked before 
INIT methods on child classes.
+        *              <br>The order of INIT method invocations within a class 
is alphabetical, then by parameter count, then by parameter types.
+        *      <li>
+        *              The method can throw any exception causing 
initialization of the servlet to fail.
+        * </ul>
+        *
+        * @param builder Context builder which can be used to configure the 
servlet.
+        * @throws Exception Any exception thrown will cause servlet to fail 
startup.
+        */
+       @RestHook(INIT)
+       public void onInit(RestContextBuilder builder) throws Exception {}
+
+       /**
+        * Method that gets called immediately after servlet initialization.
+        *
+        * <p>
+        * This method is called from within the {@link 
Servlet#init(ServletConfig)} method after the {@link RestContext}
+        * object has been created.
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              The default implementation of this method is a no-op.
+        *      <li>
+        *              Multiple POST_INIT methods can be defined on a class.
+        *              <br>POST_INIT methods on parent classes are invoked 
before POST_INIT methods on child classes.
+        *              <br>The order of POST_INIT method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
+        *      <li>
+        *              The method can throw any exception causing 
initialization of the servlet to fail.
+        * </ul>
+        *
+        * @param context The initialized context object.
+        * @throws Exception Any exception thrown will cause servlet to fail 
startup.
+        */
+       @RestHook(POST_INIT)
+       public void onPostInit(RestContext context) throws Exception {
+               this.context = context;
+               this.infoProvider = new BasicRestInfoProvider(context);
+       }
+
+       /**
+        * Identical to {@link #onPostInit(RestContext)} except the order of 
execution is child-resources first.
+        *
+        * <p>
+        * Use this method if you need to perform any kind of initialization on 
child resources before the parent resource.
+        *
+        * <p>
+        * This method is called from within the {@link 
Servlet#init(ServletConfig)} method after the {@link RestContext}
+        * object has been created and after the {@link HookEvent#POST_INIT} 
methods have been called.
+        *
+        * <p>
+        * The only valid parameter type for this method is {@link RestContext} 
which can be used to retrieve information
+        * about the servlet.
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              The default implementation of this method is a no-op.
+        *      <li>
+        *              Multiple POST_INIT_CHILD_FIRST methods can be defined 
on a class.
+        *              <br>POST_INIT_CHILD_FIRST methods on parent classes are 
invoked before POST_INIT_CHILD_FIRST methods on child classes.
+        *              <br>The order of POST_INIT_CHILD_FIRST method 
invocations within a class is alphabetical, then by parameter count, then by 
parameter types.
+        *      <li>
+        *              The method can throw any exception causing 
initialization of the servlet to fail.
+        * </ul>
+        *
+        * @param context The initialized context object.
+        * @throws Exception Any exception thrown will cause servlet to fail 
startup.
+        */
+       @RestHook(POST_INIT_CHILD_FIRST)
+       public void onPostInitChildFirst(RestContext context) throws Exception 
{}
+
+       /**
+        * Method that gets called during servlet destroy.
+        *
+        * <p>
+        * This method is called from within the {@link Servlet#destroy()}.
+        *
+        * <h5 class='figure'>Example:</h5>
+        * <p class='bcode w800'>
+        *      <ja>@Rest</ja>(...)
+        *      <jk>public class</jk> PetStoreResource <jk>extends</jk> 
ResourceJena {
+        *
+        *              <jc>// Our database.</jc>
+        *              <jk>private</jk> Map&lt;Integer,Pet&gt; <jf>petDB</jf>;
+        *
+        *              <ja>@Override</ja>
+        *              <jk>public void</jk> onDestroy(RestContext context) {
+        *                      <jf>petDB</jf> = <jk>null</jk>;
+        *              }
+        *      }
+        * </p>
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              The default implementation of this method is a no-op.
+        *      <li>
+        *              Multiple DESTROY methods can be defined on a class.
+        *              <br>DESTROY methods on child classes are invoked before 
DESTROY methods on parent classes.
+        *              <br>The order of DESTROY method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
+        *      <li>
+        *              In general, destroy methods should not throw any 
exceptions, although if any are thrown, the stack trace will be
+        *              printed to <c>System.err</c>.
+        * </ul>
+        *
+        * @param context The initialized context object.
+        * @throws Exception Any exception thrown will cause stack trace to be 
printed to <c>System.err</c>.
+        */
+       @RestHook(DESTROY)
+       public void onDestroy(RestContext context) throws Exception {}
+
+       /**
+        * A method that is called immediately after the 
<c>HttpServlet.service(HttpServletRequest, HttpServletResponse)</c>
+        * method is called.
+        *
+        * <p>
+        * Note that you only have access to the raw request and response 
objects at this point.
+        *
+        * <h5 class='figure'>Example:</h5>
+        * <p class='bcode w800'>
+        *      <ja>@Rest</ja>(...)
+        *      <jk>public class</jk> MyResource <jk>extends</jk> 
BasicRestServlet {
+        *
+        *              <jc>// Add a request attribute to all incoming 
requests.</jc>
+        *              <ja>@Override</ja>
+        *              <jk>public void</jk> onStartCall(HttpServletRequest 
req, HttpServletResponse res) {
+        *                      req.setAttribute(<js>"foobar"</js>, 
<jk>new</jk> FooBar());
+        *              }
+        *      }
+        * </p>
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              The default implementation of this method is a no-op.
+        *      <li>
+        *              Multiple START_CALL methods can be defined on a class.
+        *              <br>START_CALL methods on parent classes are invoked 
before START_CALL methods on child classes.
+        *              <br>The order of START_CALL method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
+        *      <li>
+        *              The method can throw any exception.
+        *              <br>{@link HttpException HttpExceptions} can be thrown 
to cause a particular HTTP error status code.
+        *              <br>All other exceptions cause an HTTP 500 error status 
code.
+        * </ul>
+        *
+        * @param req The HTTP servlet request object.
+        * @param res The HTTP servlet response object.
+        * @throws Exception Any exception.
+        */
+       @RestHook(START_CALL)
+       public void onStartCall(HttpServletRequest req, HttpServletResponse 
res) throws Exception {}
+
+       /**
+        * Method that gets called immediately before the <ja>@RestMethod</ja> 
annotated method gets called.
+        *
+        * <p>
+        * At this point, the {@link RestRequest} object has been fully 
initialized, and all {@link RestGuard} and
+        * {@link RestMatcher} objects have been called.
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              The default implementation of this method is a no-op.
+        *      <li>
+        *              Multiple PRE_CALL methods can be defined on a class.
+        *              <br>PRE_CALL methods on parent classes are invoked 
before PRE_CALL methods on child classes.
+        *              <br>The order of PRE_CALL method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
+        *      <li>
+        *              The method can throw any exception.
+        *              <br>{@link HttpException HttpExceptions} can be thrown 
to cause a particular HTTP error status code.
+        *              <br>All other exceptions cause an HTTP 500 error status 
code.
+        *      <li>
+        *              It's advisable not to mess around with the HTTP body 
itself since you may end up consuming the body
+        *              before the actual REST method has a chance to use it.
+        * </ul>
+        *
+        * @param req The request object.
+        * @param res The response object.
+        * @throws Exception Any exception.
+        */
+       @RestHook(PRE_CALL)
+       public void onPreCall(RestRequest req, RestResponse res) throws 
Exception {}
+
+       /**
+        * Method that gets called immediately after the <ja>@RestMethod</ja> 
annotated method gets called.
+        *
+        * <p>
+        * At this point, the output object returned by the method call has 
been set on the response, but
+        * {@link RestConverter RestConverters} have not yet been executed and 
the response has not yet been written.
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              The default implementation of this method is a no-op.
+        *      <li>
+        *              Multiple POST_CALL methods can be defined on a class.
+        *              <br>POST_CALL methods on parent classes are invoked 
before POST_CALL methods on child classes.
+        *              <br>The order of POST_CALL method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
+        *      <li>
+        *              The method can throw any exception, although at this 
point it is too late to set an HTTP error status code.
+        * </ul>
+        *
+        * @param req The request object.
+        * @param res The response object.
+        * @throws Exception Any exception.
+        */
+       @RestHook(POST_CALL)
+       public void onPostCall(RestRequest req, RestResponse res) throws 
Exception {}
+
+       /**
+        * Method that gets called right before we exit the servlet service 
method.
+        *
+        * <p>
+        * At this point, the output has been written and flushed.
+        *
+        * <p>
+        * The following attributes are set on the {@link HttpServletRequest} 
object that can be useful for logging purposes:
+        * <ul>
+        *      <li><js>"Exception"</js> - Any exceptions thrown during the 
request.
+        *      <li><js>"ExecTime"</js> - Execution time of the request.
+        * </ul>
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              The default implementation of this method is a no-op.
+        *      <li>
+        *              Multiple END_CALL methods can be defined on a class.
+        *              <br>END_CALL methods on parent classes are invoked 
before END_CALL methods on child classes.
+        *              <br>The order of END_CALL method invocations within a 
class is alphabetical, then by parameter count, then by parameter types.
+        *      <li>
+        *              The method can throw any exception, although at this 
point it is too late to set an HTTP error status code.
+        *      <li>
+        *              Note that if you override a parent method, you probably 
need to call <code><jk>super</jk>.parentMethod(...)</code>.
+        *              <br>The method is still considered part of the parent 
class for ordering purposes even though it's
+        *              overridden by the child class.
+        * </ul>
+        *
+        * @param req The HTTP servlet request object.
+        * @param res The HTTP servlet response object.
+        * @throws Exception Any exception.
+        */
+       @RestHook(END_CALL)
+       public void onEndCall(HttpServletRequest req, HttpServletResponse res) 
throws Exception {}
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Other methods.
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Returns the current HTTP request.
+        *
+        * @return The current HTTP request, or <jk>null</jk> if it wasn't 
created.
+        */
+       public synchronized RestRequest getRequest() {
+               return getContext().getRequest();
+       }
+
+       /**
+        * Returns the current HTTP response.
+        *
+        * @return The current HTTP response, or <jk>null</jk> if it wasn't 
created.
+        */
+       public synchronized RestResponse getResponse() {
+               return getContext().getResponse();
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // RestInfoProvider
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       @Override /* RestInfoProvider */
+       public Swagger getSwagger(RestRequest req) throws Exception {
+               return infoProvider.getSwagger(req);
+       }
+
+       @Override /* RestInfoProvider */
+       public String getSiteName(RestRequest req) throws Exception {
+               return infoProvider.getSiteName(req);
+       }
+
+       @Override /* RestInfoProvider */
+       public String getTitle(RestRequest req) throws Exception {
+               return infoProvider.getTitle(req);
+       }
+
+       @Override /* RestInfoProvider */
+       public String getDescription(RestRequest req) throws Exception {
+               return infoProvider.getDescription(req);
+       }
+
+       @Override /* RestInfoProvider */
+       public String getMethodSummary(Method method, RestRequest req) throws 
Exception {
+               return infoProvider.getMethodSummary(method, req);
+       }
+
+       @Override /* RestInfoProvider */
+       public String getMethodDescription(Method method, RestRequest req) 
throws Exception {
+               return infoProvider.getMethodDescription(method, req);
+       }
+}
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 4812bf7..6075fac 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
@@ -30,6 +30,8 @@ import javax.servlet.http.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.logging.*;
+import org.apache.juneau.cp.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.http.exception.*;
 
@@ -53,7 +55,7 @@ public abstract class RestServlet extends HttpServlet 
implements RestInfoProvide
        private RestInfoProvider infoProvider;
 
        @Override /* Servlet */
-       public final synchronized void init(ServletConfig servletConfig) throws 
ServletException {
+       public synchronized void init(ServletConfig servletConfig) throws 
ServletException {
                try {
                        if (context != null)
                                return;
@@ -75,6 +77,15 @@ public abstract class RestServlet extends HttpServlet 
implements RestInfoProvide
                }
        }
 
+       /**
+        * Instantiates the bean factory to use for creating beans for this 
servlet.
+        *
+        * @return A new bean factory.
+        */
+       protected BeanFactory createBeanFactory() {
+               return new BeanFactory();
+       }
+
        /*
         * Bypasses the init(ServletConfig) method and just calls the 
super.init(ServletConfig) method directly.
         * Used when subclasses of RestServlet are attached as child resources.
@@ -169,6 +180,57 @@ public abstract class RestServlet extends HttpServlet 
implements RestInfoProvide
                return context;
        }
 
+       /**
+        * Instantiates the file finder to use for this REST resource.
+        *
+        * <p>
+        * Default implementation returns <jk>null</jk>
+        * which results in the default lookup logic as defined in {@link 
RestContext#createFileFinder()}.
+        *
+        * <ul class='seealso'>
+        *      <li class='link'>{@link RestContext#REST_fileFinder}.
+        * </ul>
+        *
+        * @return The file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
+        */
+       public FileFinder createFileFinder() {
+               return null;
+       }
+
+       /**
+        * Instantiates the static file finder to use for this REST resource.
+        *
+        * <p>
+        * Default implementation returns <jk>null</jk>
+        * which results in the default lookup logic as defined in {@link 
RestContext#createStaticFiles()}.
+        *
+        * <ul class='seealso'>
+        *      <li class='link'>{@link RestContext#REST_staticFiles}.
+        * </ul>
+        *
+        * @return The static file finder to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
+        */
+       public StaticFiles createStaticFiles() {
+               return null;
+       }
+
+       /**
+        * Instantiates the call logger to use for this REST resource.
+        *
+        * <p>
+        * Default implementation returns <jk>null</jk>
+        * which results in the default lookup logic as defined in {@link 
RestContext#createCallLogger()}.
+        *
+        * <ul class='seealso'>
+        *      <li class='link'>{@link RestContext#REST_callLogger}.
+        * </ul>
+        *
+        * @return The call logger to use for this REST resource, or 
<jk>null</jk> if default logic should be used.
+        */
+       public RestLogger createCallLogger() {
+               return null;
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Convenience logger methods
        
//-----------------------------------------------------------------------------------------------------------------
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 88b93ea..ee4d2fd 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
@@ -163,10 +163,6 @@ public @interface Rest {
         *              The resource class itself will be used if it implements 
the {@link RestLogger} interface and not
         *              explicitly overridden via this annotation.
         *      <li>
-        *              The {@link RestServlet} and {@link BasicRest} classes 
implement the {@link RestLogger} interface with the same
-        *              functionality as {@link BasicRestLogger} that gets used 
if not overridden by this annotation.
-        *              <br>Subclasses can also alter the behavior by 
overriding this method.
-        *      <li>
         *              The implementation must have one of the following 
constructors:
         *              <ul>
         *                      <li><code><jk>public</jk> T(RestContext)</code>
@@ -586,10 +582,6 @@ public @interface Rest {
         *              The resource class itself will be used if it implements 
the {@link RestInfoProvider} interface and not
         *              explicitly overridden via this annotation.
         *      <li>
-        *              The {@link RestServlet} and {@link BasicRest} classes 
implement the {@link RestInfoProvider} interface with the same
-        *              functionality as {@link BasicRestInfoProvider} that 
gets used if not overridden by this annotation.
-        *              <br>Subclasses can also alter the behavior by 
overriding these methods.
-        *      <li>
         *              The implementation must have one of the following 
constructors:
         *              <ul>
         *                      <li><code><jk>public</jk> T(RestContext)</code>
@@ -955,10 +947,6 @@ public @interface Rest {
         *              The resource class itself will be used if it implements 
the {@link RestResourceResolver} interface and not
         *              explicitly overridden via this annotation.
         *      <li>
-        *              The {@link RestServlet} and {@link BasicRest} classes 
implement the {@link RestResourceResolver} interface with the same
-        *              functionality as {@link BasicRestResourceResolver} that 
gets used if not overridden by this annotation.
-        *              <br>Subclasses can also alter the behavior by 
overriding these methods.
-        *      <li>
         *              The implementation must have one of the following 
constructors:
         *              <ul>
         *                      <li><code><jk>public</jk> T(RestContext)</code>
@@ -1123,7 +1111,7 @@ public @interface Rest {
         * Used to retrieve localized files to be served up as static files 
through the REST API via the following
         * predefined methods:
         * <ul class='javatree'>
-        *      <li class='jm'>{@link BasicRest#getHtdoc(String, Locale)}.
+        *      <li class='jm'>{@link BasicRestObject#getHtdoc(String, Locale)}.
         *      <li class='jm'>{@link BasicRestServlet#getHtdoc(String, 
Locale)}.
         * </ul>
         *

Reply via email to