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 7e4b836  Tests.
7e4b836 is described below

commit 7e4b836b5fed72d2262b21dbe26eb9dca99e6549
Author: JamesBognar <[email protected]>
AuthorDate: Sun May 13 18:40:43 2018 -0400

    Tests.
---
 .../juneau/rest/test/PathVariablesResource.java    |  50 --
 .../juneau/rest/test/PropertiesResource.java       | 107 ----
 .../juneau/rest/test/RestHooksInitResource.java    | 275 ---------
 .../apache/juneau/rest/test/RestHooksResource.java | 189 ------
 .../java/org/apache/juneau/rest/test/Root.java     |   5 -
 .../java/org/apache/juneau/rest/test/PathTest.java |  41 --
 .../apache/juneau/rest/test/PathVariableTest.java  |  51 --
 .../apache/juneau/rest/test/PropertiesTest.java    |  33 --
 .../apache/juneau/rest/test/RestHooksInitTest.java | 112 ----
 .../org/apache/juneau/rest/test/RestHooksTest.java |  72 ---
 .../org/apache/juneau/rest/test/_TestSuite.java    |   3 -
 .../java/org/apache/juneau/rest/RestContext.java   |  20 +-
 .../java/org/apache/juneau/rest/mock/MockRest.java |   2 +-
 .../rest/annotation/RestHookPostCallTest.java      | 133 -----
 .../rest/annotation/RestHookPreCallTest.java       | 104 ----
 .../juneau/rest/annotation/RestHookTest.java       | 631 +++++++++++++++++++++
 .../rest/annotation/RestResourcePathTest.java      |  71 ++-
 .../annotation/RestResourcePropertiesTest.java     |  91 +++
 18 files changed, 770 insertions(+), 1220 deletions(-)

diff --git 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathVariablesResource.java
 
b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathVariablesResource.java
deleted file mode 100644
index 2689b2f..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathVariablesResource.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static org.apache.juneau.http.HttpMethodName.*;
-
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.utils.*;
-
-/**
- * JUnit automated testcase resource.
- * Tests the <code>@RestMethod.path()</code> annotation.
- */
-@RestResource(
-       path="/testPathVariables"
-)
-public class PathVariablesResource extends BasicRestServlet {
-       private static final long serialVersionUID = 1L;
-
-       @RestMethod(name=GET, path="/test1/{x}/foo/{y}/bar/{z}/*")
-       public StringMessage test1(@Path("x") String x, @Path("y") int y, 
@Path("z") boolean z) {
-               return new StringMessage("x={0},y={1},z={2}", x, y, z);
-       }
-
-       @RestMethod(name=GET, path="/test2/{z}/foo/{y}/bar/{x}/*")
-       public StringMessage test2(@Path("x") String x, @Path("y") int y, 
@Path("z") boolean z) {
-               return new StringMessage("x={0},y={1},z={2}", x, y, z);
-       }
-
-       @RestMethod(name=GET, path="/test3/{0}/foo/{1}/bar/{2}/*")
-       public StringMessage test3(@Path("0") String x, @Path("1") int y, 
@Path("2") boolean z) {
-               return new StringMessage("x={0},y={1},z={2}", x, y, z);
-       }
-
-       @RestMethod(name=GET, path="/test4/{2}/foo/{1}/bar/{0}/*")
-       public StringMessage test4(@Path("0") String x, @Path("1") int y, 
@Path("2") boolean z) {
-               return new StringMessage("x={0},y={1},z={2}", x, y, z);
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PropertiesResource.java
 
b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PropertiesResource.java
deleted file mode 100644
index 9dcd055..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PropertiesResource.java
+++ /dev/null
@@ -1,107 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static java.lang.String.*;
-import static org.apache.juneau.http.HttpMethodName.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.serializer.*;
-
-/**
- * JUnit automated testcase resource.
- */
-@RestResource(
-       path="/testProperties",
-       properties={
-               @Property(name="A1",value="a1"),
-               @Property(name="A2",value="a2"),
-               @Property(name="foo",value="bar"),
-               @Property(name="bar",value="baz"),
-               @Property(name="R1a",value="$R{requestURI}"),
-               @Property(name="R1b",value="$R{requestParentURI}"),
-               @Property(name="R2",value="$R{foo}"),
-               @Property(name="R3",value="$R{$R{foo}}"),
-               @Property(name="R4",value="$R{A1}"),
-               @Property(name="R5",value="$R{A2}"),
-               @Property(name="R6",value="$R{C}"),
-       }
-)
-public class PropertiesResource extends BasicRestServlet {
-       private static final long serialVersionUID = 1L;
-
-       
//====================================================================================================
-       // Properties defined on method.
-       
//====================================================================================================
-       @RestMethod(name=GET, path="/testPropertiesDefinedOnMethod",
-               properties={
-                       @Property(name="B1",value="b1"),
-                       @Property(name="B2",value="b2")
-               },
-               serializers=PropertySerializer1.class
-       )
-       public void testPropertiesDefinedOnMethod(RestResponse res) {
-               res.prop("A2", "c");
-               res.prop("B2", "c");
-               res.prop("C", "c");
-               res.setOutput(null);
-       }
-
-       public static class PropertySerializer1 extends WriterSerializer {
-
-               public PropertySerializer1(PropertyStore ps) {
-                       super(ps, "application/json", "*/json");
-               }
-
-               @Override /* Serializer */
-               public WriterSerializerSession 
createSession(SerializerSessionArgs args) {
-                       return new WriterSerializerSession(args) {
-
-                               @Override /* SerializerSession */
-                               protected void doSerialize(SerializerPipe out, 
Object o) throws Exception {
-                                       
out.getWriter().write(format("A1=%s,A2=%s,B1=%s,B2=%s,C=%s,R1a=%s,R1b=%s,R2=%s,R3=%s,R4=%s,R5=%s,R6=%s",
-                                               getProperty("A1"), 
getProperty("A2"), getProperty("B1"), getProperty("B2"), getProperty("C"),
-                                               getProperty("R1a"), 
getProperty("R1b"), getProperty("R2"), getProperty("R3"), getProperty("R4"), 
getProperty("R5"), getProperty("R6")));
-                               }
-                       };
-               }
-       }
-
-       
//====================================================================================================
-       // Make sure attributes/parameters/headers are available through 
ctx.getProperties().
-       
//====================================================================================================
-       @RestMethod(name=GET, path="/testProperties/{A}", 
serializers=PropertySerializer2.class)
-       public void testProperties(RestResponse res) {
-               res.setOutput(null);
-       }
-
-       public static class PropertySerializer2 extends WriterSerializer {
-
-               public PropertySerializer2(PropertyStore ps) {
-                       super(ps, "application/json", "*/json");
-               }
-
-               @Override /* Serializer */
-               public WriterSerializerSession 
createSession(SerializerSessionArgs args) {
-                       return new WriterSerializerSession(args) {
-
-                               @Override /* SerializerSession */
-                               protected void doSerialize(SerializerPipe out, 
Object o) throws Exception {
-                                       
out.getWriter().write(format("A=%s,P=%s,H=%s", getProperty("A"), 
getProperty("P"), getProperty("h")));
-                               }
-                       };
-               }
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/RestHooksInitResource.java
 
b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/RestHooksInitResource.java
deleted file mode 100644
index 3b8a838..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/RestHooksInitResource.java
+++ /dev/null
@@ -1,275 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static org.apache.juneau.rest.annotation.HookEvent.*;
-import static org.apache.juneau.http.HttpMethodName.*;
-
-import java.util.*;
-
-import javax.servlet.*;
-
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-
-/**
- * Validates the behavior of the 
@RestHook(INIT/POST_INIT/POST_INIT_CHILD_FIRST) annotations.
- */
-@RestResource(
-       path="/testRestHooksInit",
-       children={
-               RestHooksInitResource.Super.class,
-               RestHooksInitResource.Sub.class
-       }
-)
-public class RestHooksInitResource extends BasicRestServlet {
-       private static final long serialVersionUID = 1L;
-
-       @RestResource(
-               path="/super"
-       )
-       public static class Super extends BasicRestServlet {
-               private static final long serialVersionUID = 1L;
-
-               protected List<String> init = new ArrayList<String>();
-               protected List<String> postInit = new ArrayList<String>();
-               protected List<String> postInitChildFirst = new 
ArrayList<String>();
-
-               @RestHook(INIT)
-               public void init1c(RestContextBuilder builder) {
-                       init.add("super-1c");
-               }
-
-               @RestHook(INIT)
-               public void init1a(ServletConfig config) {
-                       init.add("super-1a");
-               }
-
-               @RestHook(INIT)
-               public void init1b() {
-                       init.add("super-1b");
-               }
-
-               @RestHook(INIT)
-               public void init2a() {
-                       init.add("super-2a");
-               }
-
-               @RestHook(POST_INIT)
-               public void postInit1c(RestContext context) {
-                       postInit.add("super-1c");
-               }
-
-               @RestHook(POST_INIT)
-               public void postInit1a(RestContext context) {
-                       postInit.add("super-1a");
-               }
-
-               @RestHook(POST_INIT)
-               public void postInit1b() {
-                       postInit.add("super-1b");
-               }
-
-               @RestHook(POST_INIT)
-               public void postInit2a() {
-                       postInit.add("super-2a");
-               }
-
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst1c(RestContext context) {
-                       postInitChildFirst.add("super-1c");
-               }
-
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst1a(RestContext context) {
-                       postInitChildFirst.add("super-1a");
-               }
-
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst1b() {
-                       postInitChildFirst.add("super-1b");
-               }
-
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst2a() {
-                       postInitChildFirst.add("super-2a");
-               }
-
-               @RestMethod(name=GET, path="/init")
-               public List<String> getInitEvents() {
-                       return init;
-               }
-
-               @RestMethod(name=GET, path="/postInit")
-               public List<String> getPostInitEvents() {
-                       return postInit;
-               }
-
-               @RestMethod(name=GET, path="/postInitChildFirst")
-               public List<String> getPostInitChildFirstEvents() {
-                       return postInitChildFirst;
-               }
-       }
-
-       @RestResource(
-               path="/sub",
-               children={
-                       Child.class
-               }
-       )
-       public static class Sub extends Super {
-               private static final long serialVersionUID = 1L;
-
-               protected static String postInitOrderTest;
-               protected static String postInitChildFirstOrderTest;
-
-               @Override
-               @RestHook(INIT)
-               public void init1c(RestContextBuilder builder) {
-                       init.add("sub-1c");
-               }
-
-               @Override
-               @RestHook(INIT)
-               public void init1a(ServletConfig config) {
-                       init.add("sub-1a");
-               }
-
-               @Override
-               @RestHook(INIT)
-               public void init1b() {
-                       init.add("sub-1b");
-               }
-
-               @RestHook(INIT)
-               public void init2b() {
-                       init.add("sub-2b");
-               }
-
-               @Override
-               @RestHook(POST_INIT)
-               public void postInit1c(RestContext context) {
-                       postInit.add("sub-1c");
-               }
-
-               @Override
-               @RestHook(POST_INIT)
-               public void postInit1a(RestContext context) {
-                       postInit.add("sub-1a");
-               }
-
-               @Override
-               @RestHook(POST_INIT)
-               public void postInit1b() {
-                       postInit.add("sub-1b");
-               }
-
-               @RestHook(POST_INIT)
-               public void postInit2b() {
-                       postInit.add("sub-2b");
-               }
-
-               @Override
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst1c(RestContext context) {
-                       postInitChildFirst.add("sub-1c");
-               }
-
-               @Override
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst1a(RestContext context) {
-                       postInitChildFirst.add("sub-1a");
-               }
-
-               @Override
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst1b() {
-                       postInitChildFirst.add("sub-1b");
-               }
-
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst2b() {
-                       postInitChildFirst.add("sub-2b");
-               }
-
-               @RestHook(POST_INIT)
-               public void postInitOrderTestSub() {
-                       postInitOrderTest = "PARENT";
-               }
-
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirstOrderTestSub() {
-                       postInitChildFirstOrderTest = "PARENT";
-               }
-
-               @RestMethod(name=GET, path="/postInitOrder")
-               public String postInitOrderTest() {
-                       return postInitOrderTest;
-               }
-
-               @RestMethod(name=GET, path="/postInitChildFirstOrder")
-               public String postInitChildFirstOrderTest() {
-                       return postInitChildFirstOrderTest;
-               }
-       }
-
-       @RestResource(
-               path="/child"
-       )
-       public static class Child extends Super {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               @RestHook(INIT)
-               public void init1c(RestContextBuilder builder) {
-                       init.add("child-1c");
-               }
-
-               @RestHook(INIT)
-               public void init2b() {
-                       init.add("child-2b");
-               }
-
-               @Override
-               @RestHook(POST_INIT)
-               public void postInit1c(RestContext context) {
-                       postInit.add("child-1c");
-               }
-
-               @RestHook(POST_INIT)
-               public void postInit2b() {
-                       postInit.add("child-2b");
-               }
-
-               @Override
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst1c(RestContext context) {
-                       postInitChildFirst.add("child-1c");
-               }
-
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirst2b() {
-                       postInitChildFirst.add("child-2b");
-               }
-
-               @RestHook(POST_INIT)
-               public void postInitOrderTestSub() {
-                       Sub.postInitOrderTest = "CHILD";
-               }
-
-               @RestHook(POST_INIT_CHILD_FIRST)
-               public void postInitChildFirstOrderTestSub() {
-                       Sub.postInitChildFirstOrderTest = "CHILD";
-               }
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/RestHooksResource.java
 
b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/RestHooksResource.java
deleted file mode 100644
index 333034b..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/RestHooksResource.java
+++ /dev/null
@@ -1,189 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static org.apache.juneau.rest.annotation.HookEvent.*;
-
-import java.util.*;
-
-import javax.servlet.http.*;
-
-import org.apache.juneau.http.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.utils.*;
-
-/**
- * Validates the behavior of the @RestHook(START/PRE/POST) annotations.
- */
-@RestResource(
-       path="/testRestHooks",
-       children={
-               RestHooksResource.Start.class,
-               RestHooksResource.Pre.class,
-               RestHooksResource.Post.class,
-       }
-)
-public class RestHooksResource extends BasicRestServlet {
-       private static final long serialVersionUID = 1L;
-
-       @RestResource(
-               path="/start"
-       )
-       public static class Start extends StartParent {
-               private static final long serialVersionUID = 1L;
-
-               private boolean start3Called;
-
-               @RestHook(START_CALL)
-               public void start3() {
-                       start3Called = true;
-               }
-
-               @RestHook(START_CALL)
-               public void start4(HttpServletRequest req, HttpServletResponse 
res) {
-                       res.setHeader("start3-called", ""+start3Called);
-                       start3Called = false;
-                       if (res.getHeader("start4-called") != null)
-                               throw new RuntimeException("start4 called 
multiple times.");
-                       res.setHeader("start4-called", "true");
-               }
-
-               @RestMethod(path="/")
-               public Map<String,Object> getHeaders(RestRequest req, 
RestResponse res) {
-                       return new AMap<String,Object>()
-                               .append("1", res.getHeader("start1-called"))
-                               .append("2", res.getHeader("start2-called"))
-                               .append("3", res.getHeader("start3-called"))
-                               .append("4", res.getHeader("start4-called"));
-               }
-       }
-
-       public static class StartParent extends BasicRestServlet {
-               private static final long serialVersionUID = 1L;
-
-               private boolean start1Called;
-
-               @RestHook(START_CALL)
-               public void start1() {
-                       start1Called = true;
-               }
-
-               @RestHook(START_CALL)
-               public void start2(HttpServletRequest req, HttpServletResponse 
res) {
-                       res.setHeader("start1-called", ""+start1Called);
-                       start1Called = false;
-                       if (res.getHeader("start2-called") != null)
-                               throw new RuntimeException("start2 called 
multiple times.");
-                       res.setHeader("start2-called", "true");
-               }
-       }
-
-       @RestResource(
-               path="/pre"
-       )
-       public static class Pre extends PreParent {
-               private static final long serialVersionUID = 1L;
-
-               private boolean pre3Called;
-
-               @RestHook(PRE_CALL)
-               public void pre3() {
-                       pre3Called = true;
-               }
-
-               @RestHook(PRE_CALL)
-               public void pre4(HttpServletRequest req, HttpServletResponse 
res) {
-                       res.setHeader("pre3-called", ""+pre3Called);
-                       pre3Called = false;
-                       if (res.getHeader("pre4-called") != null)
-                               throw new RuntimeException("pre4 called 
multiple times.");
-                       res.setHeader("pre4-called", "true");
-               }
-
-               @RestMethod(path="/")
-               public Map<String,Object> getHeaders(RestRequest req, 
RestResponse res) {
-                       return new AMap<String,Object>()
-                               .append("1", res.getHeader("pre1-called"))
-                               .append("2", res.getHeader("pre2-called"))
-                               .append("3", res.getHeader("pre3-called"))
-                               .append("4", res.getHeader("pre4-called"));
-               }
-       }
-
-       public static class PreParent extends BasicRestServlet {
-               private static final long serialVersionUID = 1L;
-
-               private boolean pre1Called;
-
-               @RestHook(PRE_CALL)
-               public void pre1() {
-                       pre1Called = true;
-               }
-
-               @RestHook(PRE_CALL)
-               public void pre2(Accept accept, RestRequest req, RestResponse 
res) {
-                       res.setHeader("pre1-called", ""+pre1Called);
-                       pre1Called = false;
-                       if (res.getHeader("pre2-called") != null)
-                               throw new RuntimeException("pre2 called 
multiple times.");
-                       res.setHeader("pre2-called", "true");
-               }
-       }
-
-       @RestResource(
-               path="/post"
-       )
-       public static class Post extends PostParent {
-               private static final long serialVersionUID = 1L;
-               private boolean post3Called;
-
-               @RestHook(POST_CALL)
-               public void post3() {
-                       post3Called = true;
-               }
-
-               @RestHook(POST_CALL)
-               public void post4(HttpServletRequest req, HttpServletResponse 
res) {
-                       res.setHeader("post3-called", ""+post3Called);
-                       post3Called = false;
-                       if (res.getHeader("post4-called") != null)
-                               throw new RuntimeException("post4 called 
multiple times.");
-                       res.setHeader("post4-called", "true");
-               }
-
-               @RestMethod(path="/")
-               public String doGet() {
-                       return "OK";
-               }
-       }
-
-       public static class PostParent extends BasicRestServlet {
-               private static final long serialVersionUID = 1L;
-               private boolean post1Called;
-
-               @RestHook(POST_CALL)
-               public void post1() {
-                       post1Called = true;
-               }
-
-               @RestHook(POST_CALL)
-               public void post2(Accept accept, RestRequest req, RestResponse 
res) {
-                       res.setHeader("post1-called", ""+post1Called);
-                       post1Called = false;
-                       if (res.getHeader("post2-called") != null)
-                               throw new RuntimeException("post2 called 
multiple times.");
-                       res.setHeader("post2-called", "true");
-               }
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/Root.java
 
b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/Root.java
index 7d3cc7b..09f4056 100644
--- 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/Root.java
+++ 
b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/Root.java
@@ -36,14 +36,9 @@ import org.apache.juneau.rest.test.client.*;
                InterfaceProxyResource.class,
                LargePojosResource.class,
                ParsersResource.class,
-               PathResource.class,
                PathsResource.class,
-               PathVariablesResource.class,
-               PropertiesResource.class,
                RequestBeanProxyResource.class,
                RestClient2Resource.class,
-               RestHooksInitResource.class,
-               RestHooksResource.class,
                SerializersResource.class,
                StaticFilesResource.class,
                ThirdPartyProxyResource.class,
diff --git 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PathTest.java
 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PathTest.java
deleted file mode 100644
index a4c9db5..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PathTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static org.junit.Assert.*;
-
-import org.apache.juneau.rest.client.*;
-import org.junit.*;
-
-public class PathTest extends RestTestcase {
-
-       private static String URL = "/testPath";
-
-       
//====================================================================================================
-       // Basic tests
-       
//====================================================================================================
-       @Test
-       public void testBasic() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               String r = null;
-
-               r = client.doGet(URL).getResponse(String.class);
-               assertEquals("/testPath", r);
-
-               r = client.doGet(URL + "/testPath2").getResponse(String.class);
-               assertEquals("/testPath/testPath2", r);
-
-               r = client.doGet(URL + 
"/testPath2/testPath3").getResponse(String.class);
-               assertEquals("/testPath/testPath2/testPath3", r);
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PathVariableTest.java
 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PathVariableTest.java
deleted file mode 100644
index 3f20146..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PathVariableTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static org.junit.Assert.*;
-
-import org.apache.juneau.rest.client.*;
-import org.junit.*;
-
-/**
- * Tests the <code>@RestMethod.path()</code> annotation.
- */
-public class PathVariableTest extends RestTestcase {
-
-       private static String URL = "/testPathVariables";
-       RestClient client = TestMicroservice.DEFAULT_CLIENT;
-
-       @Test
-       public void test1() throws Exception {
-               String r = client.doGet(URL + 
"/test1/xxx/foo/123/bar/true").getResponseAsString();
-               assertEquals("x=xxx,y=123,z=true", r);
-       }
-
-       @Test
-       public void test2() throws Exception {
-               String r = client.doGet(URL + 
"/test2/true/foo/123/bar/xxx").getResponseAsString();
-               assertEquals("x=xxx,y=123,z=true", r);
-       }
-
-       @Test
-       public void test3() throws Exception {
-               String r = client.doGet(URL + 
"/test3/xxx/foo/123/bar/true").getResponseAsString();
-               assertEquals("x=xxx,y=123,z=true", r);
-       }
-
-       @Test
-       public void test4() throws Exception {
-               String r = client.doGet(URL + 
"/test4/true/foo/123/bar/xxx").getResponseAsString();
-               assertEquals("x=xxx,y=123,z=true", r);
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
deleted file mode 100644
index e34b382..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static org.junit.Assert.*;
-
-import org.apache.juneau.rest.client.*;
-import org.junit.*;
-
-public class PropertiesTest extends RestTestcase {
-
-       private static String URL = "/testProperties";
-
-       
//====================================================================================================
-       // Properties defined on method.
-       
//====================================================================================================
-       @Test
-       public void testPropertiesDefinedOnMethod() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               String r = client.doGet(URL + 
"/testPropertiesDefinedOnMethod").getResponseAsString();
-               
assertTrue(r.matches("A1=a1,A2=c,B1=b1,B2=c,C=c,R1a=.*/testProperties/testPropertiesDefinedOnMethod,R1b=.*/testProperties,R2=bar,R3=,R4=a1,R5=c,R6=c"));
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestHooksInitTest.java
 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestHooksInitTest.java
deleted file mode 100644
index 99ab093..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestHooksInitTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static org.apache.juneau.rest.testutils.TestUtils.*;
-
-import java.util.*;
-
-import org.apache.juneau.rest.client.*;
-import org.junit.*;
-
-/**
- * Validates the behavior of the 
@RestHook(INIT/POST_INIT/POST_INIT_CHILD_FIRST) annotations.
- */
-public class RestHooksInitTest extends RestTestcase {
-
-       private static String URL = "/testRestHooksInit";
-
-       
//====================================================================================================
-       // @RestHook(INIT)
-       
//====================================================================================================
-       @Test
-       public void testInit() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               String e;
-               Object r;
-
-               r = client.doGet(URL + "/super/init").getResponse(List.class);
-               e = "['super-1a','super-1b','super-1c','super-2a']";
-               assertObjectEquals(e, r);
-
-               r = client.doGet(URL + "/sub/init").getResponse(List.class);
-               e = "['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']";
-               assertObjectEquals(e, r);
-
-               r = client.doGet(URL + 
"/sub/child/init").getResponse(List.class);
-               e = "['super-1a','super-1b','child-1c','super-2a','child-2b']";
-               assertObjectEquals(e, r);
-       }
-
-       
//====================================================================================================
-       // @RestHook(POST_INIT)
-       
//====================================================================================================
-       @Test
-       public void testPostInit() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               String e;
-               Object r;
-
-               r = client.doGet(URL + 
"/super/postInit").getResponse(List.class);
-               e = "['super-1a','super-1b','super-1c','super-2a']";
-               assertObjectEquals(e, r);
-
-               r = client.doGet(URL + "/sub/postInit").getResponse(List.class);
-               e = "['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']";
-               assertObjectEquals(e, r);
-
-               r = client.doGet(URL + 
"/sub/child/postInit").getResponse(List.class);
-               e = "['super-1a','super-1b','child-1c','super-2a','child-2b']";
-               assertObjectEquals(e, r);
-       }
-
-       
//====================================================================================================
-       // @RestHook(POST_INIT_CHILD_FIRST)
-       
//====================================================================================================
-       @Test
-       public void testPostInitChildFirst() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               String e;
-               Object r;
-
-               r = client.doGet(URL + 
"/super/postInitChildFirst").getResponse(List.class);
-               e = "['super-1a','super-1b','super-1c','super-2a']";
-               assertObjectEquals(e, r);
-
-               r = client.doGet(URL + 
"/sub/postInitChildFirst").getResponse(List.class);
-               e = "['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']";
-               assertObjectEquals(e, r);
-
-               r = client.doGet(URL + 
"/sub/child/postInitChildFirst").getResponse(List.class);
-               e = "['super-1a','super-1b','child-1c','super-2a','child-2b']";
-               assertObjectEquals(e, r);
-       }
-
-       
//====================================================================================================
-       // @RestHook(POST_INIT/POST_INIT_CHILD_FIRST) orders
-       
//====================================================================================================
-       @Test
-       public void testPostInitChildFirstOrder() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               String e;
-               Object r;
-
-               r = client.doGet(URL + 
"/sub/postInitOrder").getResponse(String.class);
-               e = "'CHILD'";
-               assertObjectEquals(e, r);
-
-               r = client.doGet(URL + 
"/sub/postInitChildFirstOrder").getResponse(String.class);
-               e = "'PARENT'";
-               assertObjectEquals(e, r);
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestHooksTest.java
 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestHooksTest.java
deleted file mode 100644
index f306c0c..0000000
--- 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestHooksTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.test;
-
-import static org.apache.juneau.microservice.testutils.TestUtils.*;
-import static org.junit.Assert.*;
-
-import java.util.*;
-
-import org.apache.http.*;
-import org.apache.juneau.rest.client.*;
-import org.junit.*;
-
-/**
- * Validates the behavior of the @RestHook(START/PRE/POST) annotations.
- */
-public class RestHooksTest extends RestTestcase {
-
-       private static String URL = "/testRestHooks";
-
-       
//====================================================================================================
-       // @RestHook(START)
-       
//====================================================================================================
-       @Test
-       public void testStart() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               String e;
-               Object r;
-
-               r = client.doGet(URL + "/start").getResponse(Map.class);
-               e = "{'1':'true','2':'true','3':'true','4':'true'}";
-               assertObjectEquals(e, r);
-       }
-
-       
//====================================================================================================
-       // @RestHook(START)
-       
//====================================================================================================
-       @Test
-       public void testPre() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               String e;
-               Object r;
-
-               r = client.doGet(URL + "/pre").getResponse(Map.class);
-               e = "{'1':'true','2':'true','3':'true','4':'true'}";
-               assertObjectEquals(e, r);
-       }
-
-       
//====================================================================================================
-       // @RestHook(POST)
-       
//====================================================================================================
-       @Test
-       public void testPost() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-
-               HttpResponse res = client.doGet(URL + "/post").getResponse();
-               assertEquals("true", 
res.getFirstHeader("post1-called").getValue());
-               assertEquals("true", 
res.getFirstHeader("post2-called").getValue());
-               assertEquals("true", 
res.getFirstHeader("post3-called").getValue());
-               assertEquals("true", 
res.getFirstHeader("post4-called").getValue());
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
index dd1f200..0105ddf 100644
--- 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
+++ 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
@@ -36,9 +36,6 @@ import org.junit.runners.Suite.*;
        LargePojosTest.class,
        ParsersTest.class,
        PathsTest.class,
-       PathTest.class,
-       PathVariableTest.class,
-       PropertiesTest.class,
        RequestBeanProxyTest.class,
        RestClientTest.class,
        SerializersTest.class,
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 ad4890e..37154f5 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
@@ -4435,24 +4435,32 @@ public final class RestContext extends BeanContext {
                }
        }
 
-       /*
-        * Calls all @RestHook(POST_INIT) methods.
+       /**
+        * Calls all @RestHook(POST_INIT) methods in parent-to-child order.
+        * 
+        * @return This object (for method chaining). 
+        * @throws ServletException 
         */
-       void postInit() throws ServletException {
+       public RestContext postInit() throws ServletException {
                for (int i = 0; i < postInitMethods.length; i++)
                        postInitOrDestroy(resource, postInitMethods[i], 
postInitMethodParams[i]);
                for (RestContext childContext : this.childResources.values())
                        childContext.postInit();
+               return this;
        }
 
-       /*
-        * Calls all @RestHook(POST_INIT_CHILD_FIRST) methods.
+       /**
+        * Calls all @RestHook(POST_INIT_CHILD_FIRST) methods in 
child-to-parent order.
+        * 
+        * @return This object (for method chaining). 
+        * @throws ServletException 
         */
-       void postInitChildFirst() throws ServletException {
+       public RestContext postInitChildFirst() throws ServletException {
                for (RestContext childContext : this.childResources.values())
                        childContext.postInitChildFirst();
                for (int i = 0; i < postInitChildFirstMethods.length; i++)
                        postInitOrDestroy(resource, 
postInitChildFirstMethods[i], postInitChildFirstMethodParams[i]);
+               return this;
        }
 
        private void postInitOrDestroy(Object r, Method m, Class<?>[] p) {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
index e88af04..6d3adb8 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
@@ -55,7 +55,7 @@ public class MockRest {
        
        private MockRest(Class<?> c) throws Exception {
                if (! CONTEXTS.containsKey(c))
-                       CONTEXTS.put(c, 
RestContext.create(c.newInstance()).build());
+                       CONTEXTS.put(c, 
RestContext.create(c.newInstance()).build().postInit().postInitChildFirst());
                rc = CONTEXTS.get(c);
        }
        
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookPostCallTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookPostCallTest.java
deleted file mode 100644
index 1c632fd..0000000
--- 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookPostCallTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.annotation;
-
-import static org.apache.juneau.http.HttpMethodName.*;
-import static org.apache.juneau.rest.annotation.HookEvent.*;
-
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.mock.*;
-import org.apache.juneau.serializer.*;
-import org.apache.juneau.utils.*;
-import org.junit.*;
-import org.junit.runners.*;
-
-/**
- * Tests aspects of @RestHook(POST_CALL).
- */
-@SuppressWarnings({"javadoc"})
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class RestHookPostCallTest {
-
-       
//=================================================================================================================
-       // @RestHook(POST_CALL)
-       
//=================================================================================================================
-
-       @RestResource(
-               serializers=A01.class,
-               properties={
-                       @Property(name="p1",value="sp1"), // Unchanged 
servlet-level property.
-                       @Property(name="p2",value="sp2"), // Servlet-level 
property overridden by onPostCall.
-                       @Property(name="p3",value="sp3"), // Servlet-level 
property overridded by method.
-                       @Property(name="p4",value="sp4")  // Servlet-level 
property overridden by method then onPostCall.
-               }
-       )
-       public static class A {
-
-               @RestHook(POST_CALL)
-               public void onPostCall(RestRequest req, RestResponse res) {
-                       RequestProperties properties = req.getProperties();
-                       properties.put("p2", "xp2");
-                       properties.put("p4", "xp4");
-                       properties.put("p5", "xp5"); // New property
-                       String overrideAccept = 
req.getHeader("Override-Accept");
-                       if (overrideAccept != null)
-                               req.getHeaders().put("Accept", overrideAccept);
-                       String overrideContentType = 
req.getHeader("Override-Content-Type");
-                       if (overrideContentType != null)
-                               properties.put("Override-Content-Type", 
overrideContentType);
-               }
-
-               @RestMethod(name=PUT, path="/propertiesOverridenByAnnotation",
-                       properties={
-                               @Property(name="p3",value="mp3"),
-                               @Property(name="p4",value="mp4")
-                       },
-                       defaultRequestHeaders="Accept: text/s2"
-               )
-               public String a01() {
-                       return null;
-               }
-
-               @RestMethod(name=PUT, 
path="/propertiesOverriddenProgramatically")
-               public String a02(RestRequest req, RequestProperties 
properties) throws Exception {
-                       properties.put("p3", "pp3");
-                       properties.put("p4", "pp4");
-                       String accept = req.getHeader("Accept");
-                       if (accept == null || accept.isEmpty())
-                               req.getHeaders().put("Accept", "text/s2");
-                       return null;
-               }
-       }
-       static MockRest a = MockRest.create(A.class);
-
-       public static class A01 extends WriterSerializer {
-               public A01(PropertyStore ps) {
-                       super(ps, "test/s1", "text/s1,text/s2,text/s3");
-               }
-               @Override /* Serializer */
-               public WriterSerializerSession 
createSession(SerializerSessionArgs args) {
-                       return new WriterSerializerSession(args) {
-                               @Override /* SerializerSession */
-                               protected void doSerialize(SerializerPipe out, 
Object o) throws Exception {
-                                       
out.getWriter().write("p1="+getProperty("p1", 
String.class)+",p2="+getProperty("p2", String.class)+",p3="+getProperty("p3", 
String.class)+",p4="+getProperty("p4", String.class)+",p5="+getProperty("p5", 
String.class)+",contentType="+getProperty("mediaType", String.class));
-                               }
-                               @Override /* SerializerSession */
-                               public Map<String,String> getResponseHeaders() {
-                                       ObjectMap p = getProperties();
-                                       if 
(p.containsKey("Override-Content-Type"))
-                                               return new 
AMap<String,String>().append("Content-Type", 
p.getString("Override-Content-Type"));
-                                       return Collections.emptyMap();
-                               }
-                       };
-               }
-       }
-
-       @Test
-       public void a01a_propertiesOverridenByAnnotation() throws Exception {
-               a.request("PUT", 
"/propertiesOverridenByAnnotation").accept("text/s1").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s1");
-               a.request("PUT", 
"/propertiesOverridenByAnnotation").accept("text/s1").header("Override-Accept", 
"text/s2").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2");
-               a.request("PUT", 
"/propertiesOverridenByAnnotation").accept("text/s1").header("Override-Content-Type",
 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s1");
-       }
-       @Test
-       public void a01b_propertiesOverridenByAnnotation_defaultAccept() throws 
Exception {
-               a.request("PUT", 
"/propertiesOverridenByAnnotation").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2");
-               a.request("PUT", 
"/propertiesOverridenByAnnotation").header("Override-Accept", 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s3");
-               a.request("PUT", 
"/propertiesOverridenByAnnotation").header("Override-Content-Type", 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2");
-       }
-       @Test
-       public void a02a_propertiesOverriddenProgramatically() throws Exception 
{
-               a.request("PUT", 
"/propertiesOverriddenProgramatically").accept("text/s1").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s1");
-               a.request("PUT", 
"/propertiesOverriddenProgramatically").accept("text/s1").header("Override-Accept",
 
"text/s2").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2");
-               a.request("PUT", 
"/propertiesOverriddenProgramatically").accept("text/s1").header("Override-Content-Type",
 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s1");
-       }
-       @Test
-       public void a02b_propertiesOverriddenProgramatically_defaultAccept() 
throws Exception {
-               a.request("PUT", 
"/propertiesOverriddenProgramatically").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2");
-               a.request("PUT", 
"/propertiesOverriddenProgramatically").header("Override-Accept", 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s3");
-               a.request("PUT", 
"/propertiesOverriddenProgramatically").header("Override-Content-Type", 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2");
-       }
-}
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookPreCallTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookPreCallTest.java
deleted file mode 100644
index ca63420..0000000
--- 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookPreCallTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.annotation;
-
-import static org.apache.juneau.http.HttpMethodName.*;
-import static org.apache.juneau.rest.annotation.HookEvent.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.parser.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.mock.*;
-import org.junit.*;
-import org.junit.runners.*;
-
-/**
- * Tests aspects of @RestHook(PRE_CALL).
- */
-@SuppressWarnings({"javadoc"})
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class RestHookPreCallTest {
-
-       
//=================================================================================================================
-       // @RestHook(PRE_CALL)
-       
//=================================================================================================================
-       @RestResource(
-               parsers=A01.class,
-               properties={
-                       @Property(name="p1",value="sp1"), // Unchanged 
servlet-level property.
-                       @Property(name="p2",value="sp2"), // Servlet-level 
property overridden by onPreCall.
-                       @Property(name="p3",value="sp3"), // Servlet-level 
property overridded by method.
-                       @Property(name="p4",value="sp4")  // Servlet-level 
property overridden by method then onPreCall.
-               }
-       )
-       public static class A {
-
-               @RestHook(PRE_CALL)
-               public void onPreCall(RestRequest req) {
-                       RequestProperties properties = req.getProperties();
-                       properties.put("p2", "xp2");
-                       properties.put("p4", "xp4");
-                       properties.put("p5", "xp5"); // New property
-                       String overrideContentType = 
req.getHeader("Override-Content-Type");
-                       if (overrideContentType != null)
-                               req.getHeaders().put("Content-Type", 
overrideContentType);
-               }
-
-               @RestMethod(name=PUT, path="/propertiesOverriddenByAnnotation",
-                       properties={
-                               @Property(name="p3",value="mp3"),
-                               @Property(name="p4",value="mp4")
-                       }
-               )
-               public String a01(@Body String in) {
-                       return in;
-               }
-
-               @RestMethod(name=PUT, 
path="/propertiesOverriddenProgrammatically")
-               public String a02(RestRequest req, RequestProperties 
properties) throws Exception {
-                       properties.put("p3", "pp3");
-                       properties.put("p4", "pp4");
-                       return req.getBody().asType(String.class);
-               }
-       }
-       static MockRest a = MockRest.create(A.class);
-
-       public static class A01 extends ReaderParser {
-               public A01(PropertyStore ps) {
-                       super(ps, "text/a1", "text/a2", "text/a3");
-               }
-               @Override /* Parser */
-               public ReaderParserSession createSession(ParserSessionArgs 
args) {
-                       return new ReaderParserSession(args) {
-                               @Override /* ParserSession */
-                               @SuppressWarnings("unchecked")
-                               protected <T> T doParse(ParserPipe pipe, 
ClassMeta<T> type) throws Exception {
-                                       String matchingContentType = 
getProperty("mediaType", String.class);
-                                       return (T)("p1="+getProperty("p1", 
String.class)+",p2="+getProperty("p2", String.class)+",p3="+getProperty("p3", 
String.class)+",p4="+getProperty("p4", String.class)+",p5="+getProperty("p5", 
String.class)+",contentType="+matchingContentType);
-                               }
-                       };
-               }
-       }
-
-       @Test
-       public void a01_propertiesOverriddenByAnnotation() throws Exception {
-               a.request("PUT", 
"/propertiesOverriddenByAnnotation").contentType("text/a1").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/a1");
-               a.request("PUT", 
"/propertiesOverriddenByAnnotation").contentType("text/a1").header("Override-Content-Type",
 
"text/a2").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/a2");
-       }
-
-       @Test
-       public void a02_propertiesOverriddenProgrammatically() throws Exception 
{
-               a.request("PUT", 
"/propertiesOverriddenProgrammatically").contentType("text/a1").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5,contentType=text/a1");
-               a.request("PUT", 
"/propertiesOverriddenProgrammatically").contentType("text/a1").header("Override-Content-Type",
 
"text/a2").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5,contentType=text/a2");
-       }
-}
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookTest.java
new file mode 100644
index 0000000..66c31ad
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestHookTest.java
@@ -0,0 +1,631 @@
+// 
***************************************************************************************************************************
+// * 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.annotation;
+
+import static org.apache.juneau.http.HttpMethodName.*;
+import static org.apache.juneau.rest.annotation.HookEvent.*;
+
+import java.util.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.mock.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+/**
+ * Tests aspects of @RestHook.
+ */
+@SuppressWarnings({"javadoc"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class RestHookTest {
+
+       
//=================================================================================================================
+       // @RestHook(PRE_CALL)
+       
//=================================================================================================================
+       
+       @RestResource(
+               parsers=A01.class,
+               properties={
+                       @Property(name="p1",value="sp1"), // Unchanged 
servlet-level property.
+                       @Property(name="p2",value="sp2"), // Servlet-level 
property overridden by onPreCall.
+                       @Property(name="p3",value="sp3"), // Servlet-level 
property overridded by method.
+                       @Property(name="p4",value="sp4")  // Servlet-level 
property overridden by method then onPreCall.
+               }
+       )
+       public static class A {
+
+               @RestHook(PRE_CALL)
+               public void onPreCall(RestRequest req) {
+                       RequestProperties properties = req.getProperties();
+                       properties.put("p2", "xp2");
+                       properties.put("p4", "xp4");
+                       properties.put("p5", "xp5"); // New property
+                       String overrideContentType = 
req.getHeader("Override-Content-Type");
+                       if (overrideContentType != null)
+                               req.getHeaders().put("Content-Type", 
overrideContentType);
+               }
+
+               @RestMethod(name=PUT, path="/propertiesOverriddenByAnnotation",
+                       properties={
+                               @Property(name="p3",value="mp3"),
+                               @Property(name="p4",value="mp4")
+                       }
+               )
+               public String a01(@Body String in) {
+                       return in;
+               }
+
+               @RestMethod(name=PUT, 
path="/propertiesOverriddenProgrammatically")
+               public String a02(RestRequest req, RequestProperties 
properties) throws Exception {
+                       properties.put("p3", "pp3");
+                       properties.put("p4", "pp4");
+                       return req.getBody().asType(String.class);
+               }
+       }
+       static MockRest a = MockRest.create(A.class);
+
+       public static class A01 extends ReaderParser {
+               public A01(PropertyStore ps) {
+                       super(ps, "text/a1", "text/a2", "text/a3");
+               }
+               @Override /* Parser */
+               public ReaderParserSession createSession(ParserSessionArgs 
args) {
+                       return new ReaderParserSession(args) {
+                               @Override /* ParserSession */
+                               @SuppressWarnings("unchecked")
+                               protected <T> T doParse(ParserPipe pipe, 
ClassMeta<T> type) throws Exception {
+                                       String matchingContentType = 
getProperty("mediaType", String.class);
+                                       return (T)("p1="+getProperty("p1", 
String.class)+",p2="+getProperty("p2", String.class)+",p3="+getProperty("p3", 
String.class)+",p4="+getProperty("p4", String.class)+",p5="+getProperty("p5", 
String.class)+",contentType="+matchingContentType);
+                               }
+                       };
+               }
+       }
+
+       @Test
+       public void a01_preCall_propertiesOverriddenByAnnotation() throws 
Exception {
+               a.request("PUT", 
"/propertiesOverriddenByAnnotation").contentType("text/a1").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/a1");
+               a.request("PUT", 
"/propertiesOverriddenByAnnotation").contentType("text/a1").header("Override-Content-Type",
 
"text/a2").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/a2");
+       }
+
+       @Test
+       public void a02_preCall_propertiesOverriddenProgrammatically() throws 
Exception {
+               a.request("PUT", 
"/propertiesOverriddenProgrammatically").contentType("text/a1").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5,contentType=text/a1");
+               a.request("PUT", 
"/propertiesOverriddenProgrammatically").contentType("text/a1").header("Override-Content-Type",
 
"text/a2").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5,contentType=text/a2");
+       }
+
+       
//=================================================================================================================
+       // @RestHook(POST_CALL)
+       
//=================================================================================================================
+
+       @RestResource(
+               serializers=B01.class,
+               properties={
+                       @Property(name="p1",value="sp1"), // Unchanged 
servlet-level property.
+                       @Property(name="p2",value="sp2"), // Servlet-level 
property overridden by onPostCall.
+                       @Property(name="p3",value="sp3"), // Servlet-level 
property overridded by method.
+                       @Property(name="p4",value="sp4")  // Servlet-level 
property overridden by method then onPostCall.
+               }
+       )
+       public static class B {
+
+               @RestHook(POST_CALL)
+               public void onPostCall(RestRequest req, RestResponse res) {
+                       RequestProperties properties = req.getProperties();
+                       properties.put("p2", "xp2");
+                       properties.put("p4", "xp4");
+                       properties.put("p5", "xp5"); // New property
+                       String overrideAccept = 
req.getHeader("Override-Accept");
+                       if (overrideAccept != null)
+                               req.getHeaders().put("Accept", overrideAccept);
+                       String overrideContentType = 
req.getHeader("Override-Content-Type");
+                       if (overrideContentType != null)
+                               properties.put("Override-Content-Type", 
overrideContentType);
+               }
+
+               @RestMethod(name=PUT, path="/propertiesOverridenByAnnotation",
+                       properties={
+                               @Property(name="p3",value="mp3"),
+                               @Property(name="p4",value="mp4")
+                       },
+                       defaultRequestHeaders="Accept: text/s2"
+               )
+               public String b01() {
+                       return null;
+               }
+
+               @RestMethod(name=PUT, 
path="/propertiesOverriddenProgramatically")
+               public String b02(RestRequest req, RequestProperties 
properties) throws Exception {
+                       properties.put("p3", "pp3");
+                       properties.put("p4", "pp4");
+                       String accept = req.getHeader("Accept");
+                       if (accept == null || accept.isEmpty())
+                               req.getHeaders().put("Accept", "text/s2");
+                       return null;
+               }
+       }
+       static MockRest b = MockRest.create(B.class);
+
+       public static class B01 extends WriterSerializer {
+               public B01(PropertyStore ps) {
+                       super(ps, "test/s1", "text/s1,text/s2,text/s3");
+               }
+               @Override /* Serializer */
+               public WriterSerializerSession 
createSession(SerializerSessionArgs args) {
+                       return new WriterSerializerSession(args) {
+                               @Override /* SerializerSession */
+                               protected void doSerialize(SerializerPipe out, 
Object o) throws Exception {
+                                       
out.getWriter().write("p1="+getProperty("p1", 
String.class)+",p2="+getProperty("p2", String.class)+",p3="+getProperty("p3", 
String.class)+",p4="+getProperty("p4", String.class)+",p5="+getProperty("p5", 
String.class)+",contentType="+getProperty("mediaType", String.class));
+                               }
+                               @Override /* SerializerSession */
+                               public Map<String,String> getResponseHeaders() {
+                                       ObjectMap p = getProperties();
+                                       if 
(p.containsKey("Override-Content-Type"))
+                                               return new 
AMap<String,String>().append("Content-Type", 
p.getString("Override-Content-Type"));
+                                       return Collections.emptyMap();
+                               }
+                       };
+               }
+       }
+
+       @Test
+       public void b01a_postCall_propertiesOverridenByAnnotation() throws 
Exception {
+               b.request("PUT", 
"/propertiesOverridenByAnnotation").accept("text/s1").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s1");
+               b.request("PUT", 
"/propertiesOverridenByAnnotation").accept("text/s1").header("Override-Accept", 
"text/s2").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2");
+               b.request("PUT", 
"/propertiesOverridenByAnnotation").accept("text/s1").header("Override-Content-Type",
 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s1");
+       }
+       @Test
+       public void 
b01b_postCall_propertiesOverridenByAnnotation_defaultAccept() throws Exception {
+               b.request("PUT", 
"/propertiesOverridenByAnnotation").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2");
+               b.request("PUT", 
"/propertiesOverridenByAnnotation").header("Override-Accept", 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s3");
+               b.request("PUT", 
"/propertiesOverridenByAnnotation").header("Override-Content-Type", 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2");
+       }
+       @Test
+       public void b02a_postCall_propertiesOverriddenProgramatically() throws 
Exception {
+               b.request("PUT", 
"/propertiesOverriddenProgramatically").accept("text/s1").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s1");
+               b.request("PUT", 
"/propertiesOverriddenProgramatically").accept("text/s1").header("Override-Accept",
 
"text/s2").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2");
+               b.request("PUT", 
"/propertiesOverriddenProgramatically").accept("text/s1").header("Override-Content-Type",
 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s1");
+       }
+       @Test
+       public void 
b02b_postCall_propertiesOverriddenProgramatically_defaultAccept() throws 
Exception {
+               b.request("PUT", 
"/propertiesOverriddenProgramatically").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2");
+               b.request("PUT", 
"/propertiesOverriddenProgramatically").header("Override-Accept", 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s3");
+               b.request("PUT", 
"/propertiesOverriddenProgramatically").header("Override-Content-Type", 
"text/s3").execute().assertBody("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2");
+       }
+       
+       
//====================================================================================================
+       // @RestHook(INIT)
+       
//====================================================================================================
+       
+       @RestResource(children={C_Super.class,C_Sub.class})
+       public static class C {}
+       static MockRest c = MockRest.create(C.class);
+
+       @RestResource(path="/super")
+       public static class C_Super {
+               protected ObjectList events = new ObjectList();
+               @RestHook(INIT)
+               public void init1c(RestContextBuilder builder) {
+                       events.add("super-1c");
+               }
+               @RestHook(INIT)
+               public void init1a(ServletConfig config) {
+                       events.add("super-1a");
+               }
+               @RestHook(INIT)
+               public void init1b() {
+                       events.add("super-1b");
+               }
+               @RestHook(INIT)
+               public void init2a() {
+                       events.add("super-2a");
+               }
+               @RestMethod(name=GET)
+               public ObjectList getEvents() {
+                       return events;
+               }
+       }
+
+       @RestResource(path="/sub", children={C_Child.class})
+       public static class C_Sub extends C_Super {
+               @Override
+               @RestHook(INIT)
+               public void init1c(RestContextBuilder builder) {
+                       events.add("sub-1c");
+               }
+               @Override
+               @RestHook(INIT)
+               public void init1a(ServletConfig config) {
+                       events.add("sub-1a");
+               }
+               @Override
+               @RestHook(INIT)
+               public void init1b() {
+                       events.add("sub-1b");
+               }
+               @RestHook(INIT)
+               public void init2b() {
+                       events.add("sub-2b");
+               }
+       }
+
+       @RestResource(path="/child")
+       public static class C_Child extends C_Super {
+               @Override
+               @RestHook(INIT)
+               public void init1c(RestContextBuilder builder) {
+                       events.add("child-1c");
+               }
+               @RestHook(INIT)
+               public void init2b() {
+                       events.add("child-2b");
+               }
+       }
+
+       @Test
+       public void c01_init() throws Exception {
+               c.request("GET", 
"/super").execute().assertBody("['super-1a','super-1b','super-1c','super-2a']");
+               c.request("GET", 
"/sub").execute().assertBody("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
+               c.request("GET", 
"/sub/child").execute().assertBody("['super-1a','super-1b','child-1c','super-2a','child-2b']");
+       }
+
+       
//====================================================================================================
+       // @RestHook(POST_INIT)
+       
//====================================================================================================
+       @RestResource(children={D_Super.class,D_Sub.class})
+       public static class D {}
+       static MockRest d = MockRest.create(D.class);
+
+       @RestResource(path="/super")
+       public static class D_Super {
+               protected ObjectList events = new ObjectList();
+               @RestHook(POST_INIT)
+               public void postInit1c(RestContext context) {
+                       events.add("super-1c");
+               }
+               @RestHook(POST_INIT)
+               public void postInit1a(RestContext context) {
+                       events.add("super-1a");
+               }
+               @RestHook(POST_INIT)
+               public void postInit1b() {
+                       events.add("super-1b");
+               }
+               @RestHook(POST_INIT)
+               public void postInit2a() {
+                       events.add("super-2a");
+               }
+               @RestMethod(name=GET)
+               public ObjectList getEvents() {
+                       return events;
+               }
+       }
+
+       @RestResource(path="/sub",children={D_Child.class})
+       public static class D_Sub extends D_Super {
+               protected static String LAST_CALLED;
+               @Override
+               @RestHook(POST_INIT)
+               public void postInit1c(RestContext context) {
+                       events.add("sub-1c");
+               }
+               @Override
+               @RestHook(POST_INIT)
+               public void postInit1a(RestContext context) {
+                       events.add("sub-1a");
+               }
+               @Override
+               @RestHook(POST_INIT)
+               public void postInit1b() {
+                       events.add("sub-1b");
+               }
+               @RestHook(POST_INIT)
+               public void postInit2b() {
+                       events.add("sub-2b");
+               }
+               @RestHook(POST_INIT)
+               public void postInitOrderTestSub() {
+                       LAST_CALLED = "PARENT";
+               }
+               @RestMethod(name=GET, path="/lastCalled")
+               public String getLastCalled() {
+                       return LAST_CALLED;
+               }
+       }
+
+       @RestResource(path="/child")
+       public static class D_Child extends D_Super {
+               @Override
+               @RestHook(POST_INIT)
+               public void postInit1c(RestContext context) {
+                       events.add("child-1c");
+               }
+               @RestHook(POST_INIT)
+               public void postInit2b() {
+                       events.add("child-2b");
+               }
+               @RestHook(POST_INIT)
+               public void postInitOrderTestSub() {
+                       D_Sub.LAST_CALLED = "CHILD";
+               }
+       }
+
+       @Test
+       public void d01_postInit() throws Exception {
+               d.request("GET", 
"/super").execute().assertBody("['super-1a','super-1b','super-1c','super-2a']");
+               d.request("GET", 
"/sub").execute().assertBody("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
+               d.request("GET", 
"/sub/child").execute().assertBody("['super-1a','super-1b','child-1c','super-2a','child-2b']");
+       }
+       @Test
+       public void d02_postInit_order() throws Exception {
+               d.request("GET", 
"/sub/lastCalled").execute().assertBody("CHILD");
+       }
+
+       
//====================================================================================================
+       // @RestHook(POST_INIT_CHILD_FIRST)
+       
//====================================================================================================
+
+       @RestResource(
+               children={
+                       E_Super.class,
+                       E_Sub.class
+               }
+       )
+       public static class E {}
+       static MockRest e = MockRest.create(E.class);
+       
+       @RestResource(path="/super")
+       public static class E_Super {
+               protected ObjectList events = new ObjectList();
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst1c(RestContext context) {
+                       events.add("super-1c");
+               }
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst1a(RestContext context) {
+                       events.add("super-1a");
+               }
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst1b() {
+                       events.add("super-1b");
+               }
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst2a() {
+                       events.add("super-2a");
+               }
+               @RestMethod(name=GET)
+               public ObjectList getPostInitChildFirstEvents() {
+                       return events;
+               }
+       }
+
+       @RestResource(path="/sub", children={E_Child.class})
+       public static class E_Sub extends E_Super {
+               protected static String LAST_CALLED;
+               @Override
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst1c(RestContext context) {
+                       events.add("sub-1c");
+               }
+               @Override
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst1a(RestContext context) {
+                       events.add("sub-1a");
+               }
+               @Override
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst1b() {
+                       events.add("sub-1b");
+               }
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst2b() {
+                       events.add("sub-2b");
+               }
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirstOrderTestSub() {
+                       LAST_CALLED = "PARENT";
+               }
+               @RestMethod(name=GET, path="/lastCalled")
+               public String getLastCalled() {
+                       return LAST_CALLED;
+               }
+       }
+
+       @RestResource(path="/child")
+       public static class E_Child extends E_Super {
+               @Override
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst1c(RestContext context) {
+                       events.add("child-1c");
+               }
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirst2b() {
+                       events.add("child-2b");
+               }
+               @RestHook(POST_INIT_CHILD_FIRST)
+               public void postInitChildFirstOrderTestSub() {
+                       E_Sub.LAST_CALLED = "CHILD";
+               }
+       }
+
+       @Test
+       public void e01_postInitChildFirst() throws Exception {
+               e.request("GET", 
"/super").execute().assertBody("['super-1a','super-1b','super-1c','super-2a']");
+               e.request("GET", 
"/sub").execute().assertBody("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
+               e.request("GET", 
"/sub/child").execute().assertBody("['super-1a','super-1b','child-1c','super-2a','child-2b']");
+       }
+       @Test
+       public void e02_postInitChildFirst_order() throws Exception {
+               e.request("GET", 
"/sub/lastCalled").execute().assertBody("PARENT");
+       }
+
+       
//====================================================================================================
+       // @RestHook(START_CALL)
+       
//====================================================================================================
+       
+       @RestResource
+       public static class F extends F_Parent {
+               private boolean start3Called;
+               @RestHook(START_CALL)
+               public void start3() {
+                       start3Called = true;
+               }
+               @RestHook(START_CALL)
+               public void start4(HttpServletRequest req, HttpServletResponse 
res) {
+                       res.setHeader("start3-called", ""+start3Called);
+                       start3Called = false;
+                       if (res.getHeader("start4-called") != null)
+                               throw new RuntimeException("start4 called 
multiple times.");
+                       res.setHeader("start4-called", "true");
+               }
+               @RestMethod(path="/")
+               public ObjectMap getHeaders(RestRequest req, RestResponse res) {
+                       return new ObjectMap()
+                               .append("1", res.getHeader("start1-called"))
+                               .append("2", res.getHeader("start2-called"))
+                               .append("3", res.getHeader("start3-called"))
+                               .append("4", res.getHeader("start4-called"));
+               }
+       }
+       static MockRest f = MockRest.create(F.class);
+       
+       public static class F_Parent {
+               private boolean start1Called;
+               @RestHook(START_CALL)
+               public void start1() {
+                       start1Called = true;
+               }
+               @RestHook(START_CALL)
+               public void start2(HttpServletRequest req, HttpServletResponse 
res) {
+                       res.setHeader("start1-called", ""+start1Called);
+                       start1Called = false;
+                       if (res.getHeader("start2-called") != null)
+                               throw new RuntimeException("start2 called 
multiple times.");
+                       res.setHeader("start2-called", "true");
+               }
+       }
+
+       @Test
+       public void f01_startCall() throws Exception {
+               f.request("GET", 
"/").execute().assertBody("{'1':'true','2':'true','3':'true','4':'true'}");
+       }
+
+       
//====================================================================================================
+       // @RestHook(PRE_CALL)
+       
//====================================================================================================
+       
+       @RestResource
+       public static class G extends G_Parent {
+               private boolean pre3Called;
+               @RestHook(PRE_CALL)
+               public void pre3() {
+                       pre3Called = true;
+               }
+               @RestHook(PRE_CALL)
+               public void pre4(HttpServletRequest req, HttpServletResponse 
res) {
+                       res.setHeader("pre3-called", ""+pre3Called);
+                       pre3Called = false;
+                       if (res.getHeader("pre4-called") != null)
+                               throw new RuntimeException("pre4 called 
multiple times.");
+                       res.setHeader("pre4-called", "true");
+               }
+               @RestMethod(path="/")
+               public ObjectMap getHeaders(RestRequest req, RestResponse res) {
+                       return new ObjectMap()
+                               .append("1", res.getHeader("pre1-called"))
+                               .append("2", res.getHeader("pre2-called"))
+                               .append("3", res.getHeader("pre3-called"))
+                               .append("4", res.getHeader("pre4-called"));
+               }
+       }
+       static MockRest g = MockRest.create(G.class);
+       
+       public static class G_Parent {
+               private boolean pre1Called;
+               @RestHook(PRE_CALL)
+               public void pre1() {
+                       pre1Called = true;
+               }
+               @RestHook(PRE_CALL)
+               public void pre2(Accept accept, RestRequest req, RestResponse 
res) {
+                       res.setHeader("pre1-called", ""+pre1Called);
+                       pre1Called = false;
+                       if (res.getHeader("pre2-called") != null)
+                               throw new RuntimeException("pre2 called 
multiple times.");
+                       res.setHeader("pre2-called", "true");
+               }
+       }
+       
+       @Test
+       public void g01_preCall() throws Exception {
+               g.request("GET", 
"/").execute().assertBody("{'1':'true','2':'true','3':'true','4':'true'}");
+       }
+
+       
//====================================================================================================
+       // @RestHook(POST_CALL)
+       
//====================================================================================================
+       
+       @RestResource
+       public static class H extends H_Parent {
+               private boolean post3Called;
+               @RestHook(POST_CALL)
+               public void post3() {
+                       post3Called = true;
+               }
+               @RestHook(POST_CALL)
+               public void post4(HttpServletRequest req, HttpServletResponse 
res) {
+                       res.setHeader("post3-called", ""+post3Called);
+                       post3Called = false;
+                       if (res.getHeader("post4-called") != null)
+                               throw new RuntimeException("post4 called 
multiple times.");
+                       res.setHeader("post4-called", "true");
+               }
+               @RestMethod(path="/")
+               public String doGet() {
+                       return "OK";
+               }
+       }
+       static MockRest h = MockRest.create(H.class);
+       
+       public static class H_Parent {
+               private boolean post1Called;
+               @RestHook(POST_CALL)
+               public void post1() {
+                       post1Called = true;
+               }
+               @RestHook(POST_CALL)
+               public void post2(Accept accept, RestRequest req, RestResponse 
res) {
+                       res.setHeader("post1-called", ""+post1Called);
+                       post1Called = false;
+                       if (res.getHeader("post2-called") != null)
+                               throw new RuntimeException("post2 called 
multiple times.");
+                       res.setHeader("post2-called", "true");
+               }
+       }
+
+       @Test
+       public void h01_postCall() throws Exception {
+               h.request("GET", "/").execute()
+                       .assertHeader("post1-called", "true")
+                       .assertHeader("post2-called", "true")
+                       .assertHeader("post3-called", "true")
+                       .assertHeader("post4-called", "true");
+       }
+}
diff --git 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathResource.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourcePathTest.java
similarity index 59%
rename from 
juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathResource.java
rename to 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourcePathTest.java
index 8a7bb50..0cfb838 100644
--- 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathResource.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourcePathTest.java
@@ -10,62 +10,57 @@
 // * "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.test;
+package org.apache.juneau.rest.annotation;
 
 import static org.apache.juneau.http.HttpMethodName.*;
 
 import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.mock.*;
+import org.junit.*;
+import org.junit.runners.*;
 
 /**
- * JUnit automated testcase resource.
- * Tests the RestServlet.getPath() method.
+ * Tests that validate the behavior of @RestResource(path).
  */
-@RestResource(
-       path="/testPath",
-       children={
-               PathResource.TestPath2.class
-       }
-)
-public class PathResource extends BasicRestServlet {
-       private static final long serialVersionUID = 1L;
+@SuppressWarnings({"javadoc"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class RestResourcePathTest {
 
        
//====================================================================================================
-       // Basic tests
+       // Nested children.
        
//====================================================================================================
-       @RestMethod(name=GET, path="/")
-       public String doGet() {
-               return getContext().getPath();
-       }
 
-       @RestResource(
-               path="/testPath2",
-               children={
-                       PathResource.TestPath3.class
+       @RestResource(path="/p0", children={A01.class})
+       public static class A  {
+               @RestMethod(name=GET, path="/")
+               public String doGet(RestContext c) {
+                       return "A-" + c.getPath();
                }
-       )
-       public static class TestPath2 extends BasicRestServlet {
-               private static final long serialVersionUID = 1L;
-               // Basic tests
+       }
+       @RestResource(path="/p1", children={A02.class})
+       public static class A01 {
                @RestMethod(name=GET, path="/")
-               public String doGet() {
-                       return getContext().getPath();
+               public String doGet(RestContext c) {
+                       return "A01-" + c.getPath();
                }
        }
-
-       @RestResource(
-               path="/testPath3"
-       )
-       public static class TestPath3a extends BasicRestServlet {
-               private static final long serialVersionUID = 1L;
-               // Basic tests
+       public static class A02a  {
                @RestMethod(name=GET, path="/")
-               public String doGet() {
-                       return getContext().getPath();
+               public String doGet(RestContext c) {
+                       return "A02a-" + c.getPath();
                }
        }
+       @RestResource(path="/p2")
+       public static class A02 extends A02a {}
 
-       public static class TestPath3 extends TestPath3a {
-               private static final long serialVersionUID = 1L;
+       static MockRest a = MockRest.create(A.class);
+       
+       @Test
+       public void a01_nestedChildren() throws Exception {
+               // Since we're not running from a servlet container, we access 
A directly with no path.
+               // However, the path is still reflected in 
RestContext.getPath().
+               a.request("GET", "/").execute().assertBody("A-p0");
+               a.request("GET", "/p1").execute().assertBody("A01-p0/p1");
+               a.request("GET", 
"/p1/p2").execute().assertBody("A02a-p0/p1/p2");
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourcePropertiesTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourcePropertiesTest.java
new file mode 100644
index 0000000..d3c77dd
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourcePropertiesTest.java
@@ -0,0 +1,91 @@
+// 
***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.String.*;
+import static org.apache.juneau.http.HttpMethodName.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.mock.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+/**
+ * Tests that validate the behavior of @RestResource(properties).
+ */
+@SuppressWarnings({"javadoc"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class RestResourcePropertiesTest {
+       
+       
//=================================================================================================================
+       // Basic tests
+       
//=================================================================================================================
+       
+       @RestResource(
+               path="/p1",
+               properties={
+                       @Property(name="A1",value="a1"),
+                       @Property(name="A2",value="a2"),
+                       @Property(name="foo",value="bar"),
+                       @Property(name="bar",value="baz"),
+                       @Property(name="R1a",value="$R{requestURI}"),
+                       @Property(name="R1b",value="$R{requestParentURI}"),
+                       @Property(name="R2",value="$R{foo}"),
+                       @Property(name="R3",value="$R{$R{foo}}"),
+                       @Property(name="R4",value="$R{A1}"),
+                       @Property(name="R5",value="$R{A2}"),
+                       @Property(name="R6",value="$R{C}"),
+               }
+       )
+       public static class A {
+
+               @RestMethod(name=GET, path="/p2",
+                       properties={
+                               @Property(name="B1",value="b1"),
+                               @Property(name="B2",value="b2")
+                       },
+                       serializers=A01.class
+               )
+               public void testPropertiesDefinedOnMethod(RestResponse res) {
+                       res.prop("A2", "c");
+                       res.prop("B2", "c");
+                       res.prop("C", "c");
+                       res.setOutput(null);
+               }
+
+               public static class A01 extends WriterSerializer {
+                       public A01(PropertyStore ps) {
+                               super(ps, "text/plain", "*/*");
+                       }
+                       @Override /* Serializer */
+                       public WriterSerializerSession 
createSession(SerializerSessionArgs args) {
+                               return new WriterSerializerSession(args) {
+                                       @Override /* SerializerSession */
+                                       protected void 
doSerialize(SerializerPipe out, Object o) throws Exception {
+                                               
out.getWriter().write(format("A1=%s,A2=%s,B1=%s,B2=%s,C=%s,R1a=%s,R1b=%s,R2=%s,R3=%s,R4=%s,R5=%s,R6=%s",
+                                                       getProperty("A1"), 
getProperty("A2"), getProperty("B1"), getProperty("B2"), getProperty("C"),
+                                                       getProperty("R1a"), 
getProperty("R1b"), getProperty("R2"), getProperty("R3"), getProperty("R4"), 
getProperty("R5"), getProperty("R6")));
+                                       }
+                               };
+                       }
+               }
+       }
+       static MockRest a = MockRest.create(A.class);
+       
+       @Test
+       public void a01() throws Exception {
+               a.request("GET", 
"/p2").accept("text/plain").execute().assertBody("A1=a1,A2=c,B1=b1,B2=c,C=c,R1a=/p2,R1b=/,R2=bar,R3=,R4=a1,R5=c,R6=c");
+       }
+}

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to