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 2b10c13  RestClient tests
2b10c13 is described below

commit 2b10c1363060f26b7c7b65e343935e5cc7064f76
Author: JamesBognar <[email protected]>
AuthorDate: Sat Jun 13 14:09:15 2020 -0400

    RestClient tests
---
 .../main/java/org/apache/juneau/parser/Parser.java |   9 +
 .../org/apache/juneau/serializer/Serializer.java   |   9 +
 .../juneau/examples/rest/HelloWorldResource.java   |   4 +-
 .../juneau/rest/client2/BodyAnnotationTest.java    |   6 +-
 .../juneau/rest/client2/EndToEndInterfaceTest.java |  34 +-
 ...ClientMarshallsTest.java => MarshallsTest.java} |   2 +-
 .../rest/client2/RemoteMethodAnnotationTest.java   |  11 +-
 ...esourceAnnotationTest.java => RemotesTest.java} |  34 +-
 .../org/apache/juneau/rest/client2/RestClient.java |  18 +-
 .../java/org/apache/juneau/rest/DebugModeTest.java |  15 +-
 .../java/org/apache/juneau/rest/BasicRest.java     |   3 +-
 .../org/apache/juneau/rest/BasicRestConfig.java    |   7 +-
 .../org/apache/juneau/rest/BasicRestServlet.java   |   3 +-
 .../apache/juneau/rest/config/BasicJsonRest.java   | 108 +++----
 .../juneau/rest/config/BasicOpenApiRest.java       | 108 +++----
 .../juneau/rest/config/BasicSimpleJsonRest.java    | 108 +++----
 .../BasicUniversalRest.java}                       |  10 +-
 .../juneau/rest/config/htdocs/images/asf.png       | Bin 0 -> 8875 bytes
 .../juneau/rest/config/htdocs/images/juneau.png    | Bin 0 -> 6274 bytes
 .../juneau/rest/config/htdocs/styles/SwaggerUI.css | 342 +++++++++++++++++++++
 .../juneau/rest/config/htdocs/themes/dark.css      | 285 +++++++++++++++++
 .../juneau/rest/config/htdocs/themes/devops.css    | 275 +++++++++++++++++
 .../juneau/rest/config/htdocs/themes/light.css     | 272 ++++++++++++++++
 .../juneau/rest/config/htdocs/themes/original.css  | 236 ++++++++++++++
 24 files changed, 1687 insertions(+), 212 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
index 23a271b..ce78b64 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
@@ -120,6 +120,15 @@ import org.apache.juneau.xml.*;
 @ConfigurableContext
 public abstract class Parser extends BeanContext {
 
+       /**
+        * Represents no Parser.
+        */
+       public abstract class Null extends Parser {
+               private Null(PropertyStore ps, String[] consumes) {
+                       super(ps, consumes);
+               }
+       }
+
        
//-------------------------------------------------------------------------------------------------------------------
        // Configurable properties
        
//-------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
index 3e3d33b..9c222b5 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
@@ -42,6 +42,15 @@ import org.apache.juneau.internal.*;
 @ConfigurableContext
 public abstract class Serializer extends BeanTraverseContext {
 
+       /**
+        * Represents no Serializer.
+        */
+       public abstract class Null extends Serializer {
+               private Null(PropertyStore ps, String produces, String accept) {
+                       super(ps, produces, accept);
+               }
+       }
+
        
//-------------------------------------------------------------------------------------------------------------------
        // Configurable properties
        
//-------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
index 237c353..7d373f0 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
@@ -15,8 +15,8 @@ package org.apache.juneau.examples.rest;
 import static org.apache.juneau.http.HttpMethodName.*;
 
 import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 
 /**
  * Sample REST resource that prints out a simple "Hello world!" message.
@@ -38,7 +38,7 @@ import org.apache.juneau.rest.annotation.*;
                "</div>"
        }
 )
-public class HelloWorldResource implements BasicRestConfig {
+public class HelloWorldResource implements BasicUniversalRest {
 
        /**
         * GET request handler.
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/BodyAnnotationTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/BodyAnnotationTest.java
index 0595b02..000576c 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/BodyAnnotationTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/BodyAnnotationTest.java
@@ -27,8 +27,8 @@ import org.apache.juneau.http.annotation.Header;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.marshall.*;
-import org.apache.juneau.oapi.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.utils.*;
@@ -184,8 +184,8 @@ public class BodyAnnotationTest {
        // Basic tests - OpenAPI
        
//=================================================================================================================
 
-       
@Rest(serializers=OpenApiSerializer.class,parsers=OpenApiParser.class,defaultAccept="text/openapi")
-       public static class B {
+       @Rest
+       public static class B implements BasicOpenApiRest {
                @RestMethod
                public Object postB01(@Body int b, @Header("Content-Type") 
String ct) {
                        assertEquals("text/openapi", ct);
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/EndToEndInterfaceTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/EndToEndInterfaceTest.java
index d20fc85..216d8ff 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/EndToEndInterfaceTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/EndToEndInterfaceTest.java
@@ -23,8 +23,8 @@ import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.Header;
 import org.apache.juneau.http.annotation.Query;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.http.exception.*;
@@ -54,8 +54,8 @@ public class EndToEndInterfaceTest {
                public String a03(@Header("foo") String b);
        }
 
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, 
defaultAccept="text/json")
-       public static class A implements IA {
+       @Rest
+       public static class A implements IA, BasicSimpleJsonRest {
 
                @Override
                @RestMethod(name=PUT, path="/a01")
@@ -96,8 +96,8 @@ public class EndToEndInterfaceTest {
        
//=================================================================================================================
 
        @Remote
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, 
defaultAccept="text/json")
-       public static interface IB {
+       @Rest
+       public static interface IB extends BasicSimpleJsonRest {
 
                @RemoteMethod(method="PUT", path="/a01")
                @RestMethod(name=PUT, path="/a01")
@@ -150,8 +150,8 @@ public class EndToEndInterfaceTest {
        
//=================================================================================================================
 
        @Remote
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, 
defaultAccept="text/json")
-       public static interface IC {
+       @Rest
+       public static interface IC extends BasicSimpleJsonRest {
                @RemoteMethod @RestMethod Ok ok();
                @RemoteMethod @RestMethod Accepted accepted();
                @RemoteMethod @RestMethod AlreadyReported alreadyReported();
@@ -301,8 +301,8 @@ public class EndToEndInterfaceTest {
        
//=================================================================================================================
 
        @Remote
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, 
defaultAccept="text/json")
-       public static interface ID {
+       @Rest
+       public static interface ID extends BasicSimpleJsonRest {
                @RemoteMethod @RestMethod StreamResource streamResource() 
throws IOException ;
                @RemoteMethod @RestMethod ReaderResource readerResource() 
throws IOException ;
        }
@@ -363,8 +363,8 @@ public class EndToEndInterfaceTest {
        
//=================================================================================================================
 
        @Remote
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, 
defaultAccept="text/json")
-       public static interface IE {
+       @Rest
+       public static interface IE extends BasicSimpleJsonRest {
                @RemoteMethod @RestMethod void badRequest() throws BadRequest;
                @RemoteMethod @RestMethod void conflict() throws Conflict;
                @RemoteMethod @RestMethod void expectationFailed() throws 
ExpectationFailed;
@@ -1275,8 +1275,8 @@ public class EndToEndInterfaceTest {
        
//-----------------------------------------------------------------------------------------------------------------
 
        @Remote
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, 
defaultAccept="text/json")
-       public static interface IF {
+       @Rest
+       public static interface IF extends BasicSimpleJsonRest {
                @RemoteMethod @RestMethod BadRequest badRequest();
                @RemoteMethod @RestMethod Conflict conflict();
                @RemoteMethod @RestMethod ExpectationFailed expectationFailed();
@@ -1586,8 +1586,8 @@ public class EndToEndInterfaceTest {
        
//-----------------------------------------------------------------------------------------------------------------
 
        @Remote
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, 
defaultAccept="text/json")
-       public static interface IG {
+       @Rest
+       public static interface IG extends BasicSimpleJsonRest {
                @RemoteMethod @RestMethod Reader reader();
                @RemoteMethod @RestMethod InputStream inputStream();
        }
@@ -1619,8 +1619,8 @@ public class EndToEndInterfaceTest {
        
//=================================================================================================================
 
        @Remote
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, 
defaultAccept="text/json")
-       public static interface IH {
+       @Rest
+       public static interface IH extends BasicSimpleJsonRest {
                @RemoteMethod @RestMethod SeeOtherRoot seeOtherRoot();
        }
 
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientMarshallsTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/MarshallsTest.java
similarity index 99%
rename from 
juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientMarshallsTest.java
rename to 
juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/MarshallsTest.java
index b79ee1b..c664ca2 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientMarshallsTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/MarshallsTest.java
@@ -24,7 +24,7 @@ import org.apache.juneau.rest.mock2.*;
 import org.junit.*;
 
 @FixMethodOrder(NAME_ASCENDING)
-public class RestClientMarshallsTest {
+public class MarshallsTest {
 
        public static class Bean {
                public int f;
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteMethodAnnotationTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteMethodAnnotationTest.java
index 2275643..12e17a6 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteMethodAnnotationTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteMethodAnnotationTest.java
@@ -22,9 +22,8 @@ import org.apache.http.*;
 import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.Response;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.oapi.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.junit.*;
@@ -206,8 +205,8 @@ public class RemoteMethodAnnotationTest {
        // Return types, JSON
        
//=================================================================================================================
 
-       @Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class)
-       public static class C {
+       @Rest
+       public static class C implements BasicSimpleJsonRest {
 
                @RestMethod(name="POST")
                public String c01(@Body String body) {
@@ -294,8 +293,8 @@ public class RemoteMethodAnnotationTest {
        // Return types, part serialization
        
//=================================================================================================================
 
-       @Rest(serializers=OpenApiSerializer.class, parsers=OpenApiParser.class, 
defaultAccept="text/openapi")
-       public static class D {
+       @Rest
+       public static class D implements BasicOpenApiRest {
 
                @RestMethod(name="POST")
                @Response
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteResourceAnnotationTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemotesTest.java
similarity index 90%
rename from 
juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteResourceAnnotationTest.java
rename to 
juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemotesTest.java
index 1bfa5ea..b9aa946 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteResourceAnnotationTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemotesTest.java
@@ -16,12 +16,13 @@ import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
 
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.junit.*;
 
 @FixMethodOrder(NAME_ASCENDING)
-public class RemoteResourceAnnotationTest {
+public class RemotesTest {
 
        
//=================================================================================================================
        // @RemoteResource(path), relative paths
@@ -273,4 +274,35 @@ public class RemoteResourceAnnotationTest {
                assertEquals("foo", t.b01a());
                assertEquals("foo", t.b01b());
        }
+
+       
//=================================================================================================================
+       // Other tests
+       
//=================================================================================================================
+
+       @Rest(path="/C01")
+       public static class C01 implements BasicSimpleJsonRest {
+
+               @RestMethod(path="c01")
+               public String c01() {
+                       return "foo";
+               }
+       }
+
+       @Remote(path="/")
+       public static interface C01i {
+               @RemoteMethod
+               public String c01();
+       }
+
+       @Test
+       public void c01_overriddenRootUrl() throws Exception {
+               C01i x = MockRestClient
+                       .create(C01.class)
+                       .json()
+                       .build()
+                       .getRemote(C01i.class, "http://localhost/C01";);
+
+               assertEquals("foo", x.c01());
+       }
+
 }
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
index fd5bad5..cd77c8a 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
@@ -2908,7 +2908,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
         * @return The new proxy interface.
         * @throws RemoteMetadataException If the REST URI cannot be determined 
based on the information given.
         */
-       public <T> T getRemote(final Class<T> interfaceClass) {
+       public <T> T getRemote(Class<T> interfaceClass) {
                return getRemote(interfaceClass, null);
        }
 
@@ -2920,11 +2920,11 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
         * </ul>
         *
         * @param interfaceClass The interface to create a proxy for.
-        * @param restUrl The URL of the REST interface.
+        * @param rootUrl The URL of the REST interface.
         * @return The new proxy interface.
         */
-       public <T> T getRemote(final Class<T> interfaceClass, final Object 
restUrl) {
-               return getRemote(interfaceClass, restUrl, null, null);
+       public <T> T getRemote(Class<T> interfaceClass, Object rootUrl) {
+               return getRemote(interfaceClass, rootUrl, null, null);
        }
 
        /**
@@ -2935,18 +2935,18 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
         * </ul>
 
         * @param interfaceClass The interface to create a proxy for.
-        * @param restUrl The URL of the REST interface.
+        * @param rootUrl The URL of the REST interface.
         * @param serializer The serializer used to serialize POJOs to the body 
of the HTTP request.
         * @param parser The parser used to parse POJOs from the body of the 
HTTP response.
         * @return The new proxy interface.
         */
        @SuppressWarnings({ "unchecked" })
-       public <T> T getRemote(final Class<T> interfaceClass, Object restUrl, 
final Serializer serializer, final Parser parser) {
+       public <T> T getRemote(final Class<T> interfaceClass, Object rootUrl, 
final Serializer serializer, final Parser parser) {
 
-               if (restUrl == null)
-                       restUrl = rootUrl;
+               if (rootUrl == null)
+                       rootUrl = this.rootUrl;
 
-               final String restUrl2 = trimSlashes(emptyIfNull(restUrl));
+               final String restUrl2 = trimSlashes(emptyIfNull(rootUrl));
 
                try {
                        return (T)Proxy.newProxyInstance(
diff --git 
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/DebugModeTest.java
 
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/DebugModeTest.java
index 151ee1e..c7b9881 100644
--- 
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/DebugModeTest.java
+++ 
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/DebugModeTest.java
@@ -21,6 +21,7 @@ import javax.servlet.http.*;
 
 import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 import org.apache.juneau.rest.mock2.*;
 import org.junit.*;
 
@@ -81,7 +82,7 @@ public class DebugModeTest {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Rest(callLogger=CaptureCallLogger.class)
-       public static class A1 implements BasicRestConfig {
+       public static class A1 implements BasicUniversalRest {
                @RestMethod
                public boolean getA01(RestRequest req) {
                        return req.isDebug();
@@ -235,7 +236,7 @@ public class DebugModeTest {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Rest(callLogger=CaptureCallLogger.class, debug="true")
-       public static class A2 implements BasicRestConfig {
+       public static class A2 implements BasicUniversalRest {
                @RestMethod
                public boolean getA01(RestRequest req) {
                        return req.isDebug();
@@ -314,7 +315,7 @@ public class DebugModeTest {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Rest(callLogger=CaptureCallLogger.class,debug="false")
-       public static class A3 implements BasicRestConfig {
+       public static class A3 implements BasicUniversalRest {
                @RestMethod
                public boolean getA01(RestRequest req) {
                        return req.isDebug();
@@ -393,7 +394,7 @@ public class DebugModeTest {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Rest(callLogger=CaptureCallLogger.class,debug="per-request")
-       public static class A4 implements BasicRestConfig {
+       public static class A4 implements BasicUniversalRest {
                @RestMethod
                public boolean getA01(RestRequest req) {
                        return req.isDebug();
@@ -472,7 +473,7 @@ public class DebugModeTest {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Rest
-       public static class B1 implements BasicRestConfig, RestCallLogger {
+       public static class B1 implements BasicUniversalRest, RestCallLogger {
                @RestMethod
                public boolean getB01(RestRequest req) {
                        return req.isDebug();
@@ -535,7 +536,7 @@ public class DebugModeTest {
                        + 
"C1.getC04a=per-request,C1.getC04b=per-request,C1.getC04c=PER-REQUEST,C1.getC04d=PER-REQUEST,C1.getC04e=PER-REQUEST,C1.getC04f=PER-REQUEST,"
                        + 
"C1.getC05a=foo,C1.getC05b=,C1.getC05c=foo,C1.getC05d=foo,C1.getC05e=foo,C1.getC05f=foo,"
        )
-       public static class C1 implements BasicRestConfig {
+       public static class C1 implements BasicUniversalRest {
 
                @RestMethod
                public boolean getC01a(RestRequest req) {
@@ -869,7 +870,7 @@ public class DebugModeTest {
                        + 
"C2.getC04a=per-request,C2.getC04b=per-request,C2.getC04c=PER-REQUEST,C2.getC04d=PER-REQUEST,C2.getC04e=PER-REQUEST,C2.getC04f=PER-REQUEST,"
                        + 
"C2.getC05a=foo,C2.getC05b=,C2.getC05c=foo,C2.getC05d=foo,C2.getC05e=foo,C2.getC05f=foo,"
        )
-       public static class C2 implements BasicRestConfig {
+       public static class C2 implements BasicUniversalRest {
 
                @RestMethod
                public boolean getC01a(RestRequest req) {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRest.java
index 0cba9fb..9cc7524 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRest.java
@@ -28,6 +28,7 @@ import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.html.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 import org.apache.juneau.utils.*;
 import org.apache.juneau.http.exception.*;
 
@@ -50,7 +51,7 @@ import org.apache.juneau.http.exception.*;
                "stats: servlet:/stats"
        }
 )
-public abstract class BasicRest implements BasicRestConfig, BasicRestMethods, 
RestCallHandler, RestInfoProvider, RestCallLogger, RestResourceResolver, 
ClasspathResourceFinder {
+public abstract class BasicRest implements BasicUniversalRest, 
BasicRestMethods, RestCallHandler, RestInfoProvider, RestCallLogger, 
RestResourceResolver, ClasspathResourceFinder {
 
        private Logger logger = Logger.getLogger(getClass().getName());
        private volatile RestContext context;
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestConfig.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestConfig.java
index 4e044bf..84cfde2 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestConfig.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestConfig.java
@@ -20,6 +20,7 @@ import org.apache.juneau.msgpack.*;
 import org.apache.juneau.oapi.*;
 import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 import org.apache.juneau.serializer.annotation.*;
 import org.apache.juneau.soap.*;
 import org.apache.juneau.uon.*;
@@ -28,11 +29,13 @@ import org.apache.juneau.xml.*;
 import org.apache.juneau.xmlschema.XmlSchemaDocSerializer;
 
 /**
- * Basic configuration for a REST resource.
+ * Basic configuration for a REST resource that supports all languages.
  *
  * <p>
  * Classes that don't extend from {@link BasicRestServlet} can implement this 
interface to
  * be configured with the same serializers/parsers/etc... as {@link 
BasicRestServlet}.
+ *
+ * @deprecated Use {@link BasicUniversalRest}.
  */
 @Rest(
 
@@ -121,5 +124,5 @@ import org.apache.juneau.xmlschema.XmlSchemaDocSerializer;
        // When parsing generated beans, ignore unknown properties that may 
only exist as getters and not setters.
        ignoreUnknownBeanProperties="true"
 )
-@SuppressWarnings("deprecation")
+@Deprecated
 public interface BasicRestConfig {}
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
index 11fb1ba..d149ff6 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
@@ -19,6 +19,7 @@ import org.apache.juneau.jso.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
 import org.apache.juneau.soap.*;
 import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
@@ -164,7 +165,7 @@ import org.apache.juneau.xml.*;
                "stats: servlet:/stats"
        }
 )
-public abstract class BasicRestServlet extends RestServlet implements 
BasicRestConfig, BasicRestMethods {
+public abstract class BasicRestServlet extends RestServlet implements 
BasicUniversalRest, BasicRestMethods {
        private static final long serialVersionUID = 1L;
 
        /**
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonRest.java
similarity index 61%
copy from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
copy to 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonRest.java
index 237c353..a0f0609 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonRest.java
@@ -1,52 +1,56 @@
-// 
***************************************************************************************************************************
-// * 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.examples.rest;
-
-import static org.apache.juneau.http.HttpMethodName.*;
-
-import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-
-/**
- * Sample REST resource that prints out a simple "Hello world!" message.
- *
- * <ul class='seealso'>
- *     <li class='extlink'>{@source}
- * </ul>
- */
-@Rest(
-       title="Hello World",
-       description="An example of the simplest-possible resource",
-       path="/helloWorld"
-)
-@HtmlDocConfig(
-       aside={
-               "<div style='max-width:400px' class='text'>",
-               "       <p>This page shows a resource that simply response with 
a 'Hello world!' message</p>",
-               "       <p>The POJO serialized is a simple String.</p>",
-               "</div>"
-       }
-)
-public class HelloWorldResource implements BasicRestConfig {
-
-       /**
-        * GET request handler.
-        *
-        * @return A simple Hello-World message.
-        */
-       @RestMethod(name=GET, path="/*", summary="Responds with \"Hello 
world!\"")
-       public String sayHello() {
-               return "Hello world!";
-       }
-}
+// 
***************************************************************************************************************************
+// * 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.config;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.serializer.annotation.*;
+
+/**
+ * Basic configuration for a REST resource that supports JSON transport.
+ */
+@Rest(
+
+       // Default serializers for all Java methods in the class.
+       serializers={
+               JsonSerializer.class,
+       },
+
+       // Default parsers for all Java methods in the class.
+       parsers={
+               JsonParser.class,
+       },
+
+       defaultAccept="text/json",
+
+       // Optional external configuration file.
+       config="$S{juneau.configFile,SYSTEM_DEFAULT}",
+
+       logging=@Logging(
+               level="INFO",
+               useStackTraceHashing="true",
+               rules={
+                       @LoggingRule(codes="500-", level="WARNING")
+               }
+       )
+)
+@SerializerConfig(
+       // Enable automatic resolution of URI objects to root-relative values.
+       uriResolution="ROOT_RELATIVE"
+)
+@BeanConfig(
+       // When parsing generated beans, ignore unknown properties that may 
only exist as getters and not setters.
+       ignoreUnknownBeanProperties="true"
+)
+public interface BasicJsonRest {}
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicOpenApiRest.java
similarity index 61%
copy from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
copy to 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicOpenApiRest.java
index 237c353..24f141f 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicOpenApiRest.java
@@ -1,52 +1,56 @@
-// 
***************************************************************************************************************************
-// * 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.examples.rest;
-
-import static org.apache.juneau.http.HttpMethodName.*;
-
-import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-
-/**
- * Sample REST resource that prints out a simple "Hello world!" message.
- *
- * <ul class='seealso'>
- *     <li class='extlink'>{@source}
- * </ul>
- */
-@Rest(
-       title="Hello World",
-       description="An example of the simplest-possible resource",
-       path="/helloWorld"
-)
-@HtmlDocConfig(
-       aside={
-               "<div style='max-width:400px' class='text'>",
-               "       <p>This page shows a resource that simply response with 
a 'Hello world!' message</p>",
-               "       <p>The POJO serialized is a simple String.</p>",
-               "</div>"
-       }
-)
-public class HelloWorldResource implements BasicRestConfig {
-
-       /**
-        * GET request handler.
-        *
-        * @return A simple Hello-World message.
-        */
-       @RestMethod(name=GET, path="/*", summary="Responds with \"Hello 
world!\"")
-       public String sayHello() {
-               return "Hello world!";
-       }
-}
+// 
***************************************************************************************************************************
+// * 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.config;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.oapi.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.serializer.annotation.*;
+
+/**
+ * Basic configuration for a REST resource that supports OpenAPI transport.
+ */
+@Rest(
+
+       // Default serializers for all Java methods in the class.
+       serializers={
+               OpenApiSerializer.class,
+       },
+
+       // Default parsers for all Java methods in the class.
+       parsers={
+               OpenApiParser.class,
+       },
+
+       defaultAccept="text/openapi",
+
+       // Optional external configuration file.
+       config="$S{juneau.configFile,SYSTEM_DEFAULT}",
+
+       logging=@Logging(
+               level="INFO",
+               useStackTraceHashing="true",
+               rules={
+                       @LoggingRule(codes="500-", level="WARNING")
+               }
+       )
+)
+@SerializerConfig(
+       // Enable automatic resolution of URI objects to root-relative values.
+       uriResolution="ROOT_RELATIVE"
+)
+@BeanConfig(
+       // When parsing generated beans, ignore unknown properties that may 
only exist as getters and not setters.
+       ignoreUnknownBeanProperties="true"
+)
+public interface BasicOpenApiRest {}
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicSimpleJsonRest.java
similarity index 60%
copy from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
copy to 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicSimpleJsonRest.java
index 237c353..1738644 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicSimpleJsonRest.java
@@ -1,52 +1,56 @@
-// 
***************************************************************************************************************************
-// * 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.examples.rest;
-
-import static org.apache.juneau.http.HttpMethodName.*;
-
-import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-
-/**
- * Sample REST resource that prints out a simple "Hello world!" message.
- *
- * <ul class='seealso'>
- *     <li class='extlink'>{@source}
- * </ul>
- */
-@Rest(
-       title="Hello World",
-       description="An example of the simplest-possible resource",
-       path="/helloWorld"
-)
-@HtmlDocConfig(
-       aside={
-               "<div style='max-width:400px' class='text'>",
-               "       <p>This page shows a resource that simply response with 
a 'Hello world!' message</p>",
-               "       <p>The POJO serialized is a simple String.</p>",
-               "</div>"
-       }
-)
-public class HelloWorldResource implements BasicRestConfig {
-
-       /**
-        * GET request handler.
-        *
-        * @return A simple Hello-World message.
-        */
-       @RestMethod(name=GET, path="/*", summary="Responds with \"Hello 
world!\"")
-       public String sayHello() {
-               return "Hello world!";
-       }
-}
+// 
***************************************************************************************************************************
+// * 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.config;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.serializer.annotation.*;
+
+/**
+ * Basic configuration for a REST resource that supports simplified JSON 
transport.
+ */
+@Rest(
+
+       // Default serializers for all Java methods in the class.
+       serializers={
+               SimpleJsonSerializer.class,
+       },
+
+       // Default parsers for all Java methods in the class.
+       parsers={
+               SimpleJsonParser.class,
+       },
+
+       // Optional external configuration file.
+       config="$S{juneau.configFile,SYSTEM_DEFAULT}",
+
+       defaultAccept="text/json+simple",
+
+       logging=@Logging(
+               level="INFO",
+               useStackTraceHashing="true",
+               rules={
+                       @LoggingRule(codes="500-", level="WARNING")
+               }
+       )
+)
+@SerializerConfig(
+       // Enable automatic resolution of URI objects to root-relative values.
+       uriResolution="ROOT_RELATIVE"
+)
+@BeanConfig(
+       // When parsing generated beans, ignore unknown properties that may 
only exist as getters and not setters.
+       ignoreUnknownBeanProperties="true"
+)
+public interface BasicSimpleJsonRest {}
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestConfig.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicUniversalRest.java
similarity index 95%
copy from 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestConfig.java
copy to 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicUniversalRest.java
index 4e044bf..f7e476a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestConfig.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicUniversalRest.java
@@ -10,7 +10,7 @@
 // * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
 // * specific language governing permissions and limitations under the 
License.                                              *
 // 
***************************************************************************************************************************
-package org.apache.juneau.rest;
+package org.apache.juneau.rest.config;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.html.*;
@@ -19,16 +19,16 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.msgpack.*;
 import org.apache.juneau.oapi.*;
 import org.apache.juneau.plaintext.*;
+import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.serializer.annotation.*;
 import org.apache.juneau.soap.*;
 import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
-import org.apache.juneau.xmlschema.XmlSchemaDocSerializer;
 
 /**
- * Basic configuration for a REST resource.
+ * Basic configuration for a REST resource that supports all languages.
  *
  * <p>
  * Classes that don't extend from {@link BasicRestServlet} can implement this 
interface to
@@ -45,7 +45,6 @@ import org.apache.juneau.xmlschema.XmlSchemaDocSerializer;
                SimpleJsonSerializer.class,
                JsonSchemaSerializer.class,
                XmlDocSerializer.class,
-               XmlSchemaDocSerializer.class,
                UonSerializer.class,
                UrlEncodingSerializer.class,
                OpenApiSerializer.class,
@@ -121,5 +120,4 @@ import org.apache.juneau.xmlschema.XmlSchemaDocSerializer;
        // When parsing generated beans, ignore unknown properties that may 
only exist as getters and not setters.
        ignoreUnknownBeanProperties="true"
 )
-@SuppressWarnings("deprecation")
-public interface BasicRestConfig {}
+public interface BasicUniversalRest {}
diff --git 
a/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/images/asf.png
 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/images/asf.png
new file mode 100644
index 0000000..ce28113
Binary files /dev/null and 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/images/asf.png
 differ
diff --git 
a/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/images/juneau.png
 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/images/juneau.png
new file mode 100644
index 0000000..42a1656
Binary files /dev/null and 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/images/juneau.png
 differ
diff --git 
a/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/styles/SwaggerUI.css
 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/styles/SwaggerUI.css
new file mode 100644
index 0000000..b55ffc6
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/styles/SwaggerUI.css
@@ -0,0 +1,342 @@
+/*
+ 
***************************************************************************************************************************
+ * 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.  
                                            *
+ 
***************************************************************************************************************************
+*/
+
+.swagger-ui {  
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Header key-value pairs
+ 
----------------------------------------------------------------------------------------------------------*/
+
+.swagger-ui table.header {
+    margin-bottom: 15px;
+       width: 95%;
+       border: none;
+}
+
+.swagger-ui table.header * {
+       vertical-align: middle;
+}
+
+.swagger-ui table.header th {
+    font-weight: bold;
+    padding: 5px 10px;
+    text-align: left;
+    white-space: nowrap;
+       border: none;
+       border-radius: 3px;
+}
+
+.swagger-ui table.header td {
+       padding: 5px 10px;
+    text-align: left;
+    vertical-align: middle;
+       border: none;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Method buttons (e.g GET/PUT/... buttons)                                    
                            
+ 
----------------------------------------------------------------------------------------------------------*/
+.method-button {
+       display: inline-block;
+    font-weight: bold;
+    min-width: 60px;
+    padding: 6px 15px;
+    text-align: center;
+    border-radius: 3px;
+    text-shadow: 0 1px 0 rgba(0,0,0,.1);
+    color: #fff;
+}
+.get .method-button        { background: rgb(97,175,254); }
+.put .method-button        { background: rgb(252,161,48); }
+.post .method-button       { background: rgb(73,204,144); }
+.delete .method-button     { background: rgb(249,62,62); }
+.options .method-button    { background: rgb(153,102,255); }
+.deprecated .method-button { background: rgb(170,170,170); }
+.model .method-button      { background: rgb(150,150,150); min-width: 120px;}
+.other .method-button      { background: rgb(230,230,0); }
+
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Tag block                                                                   
                             -
+ - Encapsulates one or more op-blocks.
+ 
----------------------------------------------------------------------------------------------------------*/
+
+.tag-block {
+       min-width: 800px;
+}
+
+.tag-block-summary {
+       margin: 10px 0px;
+       padding: 5px 0px;
+    align-items: center;
+    cursor: pointer;
+       border-bottom: 1px solid rgba(59,65,81,.2);
+       user-select: none;
+       transition: all .2s;
+}
+.tag-block-summary:hover {
+       background-color: rgba(59,65,81,.1);
+}
+
+.tag-block-summary .name {
+       font-size: 18px;
+       padding: 0px 20px;
+}
+.tag-block-summary .description {
+       font-size: 14px;
+       padding: 0px 20px;
+}
+.tag-block-summary .extdocs {
+       float: right;
+       font-size: 14px;
+       padding: 0px 20px;
+}
+
+.tag-block-open .tag-block-contents { display: block; }
+.tag-block-closed .tag-block-contents { display: none; }
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Op block                                                                    
                      
+ - Encapsulates a single http-method + http-path
+ 
----------------------------------------------------------------------------------------------------------*/
+
+.op-block {
+       margin-bottom: 10px;
+    align-items: center;
+    border-radius: 4px;
+}
+
+.op-block.get        { background: rgba(97,175,254,.1); border: 1px solid 
rgb(97,175,254); }
+.op-block.put        { background: rgba(252,161,48,.1); border: 1px solid 
rgb(252,161,48); }
+.op-block.post       { background: rgba(73,204,144,.1); border: 1px solid 
rgb(73,204,144); }
+.op-block.options    { background: rgba(153,102,255,.1); border: 1px solid 
rgb(153,102,255); }
+.op-block.delete     { background: rgba(249,62,62,.1); border: 1px solid 
rgb(249,62,62); }
+.op-block.deprecated { background: rgba(170,170,170,.1); border: 1px solid 
rgb(170,170,170); }
+.op-block.model      { background: rgba(0,0,0,.05); border: 1px solid 
rgb(170,170,170); }
+.op-block.other      { background: rgba(230,230,0,0.1); border: 1px solid 
rgb(230,230,0); }
+
+.op-block-summary {    
+       padding: 5px;
+    cursor: pointer;
+       user-select: none;
+}
+
+.op-block-summary .path {
+       font-size: 14px;
+       word-break: break-all;
+    font-family: monospace;
+    font-weight: bold;
+    padding:10px;
+}
+
+.op-block.deprecated .op-block-summary .path { color: #8f9199; 
text-decoration: line-through;}
+.op-block.deprecated .op-block-summary .description { color: #8f9199 }
+
+.op-block-summary .summary {
+    font-size: 14px;
+    padding: 10px;
+}
+
+.op-block-description {
+    font-size: 14px;
+    padding: 10px;
+}
+
+
+.op-block-open .op-block-contents { display: block; }
+.op-block-closed .op-block-contents { display: none; }
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Op block section header                                                     
                                          -
+ - 'Parameters' and 'Responses' subsections in an op-block
+ 
----------------------------------------------------------------------------------------------------------*/
+
+.op-block-section-header {
+    padding: 8px 15px;
+    background: hsla(0,0%,100%,.3);
+    box-shadow: 1px 2px 3px rgba(0,0,0,.3);
+    margin: 10px;
+    border-radius: 4px;
+}
+
+.op-block-section-header .title {
+    font-size: 14px;
+    margin: 0px;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Parameters and Responses sections
+ 
----------------------------------------------------------------------------------------------------------*/
+
+table.parameters, table.responses {
+    border-collapse: collapse;
+    margin: 20px;
+       width: 95%;
+       border-bottom: 1px solid rgba(59,65,81,.2);
+}
+
+th.parameter-key, th.response-key {
+       font-size: 12px;
+    font-weight: bold;
+    text-align: left;
+       border: none;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+       background-color: inherit;
+}
+
+td.parameter-key, td.response-key {
+       font-size: 12px;
+    padding: 10px;
+    text-align: left;
+       border: none;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+       background-color: inherit;
+}
+
+td.parameter-value, td.response-value {
+    padding: 10px;
+    text-align: left;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Parameter name
+ 
----------------------------------------------------------------------------------------------------------*/
+
+.parameter-key .in {
+       font-size: 12px;
+    font-family: monospace;
+    font-weight: bold;
+    font-style: italic;
+    color: gray;
+}
+
+.parameter-key .name {
+       font-size: 14px;
+}
+
+.parameter-key .name.required {
+    font-weight: bold;
+}
+
+.parameter-key .requiredlabel {
+       font-size: 10px;
+    color: rgba(255,0,0,.6);    
+    font-weight: bold;
+}
+
+.parameter-key .type {
+    font-size: 12px;
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Examples
+ 
----------------------------------------------------------------------------------------------------------*/
+ 
+.op-block-contents .example-select {
+    margin: 10px 0 5px 0;
+       border-width: 1px;
+       font-weight:bold;
+    padding: 5px 40px 5px 10px;
+    border: 1px solid #41444e;
+    border-radius: 4px;
+    box-shadow: 0 1px 2px 0 rgba(0,0,0,.25);
+    background: hsla(0,0%,100%,.3);
+}
+
+.op-block-contents .example-select:disabled {
+    color: rgba(0,0,0,.50);
+    border: 1px solid rgba(0,0,0,.50);
+}
+
+.op-block-contents .example {
+    margin: 0;
+    padding: 5px 20px;
+    white-space: pre-wrap;
+    word-wrap: break-word;
+    hyphens: auto;
+    border-radius: 4px;
+    background: #41444e;
+    overflow-wrap: break-word;
+    font-family: monospace;
+    font-weight: 400;
+    color: limegreen;
+       display: none;
+       max-width: 800px;
+       max-height: 800px;
+       text-overflow: auto;
+       overflow: auto;
+}
+
+.op-block-contents .example.active {
+       display:block;
+}
+
+.op-block-contents .model {
+       display: none;
+}
+
+.op-block-contents .model.active {
+       display:block;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Headers
+ 
----------------------------------------------------------------------------------------------------------*/
+
+.section {
+    font-weight: bold;
+    padding: 5px 0;
+    text-align: left;
+}
+
+.headers .name {
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+div.headers {
+       margin: 20px 0px;
+}
+
+.headers .type {
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+.section-name {
+       display: inline-block;
+       vertical-align: top;
+       margin-right: 20px;
+    font-weight: bold;
+    padding: 5px 0;
+    text-align: left;
+}
+
+.section-table {
+/*     display: inline-block;*/
+}
+
+.responses .section-table td {
+       padding: 5px 20px 5px 0px;
+       text-align: left;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+}
diff --git 
a/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/dark.css
 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/dark.css
new file mode 100644
index 0000000..0a34995
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/dark.css
@@ -0,0 +1,285 @@
+/***************************************************************************************************************************
+ * 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.  
                                            *
+ 
***************************************************************************************************************************/
+ 
+/** Dark look-and-feel */ 
+ 
+/**********************************************************************************************************************/
+/**  Body                                                                      
                                      **/
+/**********************************************************************************************************************/
+
+body {
+       background-color: #212121 ;
+       margin: 0px;
+       font-family: HelveticaNeue-Light,"Helvetica Neue Light","Helvetica 
Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
+       color: #EEE;
+       height: 100%;
+}
+
+body {
+       font-size: 14px;
+}
+
+body textarea, body pre {
+       -moz-tab-size: 3; 
+       -o-tab-size: 3; 
+       -webkit-tab-size: 3; 
+       tab-size: 3; 
+}
+
+/**********************************************************************************************************************/
+/**  Header                                                                    
                                    **/
+/**********************************************************************************************************************/
+
+header {
+       background-color: #373a3c;
+}
+
+header * {
+    font-size: 14px;
+       color: #B3B3B3;
+       margin: 0px;
+       text-decoration: none;
+       font-weight: normal;
+}
+
+header h1 {
+       padding: 10px 20px;
+       font-size: 16px;
+       border-bottom: 2px solid #000000;
+       color: white;
+}
+
+header h2 {
+       padding: 10px 20px;
+       font-size: 14px;
+       border-bottom: 2px solid #000000;
+}
+
+/**********************************************************************************************************************/
+/**  Nav                                                                       
                                      **/
+/**********************************************************************************************************************/
+
+nav {
+       margin: 10px 20px 10px 20px;
+       color: #94A3AB;
+}
+
+nav>ol {
+       list-style-type: none;
+       margin: 0px 10px;
+       padding: 0px;
+}
+
+nav>ol>li {
+       display: inline;
+}
+
+nav li:not(:first-child):before {
+       content: " - ";
+}
+
+nav a {
+       font-size: 10pt;
+       color: #94A3AB;
+       text-decoration: none;
+       margin: 0px 15px;
+       text-transform: uppercase;
+       cursor: pointer;
+}
+
+nav a:active, nav a:hover {
+       color: white;
+       text-decoration: underline;
+}
+
+/**********************************************************************************************************************/
+/**  Content                                                                   
                                     **/
+/**********************************************************************************************************************/
+
+section {
+       display: table;
+       width: 100%;
+}
+
+article {
+       display: table-cell;
+}
+
+article * {
+       font-size: 9pt;
+       color: #EEE;
+}
+
+article textarea, article input, article button {
+       color: #111;
+}
+
+article textarea, article input {
+       background-color: #EEE;
+}
+
+article div.data {
+       padding: 10px;
+       background-color: #373a3c;
+       border-radius: 4px;
+       margin: 20px;
+       display: inline-block;
+       box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);
+       font-family: sans-serif;
+}
+
+article table {
+       border: none;
+       width: 100%;
+}
+
+article th {
+       padding: 4px 8px;
+       font-weight: normal;
+       text-align: center;
+       background-color: #0275d8;
+}
+
+article td {
+       vertical-align: top;
+       border-bottom: 1px solid #000000;
+       border-right: 1px solid #000000;
+       padding: 2px 5px;
+}
+
+article td:last-child {
+    width: 100%;
+}
+
+article ul {
+       margin: 0px;
+       padding-left: 20px;
+}
+
+article a {
+       color: #3d8bb5;
+       text-decoration: none;
+}
+
+article a:hover {
+       text-decoration: underline;
+}
+
+article iframe {
+       background-color: #F6F7F9;
+       border: 1px solid gray;
+       padding: 0px;
+       overflow: hidden;
+       width: 100%;
+       min-height: 400px;
+}
+
+aside {
+       display: table-cell;
+       vertical-align: top;
+       padding: 20px 20px;
+}
+
+/**********************************************************************************************************************/
+/**  Footer                                                                    
                                      **/
+/**********************************************************************************************************************/
+
+footer { 
+       padding: 10px;
+       width: 100%;
+       bottom: 0;
+       position: fixed;
+       background-color: #373a3c;
+       border-top: 2px solid #000000;
+}
+
+/**********************************************************************************************************************/
+/**  Popup windows                                                             
                                      **/
+/**********************************************************************************************************************/
+
+.popup-content {
+       display: none;
+       position: absolute;
+       background-color: #DDD;
+       white-space: nowrap;
+       padding: 5px;
+       box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);
+       z-index: 1;
+       margin-top: 10px;
+       border-radius: 4px;
+}
+
+.popup-content * {
+       color: black;
+       font-size: 11px;
+}
+
+.popup-content a:hover {
+       color: #94A3AB;
+}
+
+.popup-show {
+       display:block;
+}
+
+/**********************************************************************************************************************/
+/**  Tooltips                                                                  
                                      **/
+/**********************************************************************************************************************/
+
+.tooltip {
+       position: relative;
+       display: inline-block;      
+}
+
+.tooltip .tooltiptext {
+       visibility: hidden;
+       background-color: #FEF9E7;
+       color: black;
+       padding: 5px;
+       border-radius: 6px;
+       position: absolute;
+       z-index: 1;
+       top: 0;
+       left: 0;
+       margin-left: 30px;
+       box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);
+       opacity: 0;
+       transition: opacity 0.5s;
+       font-weight: normal;
+}
+
+.tooltip .tooltiptext * {
+       color: black;
+}
+
+.tooltip:hover .tooltiptext {
+       visibility: visible;
+       opacity: 1;
+}      
+
+.tooltiptext {
+       white-space: nowrap;
+       float: left;
+       border: 1px solid black;
+}
+
+/**********************************************************************************************************************/
+/**  Other classes                                                             
                                      **/
+/**********************************************************************************************************************/
+
+.table {display:table;}
+.row {display:table-row;}
+.cell {display:table-cell;}
+.monospace {font-family:monospace;}
+.link { color: #94A3AB; text-decoration: none; cursor: pointer;}
+.link:hover { text-decoration: underline; }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/devops.css
 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/devops.css
new file mode 100644
index 0000000..d757a92
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/devops.css
@@ -0,0 +1,275 @@
+/***************************************************************************************************************************
+ * 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.  
                                            *
+ 
***************************************************************************************************************************/
+ 
+/** DevOps look-and-feel */ 
+ 
+/**********************************************************************************************************************/
+/**  Body                                                                      
                                      **/
+/**********************************************************************************************************************/
+
+body {
+       background-color: #3B4B54;
+       margin: 0px;
+       font-family: HelveticaNeue-Light,"Helvetica Neue Light","Helvetica 
Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
+       color: #B3B3B3;
+       height: 100%;   
+}
+
+body {
+       font-size: 14px;
+}
+
+body textarea, body pre {
+       -moz-tab-size: 3; 
+       -o-tab-size: 3; 
+       -webkit-tab-size: 3; 
+       tab-size: 3; 
+}
+
+/**********************************************************************************************************************/
+/**  Header                                                                    
                                    **/
+/**********************************************************************************************************************/
+
+header {
+       background-color: #26343F;
+}
+
+header * {
+    font-size: 14px;
+       color: #B3B3B3;
+       margin: 0px;
+       text-decoration: none;
+       font-weight: normal;
+}
+
+header h1 {
+       padding: 10px 20px;
+       font-size: 16px;
+       border-bottom: 2px solid #34534B;
+       color: white;
+}
+
+header h2 {
+       padding: 10px 20px;
+       font-size: 14px;
+       border-bottom: 2px solid #34534B;
+}
+
+/**********************************************************************************************************************/
+/**  Nav                                                                       
                                      **/
+/**********************************************************************************************************************/
+
+nav {
+       margin: 10px 20px 10px 20px;
+       color: #94A3AB;
+}
+
+nav>ol {
+       list-style-type: none;
+       margin: 0px 10px;
+       padding: 0px;
+}
+
+nav>ol>li {
+       display: inline;
+}
+
+nav li:not(:first-child):before {
+       content: " - ";
+}
+
+nav a {
+       font-size: 10pt;
+       color: #94A3AB;
+       text-decoration: none;
+       margin: 0px 15px;
+       text-transform: uppercase;
+       cursor: pointer;
+}
+
+nav a:active, nav a:hover {
+       color: white;
+       text-decoration: underline;
+}
+
+/**********************************************************************************************************************/
+/**  Content                                                                   
                                     **/
+/**********************************************************************************************************************/
+
+section {
+       display: table;
+       width: 100%;
+}
+
+article {
+       display: table-cell;
+}
+
+article * {
+       font-size: 9pt;
+       color: #26343F;
+}
+
+article div.data {
+       padding: 10px;
+       background-color: white;
+       border-radius: 4px;
+       margin: 20px;
+       display: inline-block;
+       box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);
+       font-family: sans-serif;
+       color: #26343F;
+}
+
+article table {
+       border: none;
+       width: 100%;
+}
+
+article th {
+       border-top: 1px solid #D9DCDE;
+       padding: 4px 8px;
+       font-weight: bold;
+       text-align: center;
+       background-color: #F4F6F9;
+}
+
+article td {
+       vertical-align: top;
+       border-bottom: 1px solid #d9dcde;
+       border-right: 1px solid #d9dcde;
+       padding: 2px 5px;
+}
+
+article td:last-child {
+    width: 100%;
+}
+
+article ul {
+       margin: 0px;
+       padding-left: 20px;
+}
+
+article a {
+       color: #116998;
+       text-decoration: none;
+}
+
+article a:hover {
+       text-decoration: underline;
+}
+
+article iframe {
+       background-color: #F6F7F9;
+       border: 1px solid gray;
+       padding: 0px;
+       overflow: hidden;
+       width: 100%;
+       min-height: 400px;
+}
+
+aside {
+       display: table-cell;
+       vertical-align: top;
+       padding: 20px 20px;
+}
+
+/**********************************************************************************************************************/
+/**  Footer                                                                    
                                      **/
+/**********************************************************************************************************************/
+
+footer { 
+       padding: 10px;
+       width: 100%;
+       bottom: 0;
+       position: fixed;
+       background-color: #26343F;
+}
+
+/**********************************************************************************************************************/
+/**  Popup windows                                                             
                                      **/
+/**********************************************************************************************************************/
+
+.popup-content {
+       display: none;
+       position: absolute;
+       background-color: #f4f6f9;
+       white-space: nowrap;
+       padding: 5px;
+       box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);
+       z-index: 1;
+       margin-top: 10px;
+       border-radius: 4px;
+}
+
+.popup-content * {
+       color: black;
+       font-size: 11px;
+}
+
+.popup-content a:hover {
+       color: #94A3AB;
+}
+
+.popup-show {
+       display:block;
+}
+
+/**********************************************************************************************************************/
+/**  Tooltips                                                                  
                                      **/
+/**********************************************************************************************************************/
+
+.tooltip {
+       position: relative;
+       display: inline-block;      
+}
+
+.tooltip .tooltiptext {
+       visibility: hidden;
+       background-color: #FEF9E7;
+       color: black;
+       padding: 5px;
+       border-radius: 6px;
+       position: absolute;
+       z-index: 1;
+       top: 0;
+       left: 0;
+       margin-left: 30px;
+       box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);
+       opacity: 0;
+       transition: opacity 0.5s;
+       font-weight: normal;
+}
+
+.tooltip:hover .tooltiptext {
+       visibility: visible;
+       opacity: 1;
+}      
+
+.tooltiptext {
+       white-space: nowrap;
+       float: left;
+       border: 1px solid black;
+}
+
+/**********************************************************************************************************************/
+/**  Other classes                                                             
                                      **/
+/**********************************************************************************************************************/
+
+.table {display:table;}
+.row {display:table-row;}
+.cell {display:table-cell;}
+.monospace {font-family:monospace;}
+.link { color: #94A3AB; text-decoration: none; cursor: pointer;}
+.link:hover { text-decoration: underline; }
+
diff --git 
a/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/light.css
 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/light.css
new file mode 100644
index 0000000..3875da3
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/light.css
@@ -0,0 +1,272 @@
+/***************************************************************************************************************************
+ * 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.  
                                            *
+ 
***************************************************************************************************************************/
+ 
+/** Light look-and-feel */ 
+ 
+/**********************************************************************************************************************/
+/**  Body                                                                      
                                      **/
+/**********************************************************************************************************************/
+
+body {
+       margin: 0px;
+       font-size: 10px;
+       font-family: HelveticaNeue-Light,"Helvetica Neue Light","Helvetica 
Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
+       color: #2c4557;
+       height: 100%;   
+}
+
+body * {
+       font-size: 14px;
+}
+
+body textarea, body pre {
+       -moz-tab-size: 3; 
+       -o-tab-size: 3; 
+       -webkit-tab-size: 3; 
+       tab-size: 3; 
+}
+
+/**********************************************************************************************************************/
+/**  Header                                                                    
                                      **/
+/**********************************************************************************************************************/
+
+header {
+       background-color: #e8ebef;
+       padding: 10px 20px;
+       box-shadow: 5px 5px 2px #999999;
+       text-shadow: rgba(1,1,1,.2) 2px 4px 5px, rgba(125,32,191,.05) 0 -10px 
30px;
+       white-space: nowrap;
+}
+
+header * {
+       color: #af2222;;
+       font-weight: lighter;
+}
+
+header h1 {
+       font-size: 18px;
+       margin: 0px;
+       padding: 2px;
+}
+
+header h2 {
+       font-size: 14px;
+       margin: 0px;
+       padding: 2px;
+}
+
+/**********************************************************************************************************************/
+/**  Nav                                                                       
                                      **/
+/**********************************************************************************************************************/
+
+nav {
+       margin: 10px;
+       padding: 5px;
+       box-shadow: 5px 5px 2px #999999;
+       background-color: #eef3f7;
+}
+
+nav * {
+       font-size: 12px;
+       font-weight: lighter;
+}
+
+nav>ol {
+       list-style-type: none;
+       margin: 0px 10px;
+       padding: 0px;
+}
+
+nav>ol>li {
+       display: inline;
+}
+
+nav li:not(:first-child):before {
+       content: " - ";
+}
+
+nav a {
+       font-size: 10pt;
+       color: #2c4557;
+       text-decoration: none;
+       margin: 0px 10px;
+       text-transform: uppercase;
+       cursor: pointer;
+}
+
+nav a:active, nav a:hover {
+       text-decoration: none;
+       color: #94a3ab;
+}
+
+/**********************************************************************************************************************/
+/**  Content                                                                   
                                      **/
+/**********************************************************************************************************************/
+
+section {
+       display: table;
+       width: 100%;
+}
+
+article {
+       display: table-cell;
+       padding: 20px 40px;
+}
+
+article * {
+       font-size: 9pt;
+}
+
+article div.data {
+       padding: 0px;
+       margin: 0px;
+       display: inline-block;
+       font-family: sans-serif;
+}
+
+article table {
+       border: none;
+       width: 100%;
+}
+
+article td {
+       vertical-align: top;
+       border-bottom: 1px solid #d9dcde;
+       border-right: 1px solid #d9dcde;
+       padding: 2px 5px;
+}
+
+article td:last-child {
+    width: 100%;
+}
+
+article th {
+       padding: 4px 8px;
+       text-align: center;
+       background-color: #eef3f7;
+       box-shadow: 1px 1px 2px #999999;
+}
+
+article ul {
+       margin: 0px;
+       padding-left: 20px;
+}
+
+article a {
+       color: #416e8e;
+       text-decoration: none;
+}
+
+article iframe {
+       background-color: #F6F7F9;
+       border: 1px solid gray;
+       padding: 0px;
+       overflow: hidden;
+       width: 100%;
+       min-height: 400px;
+}
+
+aside {
+       display: table-cell;
+       vertical-align: top;
+       padding: 20px 20px;
+}
+
+/**********************************************************************************************************************/
+/**  Footer                                                                    
                                      **/
+/**********************************************************************************************************************/
+
+footer { 
+       padding: 10px;
+       width: 100%;
+       bottom: 0;
+       position: fixed;
+       background-color: #e8ebef;
+}
+
+/**********************************************************************************************************************/
+/**  Popup windows                                                             
                                      **/
+/**********************************************************************************************************************/
+
+.popup-content {
+       display: none;
+       position: absolute;
+       background-color: #eef3f7;
+       white-space: nowrap;
+       padding: 5px;
+       box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);
+       z-index: 1;
+       margin-top: 10px;
+       border-radius: 4px;
+}
+
+.popup-content * {
+       color: #2c4557;
+       font-size: 10pt;
+}
+
+.popup-content a:hover {
+       color: #94A3AB;
+}
+
+.popup-show {
+       display: block;
+}
+
+/**********************************************************************************************************************/
+/**  Tooltips                                                                  
                                      **/
+/**********************************************************************************************************************/
+
+.tooltip {
+       position: relative;
+       display: inline-block;      
+}
+
+.tooltip .tooltiptext {
+       visibility: hidden;
+       background-color: #FEF9E7;
+       color: black;
+       padding: 5px;
+       border-radius: 6px;
+       position: absolute;
+       z-index: 1;
+       top: 0;
+       left: 0;
+       margin-left: 30px;
+       box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);
+       opacity: 0;
+       transition: opacity 0.5s;
+       font-weight: normal;
+}
+
+.tooltip:hover .tooltiptext {
+       visibility: visible;
+       opacity: 1;
+}      
+
+.tooltiptext {
+       white-space: nowrap;
+       float: left;
+       border: 1px solid black;
+}
+
+/**********************************************************************************************************************/
+/**  Other classes                                                             
                                      **/
+/**********************************************************************************************************************/
+
+.table {display:table;}
+.row {display:table-row;}
+.cell {display:table-cell;}
+.monospace {font-family:monospace;}
+.link { color: #94A3AB; text-decoration: none; cursor: pointer;}
+.link:hover { text-decoration: underline; }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/original.css
 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/original.css
new file mode 100644
index 0000000..722feb3
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/main/resources/org/apache/juneau/rest/config/htdocs/themes/original.css
@@ -0,0 +1,236 @@
+/***************************************************************************************************************************
+ * 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.  
                                            *
+ 
***************************************************************************************************************************/
+
+/** Original look-and-feel */ 
+ 
+/**********************************************************************************************************************/
+/**  Body                                                                      
                                      **/
+/**********************************************************************************************************************/
+
+body {
+       background-image: linear-gradient(top, #CDDDDF 0, #EAEDED 20px, #FFFFFF 
70px);
+       background-image: -webkit-linear-gradient(top, #CDDDDF 0, #EAEDED 20px, 
#FFFFFF 70px);
+       background-attachment: fixed;
+       font-family: Sans-Serif;
+       color: #2c4557;
+       height: 100%;
+       margin: 0px;
+}
+
+body * {
+       font-size: 12px;
+}
+
+body textarea, body pre {
+       -moz-tab-size: 3; 
+       -o-tab-size: 3; 
+       -webkit-tab-size: 3; 
+       tab-size: 3; 
+}
+
+/**********************************************************************************************************************/
+/**  Header                                                                    
                                      **/
+/**********************************************************************************************************************/
+
+header {
+       padding: 10px 20px;
+}
+
+header h1 {
+    font-size: 16px;
+       margin-bottom: 10px;
+       margin-right: 40px;
+       padding: 5px 30px;
+       border-radius: 15px;
+       text-decoration: none;
+       font-weight: normal;
+       background: linear-gradient(to bottom, #F5F5F5, #DEE3E9) repeat scroll 
0% 0% transparent;
+       background: -webkit-gradient(linear, left top, left bottom, 
from(#F5F5F5), to(#DEE3E9));
+}
+
+header h2 {
+       font-weight: normal;
+       margin-left: 20px;
+}
+
+/**********************************************************************************************************************/
+/**  Nav                                                                       
                                      **/
+/**********************************************************************************************************************/
+
+nav {
+       margin: 0px 25px;       
+}
+
+nav>ol {
+       list-style-type: none;
+       margin: 0px 10px;
+       padding: 0px;
+}
+
+nav>ol>li {
+       display: inline;
+}
+
+nav li:not(:first-child):before {
+    content: " - ";
+}
+
+nav a {
+       text-decoration: underline;
+       cursor: pointer;
+       color: -webkit-link;
+}
+
+/**********************************************************************************************************************/
+/**  Content                                                                   
                                     **/
+/**********************************************************************************************************************/
+
+section {
+       display: table;
+       width: 100%;
+}
+
+article {
+       display: table-cell;
+       padding: 20px 40px;
+}
+
+aside {
+       display: table-cell;
+       vertical-align: top;
+       padding: 20px 20px;
+}
+
+article div.data {
+       padding: 0px;
+       margin: 0px;
+       display: inline-block;
+       font-family: sans-serif;
+}
+
+article table {
+       border:1px solid #CCCC99;
+       border-collapse: collapse;
+       margin: 5px 0px;
+       width: 100%;
+}
+
+article th {
+       border-top: 1px solid #CCCC99;
+       padding: 3px 5px;
+       color: #666666;
+       text-align: center;
+       background-image: linear-gradient(top, #FBF9E4 0%, #F3F2C2 100%);
+       background-image: -webkit-linear-gradient(top, #FBF9E4 0%, #F3F2C2 
100%);
+}
+
+article td {
+       border: 1px solid #E9EACB;
+       padding: 2px 5px;
+       color: #005C87;
+       vertical-align: top;
+}
+
+article td:last-child {
+    width: 100%;
+}
+
+article ul {
+       margin: 0px;
+       padding-left: 20px;
+}
+
+/**********************************************************************************************************************/
+/**  Footer                                                                    
                                      **/
+/**********************************************************************************************************************/
+
+footer { 
+       display: none;
+}
+
+/**********************************************************************************************************************/
+/**  Popup windows                                                             
                                      **/
+/**********************************************************************************************************************/
+
+.popup-content {
+       display: none;
+       position: absolute;
+       background-color: #eef3f7;
+       white-space: nowrap;
+       padding: 5px;
+       box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);
+       z-index: 1;
+       margin-top: 10px;
+       border-radius: 4px;
+}
+
+.popup-content * {
+       font-size: 9pt;
+}
+
+.popup-content a:hover {
+       color: #94A3AB;
+}
+
+.popup-show {
+       display: block;
+}
+
+/**********************************************************************************************************************/
+/**  Tooltips                                                                  
                                      **/
+/**********************************************************************************************************************/
+
+.tooltip {
+       position: relative;
+       display: inline-block;      
+}
+
+.tooltip .tooltiptext {
+       visibility: hidden;
+       background-color: #FEF9E7;
+       color: black;
+       padding: 5px;
+       border-radius: 6px;
+       position: absolute;
+       z-index: 1;
+       top: 0;
+       left: 0;
+       margin-left: 30px;
+       box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);
+       opacity: 0;
+       transition: opacity 0.5s;
+       font-weight: normal;
+}
+
+.tooltip:hover .tooltiptext {
+       visibility: visible;
+       opacity: 1;
+}      
+
+.tooltiptext {
+       white-space: nowrap;
+       float: left;
+       border: 1px solid black;
+}
+
+/**********************************************************************************************************************/
+/**  Other classes                                                             
                                      **/
+/**********************************************************************************************************************/
+
+.table {display:table;}
+.row {display:table-row;}
+.cell {display:table-cell;}
+.monospace {font-family:monospace;}
+.link { color: #94A3AB; text-decoration: none; cursor: pointer;}
+.link:hover { text-decoration: underline; }
+

Reply via email to