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 19777c5  Improvements to Swagger support.
19777c5 is described below

commit 19777c5a4ad55e1a4cb3d615b258f9a41e88b387
Author: JamesBognar <[email protected]>
AuthorDate: Sun Mar 25 11:14:30 2018 -0400

    Improvements to Swagger support.
---
 .../java/org/apache/juneau/PropertyStoreTest.java  |   7 +-
 .../src/main/java/org/apache/juneau/ClassMeta.java |   9 +
 .../src/main/java/org/apache/juneau/ObjectMap.java |  47 ++
 .../org/apache/juneau/httppart/HttpPartType.java   |   5 +-
 .../java/org/apache/juneau/json/JsonParser.java    |  14 +-
 .../apache/juneau/examples/rest/RootResources.java |   2 +-
 .../examples/{ => rest}/petstore/ApiResponse.java  |   2 +-
 .../examples/{ => rest}/petstore/Category.java     |   2 +-
 .../juneau/examples/{ => rest}/petstore/Order.java |   2 +-
 .../examples/{ => rest}/petstore/OrderStatus.java  |   2 +-
 .../juneau/examples/{ => rest}/petstore/Pet.java   |   2 +-
 .../examples/{ => rest}/petstore/PetStatus.java    |   2 +-
 .../{ => rest}/petstore/PetStoreResource.java      |   2 +-
 .../juneau/examples/{ => rest}/petstore/Tag.java   |   2 +-
 .../juneau/examples/{ => rest}/petstore/User.java  |   2 +-
 .../examples/rest}/petstore/PetStoreResource.json  |   0
 .../org/apache/juneau/rest/BasicRestConfig.java    |   1 +
 .../apache/juneau/rest/BasicRestInfoProvider.java  | 501 +++++++++++++--------
 .../org/apache/juneau/rest/RestJavaMethod.java     |   2 +-
 .../org/apache/juneau/rest/RestParamDefaults.java  |   4 +-
 .../java/org/apache/juneau/rest/RestParamType.java |   2 +-
 .../java/org/apache/juneau/rest/RestRequest.java   |   9 +
 22 files changed, 423 insertions(+), 198 deletions(-)

diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
index 254d17e..c8e6c7d 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
@@ -1584,13 +1584,13 @@ public class PropertyStoreTest {
                        b.removeFrom("A.foo.ss", "[xxx]");
                        fail("Exception expected.");
                } catch (ConfigException e) {
-                       assertTrue(e.getMessage().startsWith("Cannot remove 
value '[xxx]' (String) from property 'foo.ss' (Set<String>).  Invalid input for 
JsonParser parser."));
+                       assertTrue(e.getMessage().startsWith("Cannot remove 
value '[xxx]' (String) from property 'foo.ss' (Set<String>).  Invalid input for 
Simple parser."));
                }
                try {
                        b.removeFrom("A.foo.ls", "[xxx]");
                        fail("Exception expected.");
                } catch (ConfigException e) {
-                       assertTrue(e.getMessage().startsWith("Cannot remove 
value '[xxx]' (String) from property 'foo.ls' (List<String>).  Invalid input 
for JsonParser parser."));
+                       assertTrue(e.getMessage().startsWith("Cannot remove 
value '[xxx]' (String) from property 'foo.ls' (List<String>).  Invalid input 
for Simple parser."));
                }
        }
 
@@ -1601,7 +1601,8 @@ public class PropertyStoreTest {
                        b.addTo("A.foo.sms", "{xxx}");
                        fail("Exception expected.");
                } catch (ConfigException e) {
-                       assertTrue(e.getMessage().startsWith("Cannot add 
'{xxx}' (String) to property 'foo.sms' (Map<String,String>) .  Invalid input 
for JsonParser parser."));
+                       System.err.println(e.getMessage());
+                       assertTrue(e.getMessage().startsWith("Cannot add 
'{xxx}' (String) to property 'foo.sms' (Map<String,String>) .  Invalid input 
for Simple parser."));
                }
                try {
                        b.addTo("A.foo.sms", "xxx");
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
index aaf0fbe..097021a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
@@ -1782,6 +1782,15 @@ public final class ClassMeta<T> implements Type {
                return getReadableClassName(this.innerClass);
        }
 
+       /**
+        * Shortcut for calling {@link Class#getSimpleName()} on the inner 
class of this metadata.
+        * 
+        * @return The simple name of the inner class.
+        */
+       public String getSimpleName() {
+               return innerClass.getSimpleName();
+       }
+       
        private static class LocaleAsString {
                private static Method forLanguageTagMethod;
                static {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
index a41239c..5b7ca6d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
@@ -948,6 +948,23 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
        }
 
        /**
+        * Same as {@link #getObjectMap(String)} but creates a new empty {@link 
ObjectMap} if it doesn't already exist.
+        * 
+        * @param key The key.
+        * @param createIfNotExists If mapping doesn't already exist, create 
one with an empty {@link ObjectMap}.
+        * @return The converted value, or an empty value if the map contains 
no mapping for this key.
+        * @throws InvalidDataConversionException If value cannot be converted.
+        */
+       public ObjectMap getObjectMap(String key, boolean createIfNotExists) {
+               ObjectMap m = getWithDefault(key, null, ObjectMap.class);
+               if (m == null && createIfNotExists) {
+                       m = new ObjectMap();
+                       put(key, m);
+               }
+               return m;
+       }
+
+       /**
         * Returns the specified entry value converted to a {@link ObjectList}.
         * 
         * <p>
@@ -977,6 +994,23 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
        }
 
        /**
+        * Same as {@link #getObjectList(String)} but creates a new empty 
{@link ObjectList} if it doesn't already exist.
+        * 
+        * @param key The key.
+        * @param createIfNotExists If mapping doesn't already exist, create 
one with an empty {@link ObjectList}.
+        * @return The converted value, or an empty value if the map contains 
no mapping for this key.
+        * @throws InvalidDataConversionException If value cannot be converted.
+        */
+       public ObjectList getObjectList(String key, boolean createIfNotExists) {
+               ObjectList m = getWithDefault(key, null, ObjectList.class);
+               if (m == null && createIfNotExists) {
+                       m = new ObjectList();
+                       put(key, m);
+               }
+               return m;
+       }
+
+       /**
         * Returns the first entry that exists converted to a {@link String}.
         * 
         * <p>
@@ -1242,6 +1276,19 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
        }
 
        /**
+        * Adds a mapping if the specified key doesn't exist.
+        * 
+        * @param key The map key.
+        * @param val The value to set if the current value does not exist or 
is <jk>null</jk> or an empty string.
+        * @return This object (for method chaining).
+        */
+       public ObjectMap putIfNotExists(String key, Object val) {
+               if (! containsKey(key))
+                       put(key, val);
+               return this;
+       }
+
+       /**
         * Converts this map into an object of the specified type.
         * 
         * <p>
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartType.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartType.java
index 6df019b..5ab788b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartType.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartType.java
@@ -27,5 +27,8 @@ public enum HttpPartType {
        FORM_DATA,
 
        /** An HTTP header */
-       HEADER
+       HEADER,
+       
+       /** A non-standard field */
+       OTHER;
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
index 5a4bdd3..1efa411 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
@@ -153,7 +153,7 @@ public class JsonParser extends ReaderParser {
        
//-------------------------------------------------------------------------------------------------------------------
 
        /** Default parser, all default settings.*/
-       public static final JsonParser DEFAULT = new 
JsonParser(PropertyStore.DEFAULT);
+       public static final JsonParser DEFAULT = new 
JsonParser.Simple(PropertyStore.DEFAULT);
 
        /** Default parser, all default settings.*/
        public static final JsonParser DEFAULT_STRICT = new 
JsonParser.Strict(PropertyStore.DEFAULT);
@@ -176,6 +176,18 @@ public class JsonParser extends ReaderParser {
                }
        }
 
+       /** Default parser, simple mode. */
+       public static class Simple extends JsonParser {
+
+               /**
+                * Constructor.
+                * 
+                * @param ps The property store containing all the settings for 
this object.
+                */
+               public Simple(PropertyStore ps) {
+                       super(ps, "application/json+simple", 
"text/json+simple");
+               }
+       }
 
        
//-------------------------------------------------------------------------------------------------------------------
        // Instance
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
index 5d2df07..0c2612c 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
@@ -60,7 +60,7 @@ import org.apache.juneau.rest.widget.*;
        children={
                HelloWorldResource.class,
                PetStoreResource.class,
-               org.apache.juneau.examples.petstore.PetStoreResource.class,
+               org.apache.juneau.examples.rest.petstore.PetStoreResource.class,
                SystemPropertiesResource.class,
                MethodExampleResource.class,
                RequestEchoResource.class,
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/ApiResponse.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/ApiResponse.java
similarity index 97%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/ApiResponse.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/ApiResponse.java
index a2a5401..69b2cd4 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/ApiResponse.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/ApiResponse.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 import org.apache.juneau.annotation.*;
 
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Category.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Category.java
similarity index 97%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Category.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Category.java
index e8a48d4..16184d0 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Category.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Category.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 import org.apache.juneau.annotation.*;
 
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Order.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Order.java
similarity index 97%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Order.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Order.java
index 5699c3c..724ce07 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Order.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Order.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 import org.apache.juneau.annotation.*;
 
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/OrderStatus.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/OrderStatus.java
similarity index 96%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/OrderStatus.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/OrderStatus.java
index 774ae77..f8084ab 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/OrderStatus.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/OrderStatus.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 public enum OrderStatus {
        PLACED, APPROVED, DELIVERED;
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Pet.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Pet.java
similarity index 98%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Pet.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Pet.java
index 21c4751..f6b2381 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Pet.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Pet.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 import java.util.*;
 
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/PetStatus.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStatus.java
similarity index 96%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/PetStatus.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStatus.java
index e475bf3..2d2826e 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/PetStatus.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStatus.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 public enum PetStatus {
        AVAILABLE, PENDING, SOLD;
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/PetStoreResource.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java
similarity index 96%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/PetStoreResource.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java
index 9bbfe9b..d10c265 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/PetStoreResource.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 import java.util.*;
 
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Tag.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Tag.java
similarity index 97%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Tag.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Tag.java
index 298b885..fdd9dfc 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/Tag.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Tag.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 import org.apache.juneau.annotation.*;
 
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/User.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/User.java
similarity index 98%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/User.java
rename to 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/User.java
index 05a79e0..d6978cc 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/User.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/User.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.examples.petstore;
+package org.apache.juneau.examples.rest.petstore;
 
 import org.apache.juneau.annotation.*;
 
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/PetStoreResource.json
 
b/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/PetStoreResource.json
similarity index 100%
rename from 
juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/petstore/PetStoreResource.json
rename to 
juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/PetStoreResource.json
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 0ef39f2..52ab465 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
@@ -49,6 +49,7 @@ import org.apache.juneau.xml.*;
        },
        parsers={
                JsonParser.class,
+               JsonParser.Simple.class,
                XmlParser.class,
                HtmlParser.class,
                UonParser.class,
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
index f46c47b..67da8eb 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
@@ -15,6 +15,7 @@ package org.apache.juneau.rest;
 import static org.apache.juneau.internal.ReflectionUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.serializer.WriterSerializer.*;
+import static org.apache.juneau.serializer.OutputStreamSerializer.*;
 
 import java.lang.reflect.Method;
 import java.util.*;
@@ -23,6 +24,7 @@ import java.util.concurrent.*;
 import org.apache.juneau.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
@@ -50,7 +52,7 @@ public class BasicRestInfoProvider implements 
RestInfoProvider {
                siteName,
                title,
                description;
-       private final ConcurrentHashMap<Locale,Swagger> swaggers = new 
ConcurrentHashMap<>();
+       private final 
ConcurrentHashMap<Locale,ConcurrentHashMap<Integer,Swagger>> swaggers = new 
ConcurrentHashMap<>();
 
        /**
         * Constructor.
@@ -99,244 +101,385 @@ public class BasicRestInfoProvider implements 
RestInfoProvider {
         *      <br>Never <jk>null</jk>.
         * @throws Exception
         */
+       @SuppressWarnings("unchecked")
        @Override /* RestInfoProvider */
        public Swagger getSwagger(RestRequest req) throws Exception {
                
                Locale locale = req.getLocale();
                BeanSession bs = req.getBeanSession();
                
-               Swagger s = swaggers.get(locale);
-               if (s != null)
-                       return s;
+               // Find it in the cache.
+               // Swaggers are cached by user locale and an int hash of the 
@RestMethods they have access to.
+               HashCode userHash = HashCode.create();
+               for (RestJavaMethod sm : context.getCallMethods().values())
+                       if (sm.isRequestAllowed(req))
+                               userHash.add(sm.hashCode());
+               int hashCode = userHash.get();
+               
+               if (! swaggers.containsKey(locale))
+                       swaggers.putIfAbsent(locale, new 
ConcurrentHashMap<Integer,Swagger>());
+               
+               Swagger swagger = swaggers.get(locale).get(hashCode);
+               if (swagger != null)
+                       return swagger;
 
+               // Wasn't cached...need to create one.
+               
                VarResolverSession vr = req.getVarResolverSession();
                JsonParser jp = JsonParser.DEFAULT;
                MessageBundle mb = context.getMessages();
+               Class<?> c = context.getResource().getClass();
                
-               ObjectMap om = context.getClasspathResource(ObjectMap.class, 
MediaType.JSON, getClass().getSimpleName() + ".json", locale);
-               if (om == null)
-                       om = new ObjectMap();
+               // Load swagger JSON from classpath.
+               ObjectMap omSwagger = 
context.getClasspathResource(ObjectMap.class, MediaType.JSON, 
getClass().getSimpleName() + ".json", locale);
+               if (omSwagger == null)
+                       omSwagger = new ObjectMap();
                
-               LinkedHashMap<Class<?>,RestResource> 
restResourceAnnotationsParentFirst = 
findAnnotationsMapParentFirst(RestResource.class, 
context.getResource().getClass());
-
-               for (RestResource r : 
restResourceAnnotationsParentFirst.values()) {
+               // Combine it with @RestResource(swagger)
+               for (Map.Entry<Class<?>,RestResource> e : 
findAnnotationsMapParentFirst(RestResource.class, 
context.getResource().getClass()).entrySet()) {
+                       RestResource r = e.getValue();
                        if (r.swagger().length > 0) {
                                try {
-                                       String json = 
vr.resolve(StringUtils.join(r.swagger(), '\n').trim());
-                                       if (! StringUtils.isObjectMap(json, 
true))
+                                       String json = 
vr.resolve(join(r.swagger(), '\n').trim());
+                                       if (! isObjectMap(json, true))
                                                json = "{\n" + json + "\n}";
-                                       om.putAll(new ObjectMap(json));
-                               } catch (ParseException e) {
-                                       throw new ParseException("Malformed 
swagger JSON encountered in @RestResource(swagger) on class 
"+context.getResource().getClass().getName()+".").initCause(e);
+                                       omSwagger.putAll(new ObjectMap(json));
+                               } catch (ParseException x) {
+                                       throw new SwaggerException(x, 
e.getKey(), "Malformed swagger JSON encountered in @RestResource(swagger).");
                                }
                        }
                }
+               
+//             
System.out.println("==============================================================================================");
+//             System.out.println("omSwagger=");
+//             JsonSerializer.DEFAULT_LAX_READABLE.println(omSwagger);
+               
+               ObjectMap 
+                       info = omSwagger.getObjectMap("info", true),
+                       externalDocs = omSwagger.getObjectMap("externalDocs", 
true),
+                       definitions = omSwagger.getObjectMap("definitions", 
true);
+               ObjectList
+                       produces = omSwagger.getObjectList("produces", true),
+                       consumes = omSwagger.getObjectList("consumes", true);
+               
+               String s = this.title;
+               if (s == null)
+                       s = mb.findFirstString(locale, "title");
+               if (s != null) 
+                       info.put("title", vr.resolve(s));
 
-               String title = this.title;
-               if (title == null)
-                       title = mb.findFirstString(locale, "title");
-               if (title != null) 
-                       getInfo(om).put("title", vr.resolve(title));
-
-               String description = this.description;
-               if (description == null)
-                       description = mb.findFirstString(locale, "description");
-               if (description != null) 
-                       getInfo(om).put("description", vr.resolve(description));
+               s = this.description;
+               if (s == null)
+                       s = mb.findFirstString(locale, "description");
+               if (s != null) 
+                       info.put("description", vr.resolve(s));
                
-               String version = mb.findFirstString(locale, "version");
-               if (version != null) 
-                       getInfo(om).put("version", vr.resolve(version));
+               s = mb.findFirstString(locale, "version");
+               if (s != null) 
+                       info.put("version", vr.resolve(s));
                
-               String contact = mb.findFirstString(locale, "contact");
-               if (contact != null) 
-                       getInfo(om).put("contact", 
jp.parse(vr.resolve(contact), ObjectMap.class));
+               s = mb.findFirstString(locale, "contact");
+               if (s != null) 
+                       info.put("contact", jp.parse(vr.resolve(s), 
ObjectMap.class));
                
-               String license = mb.findFirstString(locale, "license");
-               if (license != null) 
-                       getInfo(om).put("license", 
jp.parse(vr.resolve(license), ObjectMap.class));
+               s = mb.findFirstString(locale, "license");
+               if (s != null) 
+                       info.put("license", jp.parse(vr.resolve(s), 
ObjectMap.class));
                
-               String termsOfService = mb.findFirstString(locale, 
"termsOfService");
-               if (termsOfService != null) 
-                       getInfo(om).put("termsOfService", 
vr.resolve(termsOfService));
+               s = mb.findFirstString(locale, "termsOfService");
+               if (s != null) 
+                       info.put("termsOfService", vr.resolve(s));
                
-               if (! om.containsKey("consumes")) {
-                       List<MediaType> consumes = 
req.getContext().getConsumes();
-                       if (! consumes.isEmpty())
-                               om.put("consumes", consumes);
-               }
+               if (consumes.isEmpty()) 
+                       consumes.addAll(req.getContext().getConsumes());
 
-               if (! om.containsKey("produces")) {
-                       List<MediaType> produces = 
req.getContext().getProduces();
-                       if (! produces.isEmpty())
-                               om.put("produces", produces);
+               if (produces.isEmpty()) 
+                       produces.addAll(req.getContext().getProduces());
+               
+               Map<String,ObjectMap> tagMap = new LinkedHashMap<>();
+               if (omSwagger.containsKey("tags")) {
+                       for (ObjectMap om : 
omSwagger.getObjectList("tags").elements(ObjectMap.class)) {
+                               String name = om.getString("name");
+                               if (name == null)
+                                       throw new SwaggerException(c, "Tag 
definition found without name in swagger JSON.");
+                               tagMap.put(name, om);
+                       }
                }
-                       
-               String tags = mb.findFirstString(locale, "tags");
-               if (tags != null)
-                       om.put("tags", jp.parse(vr.resolve(tags), 
ObjectList.class));
-
-               String externalDocs = mb.findFirstString(locale, 
"externalDocs");
-               if (externalDocs != null)
-                       om.put("externalDocs", 
jp.parse(vr.resolve(externalDocs), ObjectMap.class));
                
-               ObjectMap definitions = om.getObjectMap("definitions", new 
ObjectMap());
+               s = mb.findFirstString(locale, "tags");
+               if (s != null) {
+                       for (ObjectMap m : jp.parse(vr.resolve(s), 
ObjectList.class).elements(ObjectMap.class)) {
+                               String name = m.getString("name");
+                               if (name == null)
+                                       throw new SwaggerException(c, "Tag 
definition found without name in resource bundle.");
+                               if (tagMap.containsKey(name))
+                                       tagMap.get(name).putAll(m);
+                               else
+                                       tagMap.put(name, m);
+                       }
+               }
+
+               s = mb.findFirstString(locale, "externalDocs");
+               if (s != null) 
+                       externalDocs.putAll(jp.parse(vr.resolve(s), 
ObjectMap.class));
                
+               // Iterate through all the @RestMethod methods.
                for (RestJavaMethod sm : context.getCallMethods().values()) {
-                       if (sm.isRequestAllowed(req)) {
-                               Method m = sm.method;
-                               RestMethod rm = 
m.getAnnotation(RestMethod.class);
-                               String mn = m.getName(), cn = 
m.getClass().getName();
-                               
-                               ObjectMap mom = getOperation(om, 
sm.getPathPattern(), sm.getHttpMethod().toLowerCase());
-                               
-                               if (rm.swagger().length > 0) {
-                                       try {
-                                               String json = 
vr.resolve(StringUtils.join(rm.swagger(), '\n').trim());
-                                               if (! (json.startsWith("{") && 
json.endsWith("}")))
-                                                       json = "{\n" + json + 
"\n}";
-                                               mom.putAll(new ObjectMap(json));
-                                       } catch (ParseException e) {
-                                               throw new 
ParseException("Malformed swagger JSON encountered in @RestMethod(swagger) on 
method "+mn+" on class "+cn+".").initCause(e);
-                                       }
+                       
+                       // Skip it if user doesn't have access.
+                       if (! sm.isRequestAllowed(req))
+                               continue;
+                       
+                       Method m = sm.method;
+                       RestMethod rm = m.getAnnotation(RestMethod.class);
+                       String mn = m.getName();
+                       
+                       // Get the operation from the existing swagger so far.
+                       ObjectMap op = getOperation(omSwagger, 
sm.getPathPattern(), sm.getHttpMethod().toLowerCase());
+                       
+                       // Add @RestMethod(swagger)
+                       if (rm.swagger().length > 0) {
+                               try {
+                                       String json = 
vr.resolve(join(rm.swagger(), '\n').trim());
+                                       if (! isObjectMap(json, true))
+                                               json = "{\n" + json + "\n}";
+                                       op.putAll(new ObjectMap(json));
+                               } catch (ParseException e) {
+                                       throw new SwaggerException(e, m, 
"Malformed swagger JSON encountered in @RestMethod(swagger).");
                                }
+                       }
 
-                               mom.put("operationId", mn);
-                               
-                               String mDescription = rm.description();
-                               if (mDescription.isEmpty())
-                                       mDescription = 
mb.findFirstString(locale, mn + ".description");
-                               if (mDescription != null)
-                                       mom.put("description", 
vr.resolve(mDescription));
-                               
-                               String mTags = mb.findFirstString(locale, mn + 
".tags");
-                               if (mTags != null) {
-                                       mTags = vr.resolve(mTags);
-                                       if (StringUtils.isObjectList(mTags, 
true)) 
-                                               mom.put("tags", jp.parse(mTags, 
ArrayList.class, String.class));
-                                       else
-                                               mom.put("tags", 
Arrays.asList(StringUtils.split(mTags)));
-                               }
-                               
-                               String mSummary = mb.findFirstString(locale, mn 
+ ".summary");
-                               if (mSummary != null)
-                                       mom.put("summary", 
vr.resolve(mSummary));
+                       op.putIfNotExists("operationId", mn);
+                       
+                       s = rm.description();
+                       if (s.isEmpty())
+                               s = mb.findFirstString(locale, mn + 
".description");
+                       if (s != null)
+                               op.put("description", vr.resolve(s));
 
-                               String mExternalDocs = 
mb.findFirstString(locale, mn + ".externalDocs");
-                               if (mExternalDocs != null) 
-                                       mom.put("externalDocs", 
jp.parse(vr.resolve(s), ObjectMap.class));
-                               
-                               Map<String,ObjectMap> paramMap = new 
LinkedHashMap<>();
+                       Set<String> tags = new LinkedHashSet<>();
+                       if (op.containsKey("tags"))
+                               for (String tag : 
op.getObjectList("tags").elements(String.class)) 
+                                       tags.add(tag);
+                       
+                       s = mb.findFirstString(locale, mn + ".tags");
+                       if (s != null) {
+                               s = vr.resolve(s);
+                               if (isObjectList(s, true))
+                                       tags.addAll((List<String>)jp.parse(s, 
ArrayList.class, String.class));
+                               else
+                                       
tags.addAll(Arrays.asList(StringUtils.split(s)));
+                       }
+                       
+                       for (String tag : tags) 
+                               if (! tagMap.containsKey(tag))
+                                       tagMap.put(tag, new 
ObjectMap().append("name", tag));
+                       
+                       op.put("tags", tags);
+                       
+                       s = mb.findFirstString(locale, mn + ".summary");
+                       if (s != null)
+                               op.put("summary", vr.resolve(s));
 
-                               ObjectList parameters = 
mom.getObjectList("parameters");
-                               if (parameters != null) {
-                                       for (ObjectMap param : 
parameters.elements(ObjectMap.class)) {
-                                               String key = 
param.getString("in") + '.' + param.getString("name");
+                       s = mb.findFirstString(locale, mn + ".externalDocs");
+                       if (s != null) {
+                               ObjectMap eom = jp.parse(vr.resolve(s), 
ObjectMap.class);
+                               if (op.containsKey("externalDocs"))
+                                       
op.getObjectMap("externalDocs").putAll(eom);
+                               else
+                                       op.put("externalDocs", eom);
+                       }
+                       
+                       ObjectMap paramMap = new ObjectMap();
+
+                       ObjectList ol = op.getObjectList("parameters");
+                       if (ol != null) 
+                               for (ObjectMap param : 
ol.elements(ObjectMap.class)) 
+                                       paramMap.put(param.getString("in") + 
'.' + param.getString("name"), param);
+               
+                       s = mb.findFirstString(locale, mn + ".parameters");
+                       if (s != null) {
+                               ol = jp.parse(vr.resolve(s), ObjectList.class);
+                               for (ObjectMap param : 
ol.elements(ObjectMap.class)) {
+                                       String key = param.getString("in") + 
'.' + param.getString("name");
+                                       if (paramMap.containsKey(key))
+                                               
paramMap.getObjectMap(key).putAll(param);
+                                       else
                                                paramMap.put(key, param);
-                                       }
                                }
+                       }
                        
-                               String mParameters = mb.findFirstString(locale, 
mn + ".parameters");
-                               if (mParameters != null) {
-                                       ObjectList ol = 
jp.parse(vr.resolve(mParameters), ObjectList.class);
-                                       for (ObjectMap param : 
ol.elements(ObjectMap.class)) {
-                                               String key = 
param.getString("in") + '.' + param.getString("name");
-                                               if (paramMap.containsKey(key))
-                                                       
paramMap.get(key).putAll(param);
-                                               else
-                                                       paramMap.put(key, 
param);
-                                       }
-                               }
+                       // Finally, look for parameters defined on method.
+                       for (RestParam mp : context.getRestParams(m)) {
                                
-                               // Finally, look for parameters defined on 
method.
-                               for (RestParam mp : context.getRestParams(m)) {
-                                       RestParamType in = mp.getParamType();
-                                       if (in != RestParamType.OTHER) {
-                                               String key = in.toString() + 
'.' + (in == RestParamType.BODY ? null : mp.getName());
-                                               
-                                               if (! paramMap.containsKey(key))
-                                                       paramMap.put(key, new 
ObjectMap());
-                                               ObjectMap param = 
paramMap.get(key);
-                                                       
-                                               param.append("in", in);
-                                               
-                                               if (in != RestParamType.BODY)
-                                                       param.append("name", 
mp.name);
+                               RestParamType in = mp.getParamType();
+                               
+                               if (in == RestParamType.OTHER)
+                                       continue;
+                               
+                               String key = in.toString() + '.' + (in == 
RestParamType.BODY ? null : mp.getName());
+                               
+                               ObjectMap param = paramMap.getObjectMap(key, 
true);
+                                       
+                               param.append("in", in);
+                               
+                               if (in != RestParamType.BODY)
+                                       param.append("name", mp.name);
+                               
+                               if (! param.containsKey("schema")) {
+                                       
+                                       ClassMeta<?> cm = 
bs.getClassMeta(mp.getType());
+                                       
+                                       if (cm.isMapOrBean() || 
cm.isCollectionOrArray()) {
+                                               String name = 
cm.getSimpleName();
                                                
-                                               if (! 
param.containsKey("schema")) {
-                                                       ClassMeta<?> cm = 
bs.getClassMeta(mp.getType());
-                                                       
-                                                       if (cm.isBean()) {
-                                                               String name = 
mp.forClass().getSimpleName();
-                                                               if (! 
definitions.containsKey(name)) {
-                                                                       
ObjectMap definition = JsonSchemaUtils.getSchema(bs, cm);
-                                                                       
-                                                                       Object 
example = cm.getExample(bs);
-                                                                       if 
(example != null) {
-                                                                               
ObjectMap examples = new ObjectMap();
-                                                                               
ObjectMap sprops = new ObjectMap().append(WSERIALIZER_useWhitespace, true);
-                                                                               
for (MediaType mt : req.getParsers().getSupportedMediaTypes()) {
-                                                                               
        if (mt != MediaType.HTML) {
-                                                                               
                Serializer s2 = req.getSerializers().getSerializer(mt);
-                                                                               
                if (s2 != null) {
-                                                                               
                        SerializerSessionArgs args = new 
SerializerSessionArgs(sprops, req.getJavaMethod(), req.getLocale(), null, mt, 
req.getUriContext());
-                                                                               
                        String eVal = 
s2.createSession(args).serializeToString(example);
-                                                                               
                        examples.put(s2.getMediaTypes()[0].toString(), eVal);
-                                                                               
                }
+                                               if (! 
definitions.containsKey(name)) {
+                                                       ObjectMap definition = 
JsonSchemaUtils.getSchema(bs, cm);
+                                                       Object example = 
cm.getExample(bs);
+
+                                                       if (example != null) {
+                                                               ObjectMap 
examples = new ObjectMap();
+                                                               ObjectMap 
sprops = new ObjectMap().append(WSERIALIZER_useWhitespace, 
true).append(OSSERIALIZER_binaryFormat, BinaryFormat.SPACED_HEX);
+                                                               
+                                                               if (in == 
RestParamType.BODY) {
+                                                                       for 
(MediaType mt : req.getParsers().getSupportedMediaTypes()) {
+                                                                               
if (mt != MediaType.HTML) {
+                                                                               
        Serializer s2 = req.getSerializers().getSerializer(mt);
+                                                                               
        if (s2 != null) {
+                                                                               
                SerializerSessionArgs args = new SerializerSessionArgs(sprops, 
req.getJavaMethod(), req.getLocale(), null, mt, req.getUriContext());
+                                                                               
                String eVal = s2.createSession(args).serializeToString(example);
+                                                                               
                examples.put(s2.getMediaTypes()[0].toString(), eVal);
                                                                                
        }
                                                                                
}
-                                                                               
definition.put("x-examples", examples);
                                                                        }
-                                                                       
-                                                                       
definitions.put(name, definition);
+                                                               } else {
+                                                                       
examples.put("example", 
req.getPartSerializer().serialize(HttpPartType.valueOf(in.name()), example));
                                                                }
-                                                               
param.put("schema", new ObjectMap().append("$ref", "#/definitions/" + 
mp.forClass().getSimpleName()));
+                                                               
+                                                               
definition.put("x-examples", examples);
                                                        }
+                                                       
+                                                       definitions.put(name, 
definition);
                                                }
+                                               param.put("schema", new 
ObjectMap().append("$ref", "#/definitions/" + name));
                                        }
                                }
-                               
-                               if (! paramMap.isEmpty())
-                                       mom.put("parameters", 
paramMap.values());
-                               
-                               String mResponses = mb.findFirstString(locale, 
mn + ".responses");
-                               if (mResponses != null) 
-                                       mom.put("responses", 
jp.parse(vr.resolve(mResponses), ObjectMap.class));
+                       }
+                       
+                       if (! paramMap.isEmpty())
+                               op.put("parameters", paramMap.values());
 
-                               if (! mom.containsKey("consumes")) {
-                                       List<MediaType> mConsumes = 
req.getParsers().getSupportedMediaTypes();
-                                       if (! 
mConsumes.equals(om.get("consumes")))
-                                               mom.put("consumes", mConsumes);
+                       ObjectMap responses = op.getObjectMap("responses", 
true);
+                       
+                       s = mb.findFirstString(locale, mn + ".responses");
+                       if (s != null) {
+                               for (Map.Entry<String,Object> e : 
jp.parse(vr.resolve(s), ObjectMap.class).entrySet()) {
+                                       String httpCode = e.getKey();
+                                       if (responses.containsKey(httpCode))
+                                               
responses.getObjectMap(httpCode).putAll((ObjectMap)e.getValue());
+                                       else
+                                               responses.put(httpCode, 
e.getValue());
                                }
-       
-                               if (! mom.containsKey("produces")) {
-                                       List<MediaType> mProduces = 
req.getSerializers().getSupportedMediaTypes();
-                                       if (! 
mProduces.equals(om.get("produces")))
-                                               mom.put("produces", mProduces);
+                       }
+                       
+                       if (! responses.containsKey("200"))
+                               responses.put("200", new 
ObjectMap().append("description", "Success"));
+                       
+                       ObjectMap okResponse = responses.getObjectMap("200");
+                       
+                       ClassMeta<?> cm = bs.getClassMeta(m.getReturnType());
+                       
+                       if ((cm.isMapOrBean() || cm.isCollectionOrArray()) && ! 
okResponse.containsKey("schema") && cm.getInnerClass() != Swagger.class) {
+                               String name = cm.getSimpleName();
+                               
+                               if (! definitions.containsKey(name)) {
+                                       ObjectMap definition;
+                                       try {
+                                               definition = 
JsonSchemaUtils.getSchema(bs, cm);
+                                       } catch (Exception e1) {
+                                               System.err.println(cm);
+                                               throw e1;
+                                       }       
+                                       Object example = cm.getExample(bs);
+                                       
+                                       if (example != null) {
+                                               ObjectMap examples = new 
ObjectMap();
+                                               ObjectMap sprops = new 
ObjectMap().append(WSERIALIZER_useWhitespace, 
true).append(OSSERIALIZER_binaryFormat, BinaryFormat.SPACED_HEX);
+                                               
+                                               for (MediaType mt : 
req.getSerializers().getSupportedMediaTypes()) {
+                                                       if (mt != 
MediaType.HTML) {
+                                                               Serializer s2 = 
req.getSerializers().getSerializer(mt);
+                                                               if (s2 != null) 
{
+                                                                       
SerializerSessionArgs args = new SerializerSessionArgs(sprops, 
req.getJavaMethod(), req.getLocale(), null, mt, req.getUriContext());
+                                                                       String 
eVal = s2.createSession(args).serializeToString(example);
+                                                                       
examples.put(s2.getMediaTypes()[0].toString(), eVal);
+                                                               }
+                                                       }
+                                               }
+                                               definition.put("x-examples", 
examples);
+                                       }
+                                       
+                                       definitions.put(name, definition);
                                }
+                               
+                               okResponse.put("schema", new 
ObjectMap().append("$ref", "#/definitions/" + name));
+                       }                       
+                       
+                       if (responses.isEmpty())
+                               op.remove("responses");
+                       else
+                               op.put("responses", new TreeMap<>(responses));
+                       
+                       if (! op.containsKey("consumes")) {
+                               List<MediaType> mConsumes = 
req.getParsers().getSupportedMediaTypes();
+                               if (! mConsumes.equals(consumes))
+                                       op.put("consumes", mConsumes);
+                       }
+
+                       if (! op.containsKey("produces")) {
+                               List<MediaType> mProduces = 
req.getSerializers().getSupportedMediaTypes();
+                               if (! mProduces.equals(produces))
+                                       op.put("produces", mProduces);
                        }
                }
                
-               if (! definitions.isEmpty())
-                       om.put("definitions", definitions);             
+               if (definitions.isEmpty())
+                       omSwagger.remove("definitions");                
+               if (tagMap.isEmpty())
+                       omSwagger.remove("tags");
                
-               String swaggerJson = 
om.toString(JsonSerializer.DEFAULT_LAX_READABLE);
+               String swaggerJson = 
omSwagger.toString(JsonSerializer.DEFAULT_LAX_READABLE);
                try {
-                       s = jp.parse(swaggerJson, Swagger.class);
+                       swagger = jp.parse(swaggerJson, Swagger.class);
                } catch (Exception e) {
-                       throw new RestServletException("Error detected in 
swagger: \n{0}", StringUtils.addLineNumbers(swaggerJson)).initCause(e);
+                       throw new RestServletException("Error detected in 
swagger: \n{0}", addLineNumbers(swaggerJson)).initCause(e);
                }
-               swaggers.put(locale, s);
                
-               return s;
+               swaggers.get(locale).put(hashCode, swagger);
+               
+//             
System.out.println("==============================================================================================");
+//             System.out.println("swagger=");
+//             JsonSerializer.DEFAULT_LAX_READABLE.println(swagger);
+               
+               return swagger;
        }
        
-       private ObjectMap getInfo(ObjectMap om) {
-               if (! om.containsKey("info"))
-                       om.put("info", new ObjectMap());
-               return om.getObjectMap("info");
+       private static class SwaggerException extends ParseException {
+               private static final long serialVersionUID = 1L;
+               
+               SwaggerException(Class<?> c, String message, Object...args) {
+                       this(null, c, message, args);
+               }
+               SwaggerException(Exception e, Class<?> c, String message, 
Object...args) {
+                       super("Swagger exception on class " + c.getName() + ".  
" + message, args);
+                       initCause(e);
+               }
+               SwaggerException(Exception e, Method m, String message, 
Object...args) {
+                       super("Swagger exception on class " + 
m.getDeclaringClass().getName() + " method "+m.getName()+".  " + message, args);
+                       initCause(e);
+               }
        }
-
+       
        private ObjectMap getOperation(ObjectMap om, String path, String 
httpMethod) {
                if (! om.containsKey("paths"))
                        om.put("paths", new ObjectMap());
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
index 1229aa4..390e3e6 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
@@ -577,7 +577,7 @@ public class RestJavaMethod implements 
Comparable<RestJavaMethod>  {
 
        @Override /* Object */
        public int hashCode() {
-               return super.hashCode();
+               return method.hashCode();
        }
        
        static String[] resolveVars(VarResolver vr, String[] in) {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
index 26635e5..0fe47c3 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
@@ -598,7 +598,7 @@ class RestParamDefaults {
                private final HttpPartParser partParser;
 
                protected FormDataObject(Method method, FormData a, Type type, 
PropertyStore ps) throws ServletException {
-                       super(FORMDATA, firstNonEmpty(a.name(), a.value()), 
type);
+                       super(FORM_DATA, firstNonEmpty(a.name(), a.value()), 
type);
                        if (a.multipart() && ! isCollection(type))
                                        throw new RestServletException("Use of 
multipart flag on @FormData parameter that's not an array or Collection on 
method ''{0}''", method);
                        this.multiPart = a.multipart();
@@ -636,7 +636,7 @@ class RestParamDefaults {
        static final class HasFormDataObject extends RestParam {
 
                protected HasFormDataObject(Method method, HasFormData a, Type 
type) throws ServletException {
-                       super(FORMDATA, firstNonEmpty(a.name(), a.value()), 
type);
+                       super(FORM_DATA, firstNonEmpty(a.name(), a.value()), 
type);
                        if (type != Boolean.class && type != boolean.class)
                                throw new RestServletException("Use of @HasForm 
annotation on parameter that is not a boolean on method ''{0}''", method);
        }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java
index 1cb8a21..ff913c5 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java
@@ -29,7 +29,7 @@ public enum RestParamType {
        HEADER("header"),
 
        /** Form data entry */
-       FORMDATA("formData"),
+       FORM_DATA("formData"),
 
        /** Query parameter */
        QUERY("query"),
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
index 1fbbe03..f134546 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -34,6 +34,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.config.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.rest.annotation.*;
@@ -1048,6 +1049,14 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                return restJavaMethod.parsers;
        }
 
+       /**
+        * Returns the part serializer associated with this request.
+        * 
+        * @return The part serializer associated with this request.
+        */
+       public HttpPartSerializer getPartSerializer() {
+               return restJavaMethod.partSerializer;
+       }
 
        /**
         * Returns the method of this request.

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

Reply via email to