Repository: incubator-juneau
Updated Branches:
  refs/heads/master da2817b93 -> fb8d004cd


Add support for "INHERIT" literal in HtmlDoc.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/fb8d004c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/fb8d004c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/fb8d004c

Branch: refs/heads/master
Commit: fb8d004cd96a8f8aefc820f535a1e1396c2b81f3
Parents: da2817b
Author: JamesBognar <[email protected]>
Authored: Tue Jul 11 19:54:20 2017 -0400
Committer: JamesBognar <[email protected]>
Committed: Tue Jul 11 19:54:20 2017 -0400

----------------------------------------------------------------------
 juneau-core/src/main/javadoc/overview.html      |   2 +
 .../juneau/rest/test/HtmlDocLinksResource.java  | 255 ++++++++++++++
 .../juneau/rest/test/HtmlDocResource.java       | 186 ++++++++++
 .../java/org/apache/juneau/rest/test/Root.java  |   2 +
 .../juneau/rest/test/HtmlDocLinksTest.java      | 337 +++++++++++++++++++
 .../apache/juneau/rest/test/HtmlDocTest.java    | 291 ++++++++++++++++
 .../org/apache/juneau/rest/test/_TestSuite.java |   2 +
 .../java/org/apache/juneau/rest/CallMethod.java |  16 +-
 .../java/org/apache/juneau/rest/RestConfig.java |  23 +-
 .../org/apache/juneau/rest/RestContext.java     |   3 +
 .../java/org/apache/juneau/rest/RestUtils.java  |  41 +++
 .../apache/juneau/rest/annotation/HtmlDoc.java  |  18 +-
 .../juneau/rest/annotation/RestMethod.java      |  18 +-
 13 files changed, 1168 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html 
b/juneau-core/src/main/javadoc/overview.html
index c868d22..d1ea77a 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -6971,6 +6971,8 @@
                                                        <li>{@link 
org.apache.juneau.rest.annotation.HtmlDoc#script() script()}
                                                        <li>{@link 
org.apache.juneau.rest.annotation.HtmlDoc#style() style()}
                                                </ul>
+                                               Additionally, the 
<js>"INHERIT"</js> string literal can be used to combine the value with
+                                               the value defined on the 
servlet or parent class.
                                </ul>
                        <li>
                                Improvements made to the {@link 
org.apache.juneau.rest.widget.Widget} API.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlDocLinksResource.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlDocLinksResource.java
 
b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlDocLinksResource.java
new file mode 100644
index 0000000..26e1b02
--- /dev/null
+++ 
b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlDocLinksResource.java
@@ -0,0 +1,255 @@
+// 
***************************************************************************************************************************
+// * 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 org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * Validates inheritance on the @HtmlDoc.links() annotation.
+ */
+@RestResource(
+       path="/testHtmlDocLinks",
+       htmldoc=@HtmlDoc(
+               links={"links1a","links1b"}
+       ),
+       children={
+               HtmlDocLinksResource.HtmlDocLinksResource2.class
+       }
+)
+public class HtmlDocLinksResource extends RestServletDefault {
+       private static final long serialVersionUID = 1L;
+
+       @RestMethod(path="/test1")
+       public Object test1() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test2",
+               htmldoc=@HtmlDoc(
+                       links={"links2a","links2b"}
+               )
+       )
+       public Object test2() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test3",
+               htmldoc=@HtmlDoc(
+                       links={"INHERIT","links3a","links3b"}
+               )
+       )
+       public Object test3() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test4",
+               htmldoc=@HtmlDoc(
+                       links={"links4a","INHERIT","links4b"}
+               )
+       )
+       public Object test4() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test5",
+               htmldoc=@HtmlDoc(
+                       links={"links5a","links5b","INHERIT"}
+               )
+       )
+       public Object test5() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test6a",
+               htmldoc=@HtmlDoc(
+                       links={"INHERIT","[0]:links6a","[3]:links6b"}
+               )
+       )
+       public Object test6a() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test6b",
+               htmldoc=@HtmlDoc(
+                       links={"[1]:links6a","[2]:links6b","INHERIT"}
+               )
+       )
+       public Object test6b() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test6c",
+               htmldoc=@HtmlDoc(
+                       links={"[1]:links6a","[0]:links6b"}
+               )
+       )
+       public Object test6c() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test6d",
+               htmldoc=@HtmlDoc(
+                       links={"INHERIT","foo[0]:links6a","bar[3]:links6b"}
+               )
+       )
+       public Object test6d() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test6e",
+               htmldoc=@HtmlDoc(
+                       links={"foo[1]:links6a","bar[2]:links6b","INHERIT"}
+               )
+       )
+       public Object test6e() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test6f",
+               htmldoc=@HtmlDoc(
+                       links={"foo[1]:links6a","bar[0]:links6b"}
+               )
+       )
+       public Object test6f() {
+               return "OK";
+       }
+
+       @RestResource(
+               path="/testHtmlDocLinks2",
+               htmldoc=@HtmlDoc(
+                       links={"INHERIT","links11a","links11b"}
+               )
+       )
+       public static class HtmlDocLinksResource2 extends HtmlDocLinksResource {
+               /**
+                *
+                */
+               private static final long serialVersionUID = 1L;
+
+               @RestMethod(path="/test11")
+               public Object test11() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test12",
+                       htmldoc=@HtmlDoc(
+                               links={"links12a","links12b"}
+                       )
+               )
+               public Object test12() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test13",
+                       htmldoc=@HtmlDoc(
+                               links={"INHERIT","links13a","links13b"}
+                       )
+               )
+               public Object test13() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test14",
+                       htmldoc=@HtmlDoc(
+                               links={"links14a","INHERIT","links14b"}
+                       )
+               )
+               public Object test14() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test15",
+                       htmldoc=@HtmlDoc(
+                               links={"links15a","links15b","INHERIT"}
+                       )
+               )
+               public Object test15() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test16a",
+                       htmldoc=@HtmlDoc(
+                               links={"INHERIT","[0]:links16a","[3]:links16b"}
+                       )
+               )
+               public Object test16a() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test16b",
+                       htmldoc=@HtmlDoc(
+                               links={"[1]:links16a","[2]:links16b","INHERIT"}
+                       )
+               )
+               public Object test16b() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test16c",
+                       htmldoc=@HtmlDoc(
+                               links={"[1]:links16a","[0]:links16b"}
+                       )
+               )
+               public Object test16c() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test16d",
+                       htmldoc=@HtmlDoc(
+                               
links={"INHERIT","foo[0]:links16a","bar[3]:links16b"}
+                       )
+               )
+               public Object test16d() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test16e",
+                       htmldoc=@HtmlDoc(
+                               
links={"foo[1]:links16a","bar[2]:links16b","INHERIT"}
+                       )
+               )
+               public Object test16e() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test16f",
+                       htmldoc=@HtmlDoc(
+                               links={"foo[1]:links16a","bar[0]:links16b"}
+                       )
+               )
+               public Object test16f() {
+                       return "OK";
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlDocResource.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlDocResource.java
 
b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlDocResource.java
new file mode 100644
index 0000000..45c398b
--- /dev/null
+++ 
b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/HtmlDocResource.java
@@ -0,0 +1,186 @@
+// 
***************************************************************************************************************************
+// * 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 org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * Validates inheritance on the @HtmlDoc annotation.
+ */
+@RestResource(
+       path="/testHtmlDoc",
+       htmldoc=@HtmlDoc(
+               aside={"aside1a","aside1b","INHERIT"},
+               footer={"footer1a","footer1b"},
+               header={"header1a","header1b"},
+               nav={"nav1a","nav1b"},
+               script={"script1a","script1b"},
+               style={"style1a","style1b"},
+               stylesheet="stylesheet1"
+       ),
+       children={
+               HtmlDocResource.HtmlDocResource2.class
+       }
+)
+public class HtmlDocResource extends RestServletDefault {
+       private static final long serialVersionUID = 1L;
+
+       @RestMethod(path="/test1")
+       public Object test1() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test2",
+               htmldoc=@HtmlDoc(
+                       aside={"aside2a","aside2b"},
+                       footer={"footer2a","footer2b"},
+                       header={"header2a","header2b"},
+                       nav={"nav2a","nav2b"},
+                       script={"script2a","script2b"},
+                       style={"style2a","style2b"},
+                       stylesheet="stylesheet2"
+               )
+       )
+       public Object test2() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test3",
+               htmldoc=@HtmlDoc(
+                       aside={"INHERIT","aside3a","aside3b"},
+                       footer={"INHERIT","footer3a","footer3b"},
+                       header={"INHERIT","header3a","header3b"},
+                       nav={"INHERIT","nav3a","nav3b"},
+                       script={"INHERIT","script3a","script3b"},
+                       style={"INHERIT","style3a","style3b"}
+               )
+       )
+       public Object test3() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test4",
+               htmldoc=@HtmlDoc(
+                       aside={"aside4a","INHERIT","aside4b"},
+                       footer={"footer4a","INHERIT","footer4b"},
+                       header={"header4a","INHERIT","header4b"},
+                       nav={"nav4a","INHERIT","nav4b"},
+                       script={"script4a","INHERIT","script4b"},
+                       style={"style4a","INHERIT","style4b"}
+               )
+       )
+       public Object test4() {
+               return "OK";
+       }
+
+       @RestMethod(
+               path="/test5",
+               htmldoc=@HtmlDoc(
+                       aside={"aside5a","aside5b","INHERIT"},
+                       footer={"footer5a","footer5b","INHERIT"},
+                       header={"header5a","header5b","INHERIT"},
+                       nav={"nav5a","nav5b","INHERIT"},
+                       script={"script5a","script5b","INHERIT"},
+                       style={"style5a","style5b","INHERIT"}
+               )
+       )
+       public Object test5() {
+               return "OK";
+       }
+
+       @RestResource(
+               path="/testHtmlDoc2",
+               htmldoc=@HtmlDoc(
+                       aside={"INHERIT","aside11a","aside11b"},
+                       footer={"footer11a","INHERIT","footer11b"},
+                       header={"header11a","header11b","INHERIT"},
+                       nav={"INHERIT","nav11a","nav11b"},
+                       script={"script11a","script11b"},
+                       style={"style11a","style11b"},
+                       stylesheet="stylesheet11"
+               )
+       )
+       public static class HtmlDocResource2 extends HtmlDocResource {
+               private static final long serialVersionUID = 1L;
+
+               @RestMethod(path="/test11")
+               public Object test11() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test12",
+                       htmldoc=@HtmlDoc(
+                               aside={"aside12a","aside12b"},
+                               footer={"footer12a","footer12b"},
+                               header={"header12a","header12b"},
+                               nav={"nav12a","nav12b"},
+                               script={"script12a","script12b"},
+                               style={"style12a","style12b"},
+                               stylesheet="stylesheet12"
+                       )
+               )
+               public Object test12() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test13",
+                       htmldoc=@HtmlDoc(
+                               aside={"INHERIT","aside13a","aside13b"},
+                               footer={"INHERIT","footer13a","footer13b"},
+                               header={"INHERIT","header13a","header13b"},
+                               nav={"INHERIT","nav13a","nav13b"},
+                               script={"INHERIT","script13a","script13b"},
+                               style={"INHERIT","style13a","style13b"}
+                       )
+               )
+               public Object test13() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test14",
+                       htmldoc=@HtmlDoc(
+                               aside={"aside14a","INHERIT","aside14b"},
+                               footer={"footer14a","INHERIT","footer14b"},
+                               header={"header14a","INHERIT","header14b"},
+                               nav={"nav14a","INHERIT","nav14b"},
+                               script={"script14a","INHERIT","script14b"},
+                               style={"style14a","INHERIT","style14b"}
+                       )
+               )
+               public Object test14() {
+                       return "OK";
+               }
+
+               @RestMethod(
+                       path="/test15",
+                       htmldoc=@HtmlDoc(
+                               aside={"aside15a","aside15b","INHERIT"},
+                               footer={"footer15a","footer15b","INHERIT"},
+                               header={"header15a","header15b","INHERIT"},
+                               nav={"nav15a","nav15b","INHERIT"},
+                               script={"script15a","script15b","INHERIT"},
+                               style={"style15a","style15b","INHERIT"}
+                       )
+               )
+               public Object test15() {
+                       return "OK";
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java 
b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
index 3075e05..f47564a 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
@@ -37,6 +37,8 @@ import org.apache.juneau.rest.labels.*;
                GzipResource.TestGzipOff.class,
                GzipResource.TestGzipOn.class,
                HeadersResource.class,
+               HtmlDocResource.class,
+               HtmlDocLinksResource.class,
                InheritanceResource.TestEncoders.class,
                InheritanceResource.TestTransforms.class,
                InheritanceResource.TestParsers.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlDocLinksTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlDocLinksTest.java
 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlDocLinksTest.java
new file mode 100644
index 0000000..5e88c08
--- /dev/null
+++ 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlDocLinksTest.java
@@ -0,0 +1,337 @@
+// 
***************************************************************************************************************************
+// * 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.*;
+
+/**
+ * Validates inheritance on the @HtmlDoc.links() annotation.
+ */
+public class HtmlDocLinksTest extends RestTestcase {
+       private RestClient client = TestMicroservice.DEFAULT_CLIENT;
+
+       private String get(String uri) throws Exception {
+               return 
client.doGet(uri).accept("text/html").getResponseAsString().replace('\n', ' 
').replace('"', '\'').replaceAll(".*<nav>", "<nav>").replaceAll("</nav>.*", 
"</nav>");
+       }
+
+       /**
+        * @RestResource(
+        *      path="/testHtmlDocLinks",
+        *      htmldoc=@HtmlDoc(
+        *              links={"links1a","links1b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test1() throws Exception {
+               String r = get("/testHtmlDocLinks/test1");
+               
assertEquals("<nav><ol><li>links1a</li><li>links1b</li></ol></nav>", r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test2",
+        *      htmldoc=@HtmlDoc(
+        *              links={"links2a","links2b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test2() throws Exception {
+               String r = get("/testHtmlDocLinks/test2");
+               
assertEquals("<nav><ol><li>links2a</li><li>links2b</li></ol></nav>", r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test3",
+        *      htmldoc=@HtmlDoc(
+        *              links={"INHERIT","links3a","links3b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test3() throws Exception {
+               String r = get("/testHtmlDocLinks/test3");
+               
assertEquals("<nav><ol><li>links1a</li><li>links1b</li><li>links3a</li><li>links3b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test4",
+        *      htmldoc=@HtmlDoc(
+        *              links={"links4a","INHERIT","links4b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test4() throws Exception {
+               String r = get("/testHtmlDocLinks/test4");
+               
assertEquals("<nav><ol><li>links4a</li><li>links1a</li><li>links1b</li><li>links4b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test5",
+        *      htmldoc=@HtmlDoc(
+        *              links={"links5a","links5b","INHERIT"}
+        *      )
+        * )
+        */
+       @Test
+       public void test5() throws Exception {
+               String r = get("/testHtmlDocLinks/test5");
+               
assertEquals("<nav><ol><li>links5a</li><li>links5b</li><li>links1a</li><li>links1b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test6a",
+        *      htmldoc=@HtmlDoc(
+        *              links={"INHERIT","[0]:links6a","[3]:links6b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test6a() throws Exception {
+               String r = get("/testHtmlDocLinks/test6a");
+               
assertEquals("<nav><ol><li>links6a</li><li>links1a</li><li>links1b</li><li>links6b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test6b",
+        *      htmldoc=@HtmlDoc(
+        *              links={"[1]:links6a","[2]:links6b","INHERIT"}
+        *      )
+        * )
+        */
+       @Test
+       public void test6b() throws Exception {
+               String r = get("/testHtmlDocLinks/test6b");
+               
assertEquals("<nav><ol><li>links6a</li><li>links6b</li><li>links1a</li><li>links1b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test6c",
+        *      htmldoc=@HtmlDoc(
+        *              links={"[1]:links6a","[0]:links6b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test6c() throws Exception {
+               String r = get("/testHtmlDocLinks/test6c");
+               
assertEquals("<nav><ol><li>links6b</li><li>links6a</li></ol></nav>", r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test6d",
+        *      htmldoc=@HtmlDoc(
+        *              links={"INHERIT","foo[0]:links6a","bar[3]:links6b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test6d() throws Exception {
+               String r = get("/testHtmlDocLinks/test6d");
+               assertEquals("<nav><ol><li><a 
href='/testHtmlDocLinks/links6a'>foo</a></li><li>links1a</li><li>links1b</li><li><a
 href='/testHtmlDocLinks/links6b'>bar</a></li></ol></nav>", r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test6e",
+        *      htmldoc=@HtmlDoc(
+        *              links={"foo[1]:links6a","bar[2]:links6b","INHERIT"}
+        *      )
+        * )
+        */
+       @Test
+       public void test6e() throws Exception {
+               String r = get("/testHtmlDocLinks/test6e");
+               assertEquals("<nav><ol><li><a 
href='/testHtmlDocLinks/links6a'>foo</a></li><li><a 
href='/testHtmlDocLinks/links6b'>bar</a></li><li>links1a</li><li>links1b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test6f",
+        *      htmldoc=@HtmlDoc(
+        *              links={"foo[1]:links6a","bar[0]:links6b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test6f() throws Exception {
+               String r = get("/testHtmlDocLinks/test6f");
+               assertEquals("<nav><ol><li><a 
href='/testHtmlDocLinks/links6b'>bar</a></li><li><a 
href='/testHtmlDocLinks/links6a'>foo</a></li></ol></nav>", r);
+       }
+
+       /**
+        * @RestResource(
+        *      path="/testHtmlDocLinks2",
+        *      htmldoc=@HtmlDoc(
+        *              links={"INHERIT","links11a","links11b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test11() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test11");
+               
assertEquals("<nav><ol><li>links1a</li><li>links1b</li><li>links11a</li><li>links11b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test12",
+        *      htmldoc=@HtmlDoc(
+        *              links={"links12a","links12b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test12() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test12");
+               
assertEquals("<nav><ol><li>links12a</li><li>links12b</li></ol></nav>", r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test13",
+        *      htmldoc=@HtmlDoc(
+        *              links={"INHERIT","links13a","links13b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test13() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test13");
+               
assertEquals("<nav><ol><li>links1a</li><li>links1b</li><li>links11a</li><li>links11b</li><li>links13a</li><li>links13b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test14",
+        *      htmldoc=@HtmlDoc(
+        *              links={"links14a","INHERIT","links14b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test14() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test14");
+               
assertEquals("<nav><ol><li>links14a</li><li>links1a</li><li>links1b</li><li>links11a</li><li>links11b</li><li>links14b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test15",
+        *      htmldoc=@HtmlDoc(
+        *              links={"links15a","links15b","INHERIT"}
+        *      )
+        * )
+        */
+       @Test
+       public void test15() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test15");
+               
assertEquals("<nav><ol><li>links15a</li><li>links15b</li><li>links1a</li><li>links1b</li><li>links11a</li><li>links11b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test16a",
+        *      htmldoc=@HtmlDoc(
+        *              links={"INHERIT","[0]:links16a","[3]:links16b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test16a() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test16a");
+               
assertEquals("<nav><ol><li>links16a</li><li>links1a</li><li>links1b</li><li>links16b</li><li>links11a</li><li>links11b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test16b",
+        *      htmldoc=@HtmlDoc(
+        *              links={"[1]:links16a","[2]:links16b","INHERIT"}
+        *      )
+        * )
+        */
+       @Test
+       public void test16b() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test16b");
+               
assertEquals("<nav><ol><li>links16a</li><li>links16b</li><li>links1a</li><li>links1b</li><li>links11a</li><li>links11b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test16c",
+        *      htmldoc=@HtmlDoc(
+        *              links={"[1]:links16a","[0]:links16b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test16c() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test16c");
+               
assertEquals("<nav><ol><li>links16b</li><li>links16a</li></ol></nav>", r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test16d",
+        *      htmldoc=@HtmlDoc(
+        *              links={"INHERIT","foo[0]:links16a","bar[3]:links16b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test16d() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test16d");
+               assertEquals("<nav><ol><li><a 
href='/testHtmlDocLinks/testHtmlDocLinks2/links16a'>foo</a></li><li>links1a</li><li>links1b</li><li><a
 
href='/testHtmlDocLinks/testHtmlDocLinks2/links16b'>bar</a></li><li>links11a</li><li>links11b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test16e",
+        *      htmldoc=@HtmlDoc(
+        *              links={"foo[1]:links16a","bar[2]:links16b","INHERIT"}
+        *      )
+        * )
+        */
+       @Test
+       public void test16e() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test16e");
+               assertEquals("<nav><ol><li><a 
href='/testHtmlDocLinks/testHtmlDocLinks2/links16a'>foo</a></li><li><a 
href='/testHtmlDocLinks/testHtmlDocLinks2/links16b'>bar</a></li><li>links1a</li><li>links1b</li><li>links11a</li><li>links11b</li></ol></nav>",
 r);
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test16f",
+        *      htmldoc=@HtmlDoc(
+        *              links={"foo[1]:links16a","bar[0]:links16b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test16f() throws Exception {
+               String r = get("/testHtmlDocLinks/testHtmlDocLinks2/test16f");
+               assertEquals("<nav><ol><li><a 
href='/testHtmlDocLinks/testHtmlDocLinks2/links16b'>bar</a></li><li><a 
href='/testHtmlDocLinks/testHtmlDocLinks2/links16a'>foo</a></li></ol></nav>", 
r);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlDocTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlDocTest.java 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlDocTest.java
new file mode 100644
index 0000000..d3c337b
--- /dev/null
+++ 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/HtmlDocTest.java
@@ -0,0 +1,291 @@
+// 
***************************************************************************************************************************
+// * 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.*;
+
+/**
+ * Validates inheritance on the @HtmlDoc annotation.
+ */
+public class HtmlDocTest extends RestTestcase {
+       private RestClient client = TestMicroservice.DEFAULT_CLIENT;
+
+       private String get(String uri) throws Exception {
+               return 
client.doGet(uri).accept("text/html").getResponseAsString().replace('\n', ' 
').replace('"', '\'');
+       }
+       private String header(String r) {
+               return r.substring(r.indexOf("<header>")+8, 
r.indexOf("</header>"));
+       }
+       private String script(String r) {
+               return r.substring(r.indexOf("<script>")+8, 
r.indexOf("</script>"));
+       }
+       private String style(String r) {
+               return r.substring(r.indexOf("<style>")+7, 
r.indexOf("</style>"));
+       }
+       private String nav(String r) {
+               return r.substring(r.indexOf("<nav>")+5, r.indexOf("</nav>"));
+       }
+       private String aside(String r) {
+               return r.substring(r.indexOf("<aside>")+7, 
r.indexOf("</aside>"));
+       }
+       private String footer(String r) {
+               return r.substring(r.indexOf("<footer>")+8, 
r.indexOf("</footer>"));
+       }
+
+       /**
+        * @RestResource(
+        *      path="/testHtmlDoc",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"aside1a","aside1b","INHERIT"},
+        *              footer={"footer1a","footer1b"},
+        *              header={"header1a","header1b"},
+        *              nav={"nav1a","nav1b"},
+        *              script={"script1a","script1b"},
+        *              style={"style1a","style1b"},
+        *              stylesheet="stylesheet1"
+        *      )
+        * )
+        */
+       @Test
+       public void test1() throws Exception {
+               String r = get("/testHtmlDoc/test1");
+               assertEquals("header1a header1b", header(r));
+               assertEquals("script1a script1b", script(r));
+               assertEquals("@import '/testHtmlDoc/stylesheet1'; style1a 
style1b ", style(r));
+               assertEquals("nav1a nav1b", nav(r));
+               assertEquals("aside1a aside1b", aside(r));
+               assertEquals("footer1a footer1b", footer(r));
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test2",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"aside2a","aside2b"},
+        *              footer={"footer2a","footer2b"},
+        *              header={"header2a","header2b"},
+        *              nav={"nav2a","nav2b"},
+        *              script={"script2a","script2b"},
+        *              style={"style2a","style2b"},
+        *              stylesheet="stylesheet2"
+        *      )
+        * )
+        */
+       @Test
+       public void test2() throws Exception {
+               String r = get("/testHtmlDoc/test2");
+               assertEquals("header2a header2b", header(r));
+               assertEquals("script2a script2b", script(r));
+               assertEquals("@import '/testHtmlDoc/stylesheet2'; style2a 
style2b ", style(r));
+               assertEquals("nav2a nav2b", nav(r));
+               assertEquals("aside2a aside2b", aside(r));
+               assertEquals("footer2a footer2b", footer(r));
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test3",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"INHERIT","aside3a","aside3b"},
+        *              footer={"INHERIT","footer3a","footer3b"},
+        *              header={"INHERIT","header3a","header3b"},
+        *              nav={"INHERIT","nav3a","nav3b"},
+        *              script={"INHERIT","script3a","script3b"},
+        *              style={"INHERIT","style3a","style3b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test3() throws Exception {
+               String r = get("/testHtmlDoc/test3");
+               assertEquals("header1a header1b header3a header3b", header(r));
+               assertEquals("script1a script1b script3a script3b", script(r));
+               assertEquals("@import '/testHtmlDoc/stylesheet1'; style1a 
style1b style3a style3b ", style(r));
+               assertEquals("nav1a nav1b nav3a nav3b", nav(r));
+               assertEquals("aside1a aside1b aside3a aside3b", aside(r));
+               assertEquals("footer1a footer1b footer3a footer3b", footer(r));
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test4",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"aside4a","INHERIT","aside4b"},
+        *              footer={"footer4a","INHERIT","footer4b"},
+        *              header={"header4a","INHERIT","header4b"},
+        *              nav={"nav4a","INHERIT","nav4b"},
+        *              script={"script4a","INHERIT","script4b"},
+        *              style={"style4a","INHERIT","style4b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test4() throws Exception {
+               String r = get("/testHtmlDoc/test4");
+               assertEquals("header4a header1a header1b header4b", header(r));
+               assertEquals("script4a script1a script1b script4b", script(r));
+               assertEquals("@import '/testHtmlDoc/stylesheet1'; style4a 
style1a style1b style4b ", style(r));
+               assertEquals("nav4a nav1a nav1b nav4b", nav(r));
+               assertEquals("aside4a aside1a aside1b aside4b", aside(r));
+               assertEquals("footer4a footer1a footer1b footer4b", footer(r));
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test5",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"aside5a","aside5b","INHERIT"},
+        *              footer={"footer5a","footer5b","INHERIT"},
+        *              header={"header5a","header5b","INHERIT"},
+        *              nav={"nav5a","nav5b","INHERIT"},
+        *              script={"script5a","script5b","INHERIT"},
+        *              style={"style5a","style5b","INHERIT"}
+        *      )
+        * )
+        */
+       @Test
+       public void test5() throws Exception {
+               String r = get("/testHtmlDoc/test5");
+               assertEquals("header5a header5b header1a header1b", header(r));
+               assertEquals("script5a script5b script1a script1b", script(r));
+               assertEquals("@import '/testHtmlDoc/stylesheet1'; style5a 
style5b style1a style1b ", style(r));
+               assertEquals("nav5a nav5b nav1a nav1b", nav(r));
+               assertEquals("aside5a aside5b aside1a aside1b", aside(r));
+               assertEquals("footer5a footer5b footer1a footer1b", footer(r));
+       }
+
+       /**
+        * @RestResource(
+        *      path="/testHtmlDoc2",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"INHERIT","aside11a","aside11b"},
+        *              footer={"footer11a","INHERIT","footer11b"},
+        *              header={"header11a","header11b","INHERIT"},
+        *              nav={"INHERIT","nav11a","nav11b"},
+        *              script={"script11a","script11b"},
+        *              style={"style11a","style11b"},
+        *              stylesheet="stylesheet11"
+        *      )
+        * )
+        */
+       @Test
+       public void test11() throws Exception {
+               String r = get("/testHtmlDoc/testHtmlDoc2/test11");
+               assertEquals("header11a header11b header1a header1b", 
header(r));
+               assertEquals("script11a script11b", script(r));
+               assertEquals("@import '/testHtmlDoc/testHtmlDoc2/stylesheet11'; 
style11a style11b ", style(r));
+               assertEquals("nav1a nav1b nav11a nav11b", nav(r));
+               assertEquals("aside1a aside1b aside11a aside11b", aside(r));
+               assertEquals("footer11a footer1a footer1b footer11b", 
footer(r));
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test12",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"aside12a","aside12b"},
+        *              footer={"footer12a","footer12b"},
+        *              header={"header12a","header12b"},
+        *              nav={"nav12a","nav12b"},
+        *              script={"script12a","script12b"},
+        *              style={"style12a","style12b"},
+        *              stylesheet="stylesheet12"
+        *      )
+        * )
+        */
+       @Test
+       public void test12() throws Exception {
+               String r = get("/testHtmlDoc/testHtmlDoc2/test12");
+               assertEquals("header12a header12b", header(r));
+               assertEquals("script12a script12b", script(r));
+               assertEquals("@import '/testHtmlDoc/testHtmlDoc2/stylesheet12'; 
style12a style12b ", style(r));
+               assertEquals("nav12a nav12b", nav(r));
+               assertEquals("aside12a aside12b", aside(r));
+               assertEquals("footer12a footer12b", footer(r));
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test13",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"INHERIT","aside13a","aside13b"},
+        *              footer={"INHERIT","footer13a","footer13b"},
+        *              header={"INHERIT","header13a","header13b"},
+        *              nav={"INHERIT","nav13a","nav13b"},
+        *              script={"INHERIT","script13a","script13b"},
+        *              style={"INHERIT","style13a","style13b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test13() throws Exception {
+               String r = get("/testHtmlDoc/testHtmlDoc2/test13");
+               assertEquals("header11a header11b header1a header1b header13a 
header13b", header(r));
+               assertEquals("script11a script11b script13a script13b", 
script(r));
+               assertEquals("@import '/testHtmlDoc/testHtmlDoc2/stylesheet11'; 
style11a style11b style13a style13b ", style(r));
+               assertEquals("nav1a nav1b nav11a nav11b nav13a nav13b", nav(r));
+               assertEquals("aside1a aside1b aside11a aside11b aside13a 
aside13b", aside(r));
+               assertEquals("footer11a footer1a footer1b footer11b footer13a 
footer13b", footer(r));
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test14",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"aside14a","INHERIT","aside14b"},
+        *              footer={"footer14a","INHERIT","footer14b"},
+        *              header={"header14a","INHERIT","header14b"},
+        *              nav={"nav14a","INHERIT","nav14b"},
+        *              script={"script14a","INHERIT","script14b"},
+        *              style={"style14a","INHERIT","style14b"}
+        *      )
+        * )
+        */
+       @Test
+       public void test14() throws Exception {
+               String r = get("/testHtmlDoc/testHtmlDoc2/test14");
+               assertEquals("header14a header11a header11b header1a header1b 
header14b", header(r));
+               assertEquals("script14a script11a script11b script14b", 
script(r));
+               assertEquals("@import '/testHtmlDoc/testHtmlDoc2/stylesheet11'; 
style14a style11a style11b style14b ", style(r));
+               assertEquals("nav14a nav1a nav1b nav11a nav11b nav14b", nav(r));
+               assertEquals("aside14a aside1a aside1b aside11a aside11b 
aside14b", aside(r));
+               assertEquals("footer14a footer11a footer1a footer1b footer11b 
footer14b", footer(r));
+       }
+
+       /**
+        * @RestMethod(
+        *      path="/test15",
+        *      htmldoc=@HtmlDoc(
+        *              aside={"aside15a","aside15b","INHERIT"},
+        *              footer={"footer15a","footer15b","INHERIT"},
+        *              header={"header15a","header15b","INHERIT"},
+        *              nav={"nav15a","nav15b","INHERIT"},
+        *              script={"script15a","script15b","INHERIT"},
+        *              style={"style15a","style15b","INHERIT"}
+        *      )
+        * )
+        */
+       @Test
+       public void test15() throws Exception {
+               String r = get("/testHtmlDoc/testHtmlDoc2/test15");
+               assertEquals("header15a header15b header11a header11b header1a 
header1b", header(r));
+               assertEquals("script15a script15b script11a script11b", 
script(r));
+               assertEquals("@import '/testHtmlDoc/testHtmlDoc2/stylesheet11'; 
style15a style15b style11a style11b ", style(r));
+               assertEquals("nav15a nav15b nav1a nav1b nav11a nav11b", nav(r));
+               assertEquals("aside15a aside15b aside1a aside1b aside11a 
aside11b", aside(r));
+               assertEquals("footer15a footer15b footer11a footer1a footer1b 
footer11b", footer(r));
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
index 48dbe5a..794b617 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
@@ -38,6 +38,8 @@ import org.junit.runners.Suite.*;
        GroupsTest.class,
        GzipTest.class,
        HeadersTest.class,
+       HtmlDocTest.class,
+       HtmlDocLinksTest.class,
        InheritanceTest.class,
        InterfaceProxyTest.class,
        JacocoDummyTest.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
index 1718dff..5f89647 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
@@ -18,6 +18,7 @@ import static org.apache.juneau.internal.ClassUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.internal.Utils.*;
 import static org.apache.juneau.rest.RestContext.*;
+import static org.apache.juneau.rest.RestUtils.*;
 import static org.apache.juneau.rest.annotation.Inherit.*;
 
 import java.lang.annotation.*;
@@ -177,14 +178,15 @@ class CallMethod implements Comparable<CallMethod>  {
                                        Widget w = 
ClassUtils.newInstance(Widget.class, wc);
                                        htmlWidgets.put(w.getName(), w);
                                }
-                               htmlHeader = hd.header().length == 0 ? 
context.getHtmlHeader() : join(hd.header(), '\n');
-                               htmlLinks = hd.links().length == 0 ? 
context.getHtmlLinks() : hd.links();
-                               htmlNav = hd.nav().length == 0 ? 
context.getHtmlNav() : join(hd.nav(), '\n');
-                               htmlAside = hd.aside().length == 0 ? 
context.getHtmlAside() : join(hd.aside(), '\n');
-                               htmlFooter = hd.footer().length == 0 ? 
context.getHtmlFooter() : join(hd.footer(), '\n');
-                               htmlStyle = hd.style().length == 0 ? 
context.getHtmlStyle() : join(hd.style(), '\n');
+
+                               htmlHeader = 
resolveNewlineSeparatedAnnotation(hd.header(), context.getHtmlHeader());
+                               htmlNav = 
resolveNewlineSeparatedAnnotation(hd.nav(), context.getHtmlNav());
+                               htmlAside = 
resolveNewlineSeparatedAnnotation(hd.aside(), context.getHtmlAside());
+                               htmlFooter = 
resolveNewlineSeparatedAnnotation(hd.footer(), context.getHtmlFooter());
+                               htmlStyle = 
resolveNewlineSeparatedAnnotation(hd.style(), context.getHtmlStyle());
+                               htmlScript = 
resolveNewlineSeparatedAnnotation(hd.script(), context.getHtmlScript());
+                               htmlLinks = resolveLinks(hd.links(), 
context.getHtmlLinks());
                                htmlStylesheet = hd.stylesheet().isEmpty() ? 
context.getHtmlStylesheet() : hd.stylesheet();
-                               htmlScript = hd.script().length == 0 ? 
context.getHtmlScript() : join(hd.script(), '\n');
                                htmlNoWrap = hd.nowrap() ? hd.nowrap() : 
context.getHtmlNoWrap();
                                htmlNoResultsMessage = 
hd.noResultsMessage().isEmpty() ? context.getHtmlNoResultsMessage() : 
hd.noResultsMessage();
                                htmlTemplate =

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
index 4ccc292..0f3be32 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
@@ -15,6 +15,7 @@ package org.apache.juneau.rest;
 import static org.apache.juneau.internal.ArrayUtils.*;
 import static org.apache.juneau.internal.ReflectionUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.rest.RestUtils.*;
 
 import java.io.*;
 import java.util.*;
@@ -223,20 +224,14 @@ public class RestConfig implements ServletConfig {
                                HtmlDoc hd = r.htmldoc();
                                for (Class<? extends Widget> cw : hd.widgets())
                                        addHtmlWidget(cw);
-                               if (hd.header().length > 0)
-                                       setHtmlHeader(join(hd.header(), '\n'));
-                               if (hd.links().length != 0)
-                                       setHtmlLinks(hd.links());
-                               if (hd.nav().length > 0)
-                                       setHtmlNav(join(hd.nav(), '\n'));
-                               if (hd.aside().length > 0)
-                                       setHtmlAside(join(hd.aside(), '\n'));
-                               if (hd.footer().length > 0)
-                                       setHtmlFooter(join(hd.footer(), '\n'));
-                               if (hd.style().length > 0)
-                                       setHtmlStyle(join(hd.style(), '\n'));
-                               if (hd.script().length > 0)
-                                       setHtmlScript(join(hd.script(), '\n'));
+                               
setHtmlHeader(resolveNewlineSeparatedAnnotation(hd.header(), htmlHeader));
+                               
setHtmlNav(resolveNewlineSeparatedAnnotation(hd.nav(), htmlNav));
+                               
setHtmlAside(resolveNewlineSeparatedAnnotation(hd.aside(), htmlAside));
+                               
setHtmlFooter(resolveNewlineSeparatedAnnotation(hd.footer(), htmlFooter));
+                               
setHtmlStyle(resolveNewlineSeparatedAnnotation(hd.style(), htmlStyle));
+                               
setHtmlScript(resolveNewlineSeparatedAnnotation(hd.script(), htmlScript));
+                               setHtmlLinks(resolveLinks(hd.links(), 
htmlLinks));
+
                                if (! hd.stylesheet().isEmpty())
                                        setHtmlStylesheet(hd.stylesheet());
                                if (! hd.noResultsMessage().isEmpty())

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
index f335985..139569a 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -464,6 +464,9 @@ public final class RestContext extends Context {
                                        r = p.second();
                                } else if (o instanceof Class<?>) {
                                        Class<?> c = (Class<?>)o;
+                                       // Don't allow specifying yourself as a 
child.  Causes an infinite loop.
+                                       if (c == config.resourceClass)
+                                               continue;
                                        r = c;
                                } else {
                                        r = o;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest/src/main/java/org/apache/juneau/rest/RestUtils.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestUtils.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/RestUtils.java
index 41c363b..5c8611c 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestUtils.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestUtils.java
@@ -12,7 +12,10 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest;
 
+import static org.apache.juneau.internal.StringUtils.*;
+
 import java.util.*;
+import java.util.regex.*;
 
 import javax.servlet.http.*;
 
@@ -182,4 +185,42 @@ public final class RestUtils {
                String val = s.substring(i+1).trim();
                return new String[]{name,val};
        }
+
+       static String resolveNewlineSeparatedAnnotation(String[] value, String 
fromParent) {
+               if (value.length == 0)
+                       return fromParent;
+
+               List<String> l = new ArrayList<String>();
+               for (String v : value) {
+                       if (! "INHERIT".equals(v))
+                               l.add(v);
+                       else if (fromParent != null)
+                               l.addAll(Arrays.asList(fromParent));
+               }
+               return join(l, '\n');
+       }
+
+       private static final Pattern INDEXED_LINK_PATTERN = 
Pattern.compile("(?s)(\\S*)\\[(\\d+)\\]\\:(.*)");
+
+       static String[] resolveLinks(String[] links, String[] parentLinks) {
+               if (links.length == 0)
+                       return parentLinks;
+
+               List<String> list = new ArrayList<String>();
+               for (String l : links) {
+                       if ("INHERIT".equals(l))
+                               list.addAll(Arrays.asList(parentLinks));
+                       else if (l.indexOf('[') != -1 && 
INDEXED_LINK_PATTERN.matcher(l).matches()) {
+                                       Matcher lm = 
INDEXED_LINK_PATTERN.matcher(l);
+                                       lm.matches();
+                                       String key = lm.group(1);
+                                       int index = Math.min(list.size(), 
Integer.parseInt(lm.group(2)));
+                                       String remainder = lm.group(3);
+                                       list.add(index, key.isEmpty() ? 
remainder : key + ":" + remainder);
+                       } else {
+                               list.add(l);
+                       }
+               }
+               return list.toArray(new String[list.size()]);
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
index 936eb65..c100dc6 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HtmlDoc.java
@@ -113,7 +113,9 @@ public @interface HtmlDoc {
         *              On methods, this value is inherited from the 
<ja>@HtmlDoc</ja> annotation on the servlet/resource class.
         *      <li>
         *              On servlet/resource classes, this value is inherited 
from the <ja>@HtmlDoc</ja> annotation on the
-        *              parent class.
+        *              parent class if not overridden.
+        *      <li>
+        *              The parent value can be included by adding the literal 
<js>"INHERIT"</js> as a value.
         * </ul>
         */
        String[] header() default {};
@@ -161,6 +163,10 @@ public @interface HtmlDoc {
         *      <li>
         *              On servlet/resource classes, this value is inherited 
from the <ja>@HtmlDoc</ja> annotation on the
         *              parent class.
+        *      <li>
+        *              The parent links can be included by adding the literal 
<js>"INHERIT"</js> as a value.
+        *              <br>Use the syntax <js>"key[index]: value"</js> or 
<js>"[index]: value"</js> to specify an index location
+        *              to place a link inside the list of parent links.
         * </ul>
         */
        String[] links() default {};
@@ -207,6 +213,8 @@ public @interface HtmlDoc {
         *      <li>
         *              On servlet/resource classes, this value is inherited 
from the <ja>@HtmlDoc</ja> annotation on the
         *              parent class.
+        *      <li>
+        *              The parent value can be included by adding the literal 
<js>"INHERIT"</js> as a value.
         * </ul>
         */
        String[] nav() default {};
@@ -248,6 +256,8 @@ public @interface HtmlDoc {
         *      <li>
         *              On servlet/resource classes, this value is inherited 
from the <ja>@HtmlDoc</ja> annotation on the
         *              parent class.
+        *      <li>
+        *              The parent value can be included by adding the literal 
<js>"INHERIT"</js> as a value.
         * </ul>
         */
        String[] aside() default {};
@@ -289,6 +299,8 @@ public @interface HtmlDoc {
         *      <li>
         *              On servlet/resource classes, this value is inherited 
from the <ja>@HtmlDoc</ja> annotation on the
         *              parent class.
+        *      <li>
+        *              The parent value can be included by adding the literal 
<js>"INHERIT"</js> as a value.
         * </ul>
         */
        String[] footer() default {};
@@ -328,6 +340,8 @@ public @interface HtmlDoc {
         *      <li>
         *              On servlet/resource classes, this value is inherited 
from the <ja>@HtmlDoc</ja> annotation on the
         *              parent class.
+        *      <li>
+        *              The parent value can be included by adding the literal 
<js>"INHERIT"</js> as a value.
         * </ul>
         */
        String[] style() default {};
@@ -405,6 +419,8 @@ public @interface HtmlDoc {
         *      <li>
         *              On servlet/resource classes, this value is inherited 
from the <ja>@HtmlDoc</ja> annotation on the
         *              parent class.
+        *      <li>
+        *              The parent value can be included by adding the literal 
<js>"INHERIT"</js> as a value.
         * </ul>
         */
        String[] script() default {};

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fb8d004c/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index 146552a..27058e3 100644
--- 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -355,13 +355,18 @@ public @interface RestMethod {
         * </p>
         *
         * <p>
-        * The format of each value is: <js>"Key: comma-delimited-tokens".
+        * The format of each value is: <js>"Key: comma-delimited-tokens"</js>.
         * <br>Keys can be fully-qualified or short class names or <js>"*"</js> 
to represent all classes.
         * <br>Values are comma-delimited lists of bean property names.
         * <br>Properties apply to specified class and all subclasses.
         *
         * <p>
-        * Semicolons can be used as an additional separator for multiple 
values: <code>bpi="Bean1: foo; Bean2: bar,baz"</code>
+        * Semicolons can be used as an additional separator for multiple 
values:
+        * <p class='bcode'>
+        *      <jc>// Equivalent</jc>
+        *      bpi={<js>"Bean1: foo"</js>,<js>"Bean2: bar,baz"</js>}
+        *      bpi=<js>"Bean1: foo; Bean2: bar,baz"</js>
+        * </p>
         */
        String[] bpi() default {};
 
@@ -396,13 +401,18 @@ public @interface RestMethod {
         * </p>
         *
         * <p>
-        * The format of each value is: <js>"Key: comma-delimited-tokens".
+        * The format of each value is: <js>"Key: comma-delimited-tokens"</js>.
         * <br>Keys can be fully-qualified or short class names or <js>"*"</js> 
to represent all classes.
         * <br>Values are comma-delimited lists of bean property names.
         * <br>Properties apply to specified class and all subclasses.
         *
         * <p>
-        * Semicolons can be used as an additional separator for multiple 
values: <code>bpi="Bean1: foo; Bean2: bar,baz"</code>
+        * Semicolons can be used as an additional separator for multiple 
values:
+        * <p class='bcode'>
+        *      <jc>// Equivalent</jc>
+        *      bpx={<js>"Bean1: foo"</js>,<js>"Bean2: bar,baz"</js>}
+        *      bpx=<js>"Bean1: foo; Bean2: bar,baz"</js>
+        * </p>
         */
        String[] bpx() default {};
 

Reply via email to