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 1a3a0e4  Swagger UI tests.
1a3a0e4 is described below

commit 1a3a0e4a96819a30a4b4d10019724558787bca95
Author: JamesBognar <[email protected]>
AuthorDate: Sat Apr 28 19:38:43 2018 -0400

    Swagger UI tests.
---
 .../main/java/org/apache/juneau/BeanSession.java   |   2 +
 .../main/java/org/apache/juneau/ObjectList.java    |  37 ++-
 .../src/main/java/org/apache/juneau/ObjectMap.java |  60 +++--
 .../apache/juneau/rest/BasicRestInfoProvider.java  |  50 ++--
 .../juneau/rest/annotation/MethodSwagger.java      |  10 +-
 .../juneau/rest/BasicRestInfoProviderTest.java     | 263 ++++++++++++++++++++-
 .../rest/BasicRestInfoProviderTest_swagger.json    | 161 ++++++++++++-
 7 files changed, 503 insertions(+), 80 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index 460f4cc..e518e49 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -534,6 +534,7 @@ public class BeanSession extends Session {
                                                return (T)m;
                                        } else if 
(!type.canCreateNewInstanceFromString(outer)) {
                                                ObjectMap m = new 
ObjectMap(value.toString());
+                                               m.setBeanSession(this);
                                                return 
convertToMemberType(outer, m, type);
                                        }
                                } catch (Exception e) {
@@ -559,6 +560,7 @@ public class BeanSession extends Session {
                                                String s = value.toString();
                                                if (isObjectList(s, false)) {
                                                        ObjectList l2 = new 
ObjectList(s);
+                                                       l2.setBeanSession(this);
                                                        for (Object o : l2)
                                                                
l.add(elementType.isObject() ? o : convertToMemberType(l, o, elementType));
                                                } else {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectList.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectList.java
index a7ebbd1..cec754d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectList.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectList.java
@@ -141,11 +141,11 @@ public class ObjectList extends LinkedList<Object> {
         * @throws ParseException If the input contains a syntax error or is 
malformed.
         */
        public ObjectList(CharSequence s, Parser p) throws ParseException {
-               this(p == null ? BeanContext.DEFAULT.createSession() : 
p.createBeanSession());
+               this(p == null ? null : p.createBeanSession());
                if (p == null)
                        p = JsonParser.DEFAULT;
                if (s != null)
-                       p.parseIntoCollection(s, this, session.object());
+                       p.parseIntoCollection(s, this, bs().object());
        }
 
        /**
@@ -169,7 +169,7 @@ public class ObjectList extends LinkedList<Object> {
         * @throws IOException If a problem occurred trying to read from the 
reader.
         */
        public ObjectList(Reader r, Parser p) throws ParseException, 
IOException {
-               this(p == null ? BeanContext.DEFAULT.createSession() : 
p.createBeanSession());
+               this(p == null ? null : p.createBeanSession());
                parseReader(r, p);
        }
 
@@ -183,21 +183,19 @@ public class ObjectList extends LinkedList<Object> {
         * @throws IOException If a problem occurred trying to read from the 
reader.
         */
        public ObjectList(Reader r) throws ParseException, IOException {
-               this(BeanContext.DEFAULT.createSession());
                parseReader(r, JsonParser.DEFAULT);
        }
 
        private void parseReader(Reader r, Parser p) throws ParseException {
                if (p == null)
                        p = JsonParser.DEFAULT;
-               p.parseIntoCollection(r, this, session.object());
+               p.parseIntoCollection(r, this, bs().object());
        }
 
        /**
         * Construct an empty JSON array. (i.e. an empty {@link LinkedList}).
         */
        public ObjectList() {
-               this(BeanContext.DEFAULT.createSession());
        }
 
        /**
@@ -246,6 +244,15 @@ public class ObjectList extends LinkedList<Object> {
        }
 
        /**
+        * Returns the {@link BeanSession} currently associated with this list.
+        * 
+        * @return The {@link BeanSession} currently associated with this list.
+        */
+       public BeanSession getBeanSession() {
+               return session;
+       }
+
+       /**
         * Convenience method for adding multiple objects to this list.
         * 
         * @param o The objects to add to the list.
@@ -324,7 +331,7 @@ public class ObjectList extends LinkedList<Object> {
         * @return The converted entry.
         */
        public <T> T get(int index, Class<T> type) {
-               return session.convertToType(get(index), type);
+               return bs().convertToType(get(index), type);
        }
 
        /**
@@ -372,7 +379,7 @@ public class ObjectList extends LinkedList<Object> {
         * @return The converted entry.
         */
        public <T> T get(int index, Type type, Type...args) {
-               return session.convertToType(get(index), type, args);
+               return bs().convertToType(get(index), type, args);
        }
 
        /**
@@ -439,7 +446,7 @@ public class ObjectList extends LinkedList<Object> {
         * @throws InvalidDataConversionException If value cannot be converted.
         */
        public <K,V> Map<K,V> getMap(int index, Class<K> keyType, Class<V> 
valType) {
-               return session.convertToType(get(index), Map.class, keyType, 
valType);
+               return bs().convertToType(get(index), Map.class, keyType, 
valType);
        }
 
        /**
@@ -462,7 +469,7 @@ public class ObjectList extends LinkedList<Object> {
         * @throws InvalidDataConversionException If value cannot be converted.
         */
        public <E> List<E> getList(int index, Class<E> elementType) {
-               return session.convertToType(get(index), List.class, 
elementType);
+               return bs().convertToType(get(index), List.class, elementType);
        }
 
        /**
@@ -671,7 +678,7 @@ public class ObjectList extends LinkedList<Object> {
 
                                        @Override /* Iterator */
                                        public E next() {
-                                               return 
session.convertToType(i.next(), childType);
+                                               return 
bs().convertToType(i.next(), childType);
                                        }
 
                                        @Override /* Iterator */
@@ -691,7 +698,7 @@ public class ObjectList extends LinkedList<Object> {
         * @return The data type of the object at the specified index, or 
<jk>null</jk> if the value is null.
         */
        public ClassMeta<?> getClassMeta(int index) {
-               return session.getClassMetaForObject(get(index));
+               return bs().getClassMetaForObject(get(index));
        }
 
        private PojoRest getPojoRest() {
@@ -751,4 +758,10 @@ public class ObjectList extends LinkedList<Object> {
                        throw new RuntimeException(e);
                }
        }
+       
+       BeanSession bs() {
+               if (session == null)
+                       session = BeanContext.DEFAULT.createBeanSession();
+               return session;
+       }
 }
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 f0484dd..8670176 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
@@ -149,11 +149,11 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
         * @throws ParseException If the input contains a syntax error or is 
malformed.
         */
        public ObjectMap(CharSequence s, Parser p) throws ParseException {
-               this(p == null ? BeanContext.DEFAULT.createSession() : 
p.createBeanSession());
+               this(p == null ? null : p.createBeanSession());
                if (p == null)
                        p = JsonParser.DEFAULT;
                if (! StringUtils.isEmpty(s))
-                       p.parseIntoMap(s, this, session.string(), 
session.object());
+                       p.parseIntoMap(s, this, bs().string(), bs().object());
        }
 
        /**
@@ -175,7 +175,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> 
{
         * @throws IOException If a problem occurred trying to read from the 
reader.
         */
        public ObjectMap(Reader r, Parser p) throws ParseException, IOException 
{
-               this(p == null ? BeanContext.DEFAULT.createSession() : 
p.createBeanSession());
+               this(p == null ? null : p.createBeanSession());
                parseReader(r, p);
        }
 
@@ -187,21 +187,19 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
         * @throws IOException If a problem occurred trying to read from the 
reader.
         */
        public ObjectMap(Reader r) throws ParseException, IOException {
-               this(BeanContext.DEFAULT.createSession());
                parseReader(r, JsonParser.DEFAULT);
        }
 
        private void parseReader(Reader r, Parser p) throws ParseException {
                if (p == null)
                        p = JsonParser.DEFAULT;
-               p.parseIntoMap(r, this, session.string(), session.object());
+               p.parseIntoMap(r, this, bs().string(), bs().object());
        }
 
        /**
         * Construct an empty JSON object (i.e. an empty {@link LinkedHashMap}).
         */
        public ObjectMap() {
-               this(BeanContext.DEFAULT.createSession());
        }
 
        /**
@@ -518,7 +516,10 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
         * @return The value, or <jk>null</jk> if the entry doesn't exist.
         */
        public <T> T getWithDefault(String key, T def, Type type, Type...args) {
-               T t = session.convertToType(get(key), type, args);
+               Object o = get(key);
+               if (o == null)
+                       return def;
+               T t = bs().convertToType(o, type, args);
                return t == null ? def : t;
        }
 
@@ -540,7 +541,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> 
{
                        if (o == null)
                                return null;
                        PojoSwap swap = pojoSwap;
-                       return (T)swap.unswap(session, o, null);
+                       return (T)swap.unswap(bs(), o, null);
                } catch (ParseException e) {
                        throw e;
                } catch (Exception e) {
@@ -925,7 +926,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> 
{
                Object o = get(key);
                if (o == null)
                        return def;
-               return session.convertToType(o, Map.class, keyType, valType);
+               return bs().convertToType(o, Map.class, keyType, valType);
        }
 
        /**
@@ -970,7 +971,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> 
{
                Object o = get(key);
                if (o == null)
                        return def;
-               return session.convertToType(o, List.class, elementType);
+               return bs().convertToType(o, List.class, elementType);
        }
 
        /**
@@ -1209,7 +1210,7 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
         *      The data type of the object at the specified key, or 
<jk>null</jk> if the value is null or does not exist.
         */
        public ClassMeta<?> getClassMeta(String key) {
-               return session.getClassMetaForObject(get(key));
+               return bs().getClassMetaForObject(get(key));
        }
 
        /**
@@ -1375,9 +1376,10 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
         */
        @SuppressWarnings("unchecked")
        public <T> T cast(Class<T> type) {
-               ClassMeta<?> c2 = session.getClassMeta(type);
-               String typePropertyName = session.getBeanTypePropertyName(c2);
-               ClassMeta<?> c1 = 
session.getBeanRegistry().getClassMeta((String)get(typePropertyName));
+               BeanSession bs = bs();
+               ClassMeta<?> c2 = bs.getClassMeta(type);
+               String typePropertyName = bs.getBeanTypePropertyName(c2);
+               ClassMeta<?> c1 = 
bs.getBeanRegistry().getClassMeta((String)get(typePropertyName));
                ClassMeta<?> c = c1 == null ? c2 : narrowClassMeta(c1, c2);
                if (c.isObject())
                        return (T)this;
@@ -1395,7 +1397,8 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
         */
        @SuppressWarnings({"unchecked"})
        public <T> T cast(ClassMeta<T> cm) {
-               ClassMeta<?> c1 = 
session.getBeanRegistry().getClassMeta((String)get(session.getBeanTypePropertyName(cm)));
+               BeanSession bs = bs();
+               ClassMeta<?> c1 = 
bs.getBeanRegistry().getClassMeta((String)get(bs.getBeanTypePropertyName(cm)));
                ClassMeta<?> c = narrowClassMeta(c1, cm);
                return (T)cast2(c);
        }
@@ -1413,11 +1416,11 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
                if (c1.isMap()) {
                        ClassMeta<?> k = getNarrowedClassMeta(c1.getKeyType(), 
c2.getKeyType());
                        ClassMeta<?> v = 
getNarrowedClassMeta(c1.getValueType(), c2.getValueType());
-                       return session.getClassMeta(c.getInnerClass(), k, v);
+                       return bs().getClassMeta(c.getInnerClass(), k, v);
                }
                if (c1.isCollection()) {
                        ClassMeta<?> e = 
getNarrowedClassMeta(c1.getElementType(), c2.getElementType());
-                       return session.getClassMeta(c.getInnerClass(), e);
+                       return bs().getClassMeta(c.getInnerClass(), e);
                }
                return c;
        }
@@ -1438,23 +1441,24 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
        @SuppressWarnings({"unchecked","rawtypes"})
        private <T> T cast2(ClassMeta<T> cm) {
 
+               BeanSession bs = bs();
                try {
                        Object value = get("value");
 
                        if (cm.isMap()) {
-                               Map m2 = (cm.canCreateNewInstance() ? 
(Map)cm.newInstance() : new ObjectMap(session));
+                               Map m2 = (cm.canCreateNewInstance() ? 
(Map)cm.newInstance() : new ObjectMap(bs));
                                ClassMeta<?> kType = cm.getKeyType(), vType = 
cm.getValueType();
                                for (Map.Entry<String,Object> e : entrySet()) {
                                        Object k = e.getKey();
                                        Object v = e.getValue();
-                                       if (! 
k.equals(session.getBeanTypePropertyName(cm))) {
+                                       if (! 
k.equals(bs.getBeanTypePropertyName(cm))) {
 
                                                // Attempt to recursively cast 
child maps.
                                                if (v instanceof ObjectMap)
                                                        v = 
((ObjectMap)v).cast(vType);
 
-                                               k = (kType.isString() ? k : 
session.convertToType(k, kType));
-                                               v = (vType.isObject() ? v : 
session.convertToType(v, vType));
+                                               k = (kType.isString() ? k : 
bs.convertToType(k, kType));
+                                               v = (vType.isObject() ? v : 
bs.convertToType(v, vType));
 
                                                m2.put(k, v);
                                        }
@@ -1462,13 +1466,13 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
                                return (T)m2;
 
                        } else if (cm.isBean()) {
-                               BeanMap<? extends T> bm = 
session.newBeanMap(cm.getInnerClass());
+                               BeanMap<? extends T> bm = 
bs.newBeanMap(cm.getInnerClass());
 
                                // Iterate through all the entries in the map 
and set the individual field values.
                                for (Map.Entry<String,Object> e : entrySet()) {
                                        String k = e.getKey();
                                        Object v = e.getValue();
-                                       if (! 
k.equals(session.getBeanTypePropertyName(cm))) {
+                                       if (! 
k.equals(bs.getBeanTypePropertyName(cm))) {
 
                                                // Attempt to recursively cast 
child maps.
                                                if (v instanceof ObjectMap)
@@ -1482,10 +1486,10 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
 
                        } else if (cm.isCollectionOrArray()) {
                                List items = (List)get("items");
-                               return session.convertToType(items, cm);
+                               return bs.convertToType(items, cm);
 
                        } else if (value != null) {
-                               return session.convertToType(value, cm);
+                               return bs.convertToType(value, cm);
                        }
 
                } catch (Exception e) {
@@ -1606,4 +1610,10 @@ public class ObjectMap extends 
LinkedHashMap<String,Object> {
                        }
                };
        }
+       
+       private BeanSession bs() {
+               if (session == null)
+                       session = BeanContext.DEFAULT.createBeanSession();
+               return session;
+       }
 }
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 80cc9d8..55ed686 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
@@ -277,20 +277,20 @@ public class BasicRestInfoProvider implements 
RestInfoProvider {
                        MethodSwagger ms = rm.swagger();
 
                        op.putAll(parseMap(joinnl(ms.value()), vr, true, false, 
"@MethodSwagger(value) on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "operationId", 
vr.resolve(ms.operationId()));
                        op.appendIf(true, true, true, "summary", 
vr.resolve(rm.summary()));
                        op.appendIf(true, true, true, "summary", 
vr.resolve(joinnl(ms.summary())));
                        op.appendIf(true, true, true, "description", 
vr.resolve(joinnl(rm.description())));
                        op.appendIf(true, true, true, "description", 
vr.resolve(joinnl(ms.description())));
                        op.appendIf(true, true, true, "deprecated", 
vr.resolve(ms.deprecated()));
                        op.appendIf(true, true, true, "externalDocs", 
parseMap(joinnl(ms.externalDocs()), vr, false, true, 
"@MethodSwagger(externalDocs) on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "tags", 
parseListOrCdl(joinnl(ms.tags()), vr, false, true, "@MethodSwagger(tags) on 
class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "schemes", 
parseListOrCdl(joinnl(ms.schemes()), vr, false, true, "@MethodSwagger(schemes) 
on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "consumes", 
parseListOrCdl(joinnl(ms.consumes()), vr, false, true, 
"@MethodSwagger(consumes) on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "produces", 
parseListOrCdl(joinnl(ms.produces()), vr, false, true, 
"@MethodSwagger(produces) on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "parameters", 
parseList(joinnl(ms.parameters()), vr, false, true, "@MethodSwagger(parameters) 
on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "responses", 
parseMap(joinnl(ms.responses()), vr, false, true, "@MethodSwagger(responses) on 
class {0} method {1}", c, m));
                        
-                       if (ms.parameters().length > 0)
-                               op.getObjectList("parameters", 
true).addAll(parseList(joinnl(ms.parameters()), vr, false, false, 
"@MethodSwagger(parameters) on class {0} method {1}", c, m));
-                       if (ms.responses().length > 0)
-                               op.getObjectMap("responses", 
true).putAll(parseMap(joinnl(ms.responses()), vr, false, false, 
"@MethodSwagger(responses) on class {0} method {1}", c, m));
-                       if (ms.tags().length > 0)
-                               op.getObjectList("tags", 
true).addAll(parseListOrCdl(joinnl(ms.tags()), vr, false, false, 
"@MethodSwagger(tags) on class {0} method {1}", c, m));
-
                        op.putIfNotExists("operationId", mn);
                        
                        if (m.getAnnotation(Deprecated.class) != null)
@@ -298,27 +298,22 @@ public class BasicRestInfoProvider implements 
RestInfoProvider {
 
                        op.appendIf(true, true, true, "summary", 
vr.resolve(mb.findFirstString(locale, mn + ".summary")));
                        op.appendIf(true, true, true, "description", 
vr.resolve(mb.findFirstString(locale, mn + ".description")));
+                       op.appendIf(true, true, true, "externalDocs", 
parseMap(mb.findFirstString(locale, mn + ".description"), vr, false, true, 
"Messages/externalDocs on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "tags", 
parseListOrCdl(mb.findFirstString(locale, mn + ".tags"), vr, false, true, 
"Messages/tags on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "schemes", 
parseListOrCdl(mb.findFirstString(locale, mn + ".schemes"), vr, false, true, 
"Messages/schemes on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "consumes", 
parseListOrCdl(mb.findFirstString(locale, mn + ".consumes"), vr, false, true, 
"Messages/consumes on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "produces", 
parseListOrCdl(mb.findFirstString(locale, mn + ".produces"), vr, false, true, 
"Messages/produces on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "parameters", 
parseList(mb.findFirstString(locale, mn + ".parameters"), vr, false, true, 
"Messages/parameters on class {0} method {1}", c, m));
+                       op.appendIf(true, true, true, "responses", 
parseMap(mb.findFirstString(locale, mn + ".responses"), vr, false, true, 
"Messages/responses on class {0} method {1}", c, m));
 
-                       s = mb.findFirstString(locale, mn + ".tags");
-                       if (s != null) 
-                               op.getObjectList("tags", 
true).addAll(parseListOrCdl(s, vr, false, false, "Messages/tags on class {0} 
method {1}", c, m));
-                       
                        if (op.containsKey("tags"))
                                for (String tag : 
op.getObjectList("tags").elements(String.class)) 
                                        if (! tagMap.containsKey(tag))
                                                tagMap.put(tag, new 
ObjectMap().append("name", tag));
                        
-                       op.appendIf(true, true, true, "externalDocs", 
parseMap(mb.findFirstString(locale, mn + ".description"), vr, false, true, 
"Messages/externalDocs on class {0} method {1}", c, m));
-                       
-                       s = mb.findFirstString(locale, mn + ".parameters");
-                       if (s != null) 
-                               op.getObjectList("parameters", 
true).addAll(parseList(s, vr, false, false, "Messages/parameters on class {0} 
method {1}", c, m));
-
                        ObjectMap paramMap = new ObjectMap();
-
-                       ObjectList ol = op.getObjectList("parameters");
-                       if (ol != null) 
-                               for (ObjectMap param : 
ol.elements(ObjectMap.class)) 
+                       if (op.containsKey("parameters"))
+                               for (ObjectMap param : 
op.getObjectList("parameters").elements(ObjectMap.class)) 
                                        paramMap.put(param.getString("in") + 
'.' + param.getString("name"), param);
                
                        // Finally, look for parameters defined on method.
@@ -374,18 +369,7 @@ public class BasicRestInfoProvider implements 
RestInfoProvider {
                                op.put("parameters", paramMap.values());
 
                        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());
-                               }
-                       }
-                       
+                                               
                        // Gather responses from @Response-annotated exceptions.
                        for (RestMethodThrown rt : 
context.getRestMethodThrowns(m)) {
                                int code = rt.getCode();
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
index 496a5c0..10efb2f 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
@@ -84,6 +84,10 @@ public @interface MethodSwagger {
        
        String[] description() default {};
 
+       String operationId() default "";
+       
+       String[] schemes() default {};
+       
        /**
         * Optional deprecated flag for the exposed API.
         * 
@@ -106,6 +110,10 @@ public @interface MethodSwagger {
         * </ul>
         */
        String deprecated() default "";
+       
+       String[] consumes() default {};
+       
+       String[] produces() default {};
 
        /**
         * Optional external documentation information for the exposed API.
@@ -241,5 +249,5 @@ public @interface MethodSwagger {
         *              Corresponds to the swagger field 
<code>/paths/{path}/{method}/tags</code>.
         * </ul>
         */
-       String[] tags() default "";
+       String[] tags() default {};
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
index 626ae73..7fd0152 100644
--- 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
@@ -14,10 +14,12 @@ package org.apache.juneau.rest;
 
 import static org.junit.Assert.assertEquals;
 import static org.apache.juneau.rest.TestUtils.*;
+import static org.apache.juneau.http.HttpMethodName.*;
 
 import java.io.*;
 import java.util.*;
 
+import org.apache.juneau.annotation.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.util.*;
@@ -713,7 +715,266 @@ public class BasicRestInfoProviderTest {
        }
        
        
//-----------------------------------------------------------------------------------------------------------------
-       // /paths/<path>/<method>/tags
+       // /paths/<path>/<method>
        
//-----------------------------------------------------------------------------------------------------------------
+
+       @RestResource()
+       public static class M01 {
+               
+               @RestMethod(name=GET,path="/path/{foo}")
+               public Foo doFoo() {
+                       return null;
+               }
+       }
        
+       @Test
+       public void m01_operation_default() throws Exception {
+               
assertObjectEquals("{operationId:'doFoo',responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}}}",
 getSwagger(new M01()).getPaths().get("/path/{foo}").get("get"));
+               
assertObjectEquals("{operationId:'s-operationId',summary:'s-summary',description:'s-description',tags:['s-tag'],externalDocs:{description:'s-description',url:'s-url'},consumes:['s-consumes'],produces:['s-produces'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['s-scheme'],deprecated:true}",
 getSwaggerWithFile(new M01()).getPaths().get("/path/{foo}").get("get"));
+       }
+
+       
@RestResource(swagger=@ResourceSwagger("{paths:{'/path/{foo}':{get:{summary:'a-summary',description:'a-description',operationId:'a-operationId',deprecated:true,consumes:['a-consumes'],produces:['a-produces'],tags:['a-tag'],schemes:['a-scheme'],externalDocs:{description:
 'a-description',url: 'a-url'}}}}}"))
+       public static class M02 {               
+               @RestMethod(name=GET,path="/path/{foo}")
+               public Foo doFoo() {
+                       return null;
+               }
+       }
+       
+       @Test
+       public void m02_operation_swaggerOnClass() throws Exception {
+               
assertObjectEquals("{operationId:'a-operationId',summary:'a-summary',description:'a-description',tags:['a-tag'],externalDocs:{description:'a-description',url:'a-url'},consumes:['a-consumes'],produces:['a-produces'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['a-scheme'],deprecated:true}",
 getSwagger(new M02()).getPaths().get("/path/{foo}").get("get"));
+               
assertObjectEquals("{operationId:'a-operationId',summary:'a-summary',description:'a-description',tags:['a-tag'],externalDocs:{description:'a-description',url:'a-url'},consumes:['a-consumes'],produces:['a-produces'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['a-scheme'],deprecated:true}",
 getSwaggerWithFile(new M02()).getPaths().get("/path/{foo}").get("get"));
+       }
+
+       
@RestResource(swagger=@ResourceSwagger("{paths:{'/path/{foo}':{get:{summary:'a-summary',description:'a-description',operationId:'a-operationId',deprecated:true,consumes:['a-consumes'],produces:['a-produces'],tags:['a-tag'],schemes:['a-scheme'],externalDocs:{description:'a-description',url:'a-url'}}}}}"))
+       public static class M03 {               
+               
@RestMethod(name=GET,path="/path/{foo}",swagger=@MethodSwagger("summary:'b-summary',description:'b-description',operationId:'b-operationId',deprecated:false,consumes:['b-consumes'],produces:['b-produces'],tags:['b-tag'],schemes:['b-scheme'],externalDocs:{description:'b-description',url:'b-url'}}"))
+               public Foo doFoo() {
+                       return null;
+               }
+       }
+       
+       @Test
+       public void m03_operation_swaggerOnMethod() throws Exception {
+               
assertObjectEquals("{operationId:'b-operationId',summary:'b-summary',description:'b-description',tags:['b-tag'],externalDocs:{description:'b-description',url:'b-url'},consumes:['b-consumes'],produces:['b-produces'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['b-scheme'],deprecated:false}",
 getSwagger(new M03()).getPaths().get("/path/{foo}").get("get"));
+               
assertObjectEquals("{operationId:'b-operationId',summary:'b-summary',description:'b-description',tags:['b-tag'],externalDocs:{description:'b-description',url:'b-url'},consumes:['b-consumes'],produces:['b-produces'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['b-scheme'],deprecated:false}",
 getSwaggerWithFile(new M03()).getPaths().get("/path/{foo}").get("get"));
+       }
+
+       
@RestResource(swagger=@ResourceSwagger("{paths:{'/path/{foo}':{get:{summary:'a-summary',description:'a-description',operationId:'a-operationId',deprecated:true,consumes:['a-consumes'],produces:['a-produces'],tags:['a-tag'],schemes:['a-scheme'],externalDocs:{description:'a-description',url:'a-url'}}}}}"))
+       public static class M04 {               
+               
@RestMethod(name=GET,path="/path/{foo}",swagger=@MethodSwagger(summary="b-summary",description="b-description",operationId="b-operationId",deprecated="false",consumes="b-consumes",produces="b-produces",tags="b-tag",schemes="b-scheme",externalDocs="description:'b-description',url:'b-url'"))
+               public Foo doFoo() {
+                       return null;
+               }
+       }
+
+       @Test
+       public void m04_operation_swaggerOnAnnotation() throws Exception {
+               
assertObjectEquals("{operationId:'b-operationId',summary:'b-summary',description:'b-description',tags:['b-tag'],externalDocs:{description:'b-description',url:'b-url'},consumes:['b-consumes'],produces:['b-produces'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['b-scheme'],deprecated:false}",
 getSwagger(new M04()).getPaths().get("/path/{foo}").get("get"));
+               
assertObjectEquals("{operationId:'b-operationId',summary:'b-summary',description:'b-description',tags:['b-tag'],externalDocs:{description:'b-description',url:'b-url'},consumes:['b-consumes'],produces:['b-produces'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['b-scheme'],deprecated:false}",
 getSwaggerWithFile(new M04()).getPaths().get("/path/{foo}").get("get"));
+       }
+
+       @RestResource(messages="BasicRestInfoProviderTest", 
swagger=@ResourceSwagger("{paths:{'/path/{foo}':{get:{summary:'a-summary',description:'a-description',operationId:'a-operationId',deprecated:true,consumes:['a-consumes'],produces:['a-produces'],tags:['a-tag'],schemes:['a-scheme'],externalDocs:{description:'a-description',url:'a-url'}}}}}"))
+       public static class M05 {               
+               
@RestMethod(name=GET,path="/path/{foo}",swagger=@MethodSwagger(summary="$L{foo}",description="$L{foo}",operationId="$L{foo}",deprecated="$L{foo}",consumes="$L{foo}",produces="$L{foo}",tags="$L{foo}",schemes="$L{foo}",externalDocs="description:'$L{foo}',url:'$L{foo}'"))
+               public Foo doFoo() {
+                       return null;
+               }
+       }
+
+       @Test
+       public void m05_operation_swaggerOnAnnotation_localized() throws 
Exception {
+               
assertObjectEquals("{operationId:'l-foo',summary:'l-foo',description:'l-foo',tags:['l-foo'],externalDocs:{description:'l-foo',url:'l-foo'},consumes:['l-foo'],produces:['l-foo'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['l-foo'],deprecated:false}",
 getSwagger(new M05()).getPaths().get("/path/{foo}").get("get"));
+               
assertObjectEquals("{operationId:'l-foo',summary:'l-foo',description:'l-foo',tags:['l-foo'],externalDocs:{description:'l-foo',url:'l-foo'},consumes:['l-foo'],produces:['l-foo'],responses:{'200':{description:'OK',schema:{type:'object',properties:{id:{format:'int32',type:'integer'}}}}},schemes:['l-foo'],deprecated:false}",
 getSwaggerWithFile(new M05()).getPaths().get("/path/{foo}").get("get"));
+       }
+       
+       
//-----------------------------------------------------------------------------------------------------------------
+       // /paths/<path>/<method>/description
+       
//-----------------------------------------------------------------------------------------------------------------
+       
+       //      paths: {
+//             '/path/{foo}': {
+//                     get: {
+//                             summary: 's-summary',
+//                             description: 's-description',
+//                             operationId: 's-operationId',
+//                             deprecated: true,
+//                             consumes: ['s-consumes'],
+//                             produces: ['s-produces'],
+//                             tags: ['s-tag'],
+//                             schemes: ['s-scheme'],
+//                             externalDocs: {
+//                                     description: 's-description',
+//                                     url: 's-url'
+//                             },
+//                             parameters: [
+//                                     {
+//                                             name: 's-query-name',
+//                                             in: 'query',
+//                                             description: 's-description',
+//                                             type: 'string',
+//                                             format: 's-format',
+//                                             pattern: 's-pattern',
+//                                             collectionFormat: 
's-collectionFormat',
+//                                             minimum: 1.0,
+//                                             maximum: 2.0,
+//                                             multipleOf: 3.0,
+//                                             minLength: 1,
+//                                             maxLength: 2,
+//                                             minItems: 3,
+//                                             maxItems: 4,
+//                                             required: true,
+//                                             allowEmptyValue: true,
+//                                             exclusiveMinimum: true,
+//                                             exclusiveMaximum: true,
+//                                             uniqueItems: true,              
                                
+//                                             schemaInfo: {
+//                                             }                               
                
+//                                     },
+//                                     {
+//                                             name: 's-header-name',
+//                                             in: 'header',
+//                                             description: 's-description',
+//                                             type: 'string',
+//                                             format: 's-format',
+//                                             pattern: 's-pattern',
+//                                             collectionFormat: 
's-collectionFormat',
+//                                             minimum: 1.0,
+//                                             maximum: 2.0,
+//                                             multipleOf: 3.0,
+//                                             minLength: 1,
+//                                             maxLength: 2,
+//                                             minItems: 3,
+//                                             maxItems: 4,
+//                                             required: true,
+//                                             allowEmptyValue: true,
+//                                             exclusiveMinimum: true,
+//                                             exclusiveMaximum: true,
+//                                             uniqueItems: true,              
                                
+//                                             schemaInfo: {
+//                                                     $ref: 
'#/definitions/Foo'
+//                                             }                               
                
+//                                     },
+//                                     {
+//                                             name: 's-path-name',
+//                                             in: 'path',
+//                                             description: 's-description',
+//                                             type: 'string',
+//                                             format: 's-format',
+//                                             pattern: 's-pattern',
+//                                             collectionFormat: 
's-collectionFormat',
+//                                             minimum: 1.0,
+//                                             maximum: 2.0,
+//                                             multipleOf: 3.0,
+//                                             minLength: 1,
+//                                             maxLength: 2,
+//                                             minItems: 3,
+//                                             maxItems: 4,
+//                                             required: true,
+//                                             allowEmptyValue: true,
+//                                             exclusiveMinimum: true,
+//                                             exclusiveMaximum: true,
+//                                             uniqueItems: true,              
                                
+//                                             schemaInfo: {
+//                                                     $ref: 
'#/definitions/Foo'
+//                                             }                               
                
+//                                     },
+//                                     {
+//                                             name: 's-formData-name',
+//                                             in: 'formData',
+//                                             description: 's-description',
+//                                             type: 'string',
+//                                             format: 's-format',
+//                                             pattern: 's-pattern',
+//                                             collectionFormat: 
's-collectionFormat',
+//                                             minimum: 1.0,
+//                                             maximum: 2.0,
+//                                             multipleOf: 3.0,
+//                                             minLength: 1,
+//                                             maxLength: 2,
+//                                             minItems: 3,
+//                                             maxItems: 4,
+//                                             required: true,
+//                                             allowEmptyValue: true,
+//                                             exclusiveMinimum: true,
+//                                             exclusiveMaximum: true,
+//                                             uniqueItems: true,              
                                
+//                                             schemaInfo: {
+//                                                     $ref: 
'#/definitions/Foo'
+//                                             }                               
                
+//                                     },
+//                                     {
+//                                             name: 's-body-name',
+//                                             in: 'body',
+//                                             description: 's-description',
+//                                             type: 'string',
+//                                             format: 's-format',
+//                                             pattern: 's-pattern',
+//                                             collectionFormat: 
's-collectionFormat',
+//                                             minimum: 1.0,
+//                                             maximum: 2.0,
+//                                             multipleOf: 3.0,
+//                                             minLength: 1,
+//                                             maxLength: 2,
+//                                             minItems: 3,
+//                                             maxItems: 4,
+//                                             required: true,
+//                                             allowEmptyValue: true,
+//                                             exclusiveMinimum: true,
+//                                             exclusiveMaximum: true,
+//                                             uniqueItems: true,              
                                
+//                                             schemaInfo: {
+//                                                     $ref: 
'#/definitions/Foo'
+//                                             }                               
                
+//                                     }
+//                             ],
+//                             responses: {
+//                                     100: {
+//                                             description:'s-100-description',
+//                                             schema: {
+//                                                     type: array,
+//                                                     items: {
+//                                                             $ref: 
'#/definitions/Foo'
+//                                                     }
+//                                             },
+//                                             headers: {
+//                                                     X-Foo: {
+//                                                             type: 'integer',
+//                                                             format: 'int32',
+//                                                             description: 
's-description'
+//                                                     }
+//                                             },
+//                                             examples: {
+//                                                     foo: {bar:123},
+//                                                     bar: 'baz'
+//                                             }
+//                                     }
+//                             },
+//                             security: [
+//                                     {foo_auth:['read:foo','write-foo']}
+//                             ]
+//                     } 
+//             }
+//     },
+//     definitions: {
+//             Foo: {
+//                     type: 'object',
+//                     properties: {
+//                             id: {
+//                                     type: 'integer',
+//                                     format: 'int64'
+//                             }
+//                     },
+//                     xml: {
+//                             name: 'Foo'
+//                     }
+//             }
+//     }
+       
+       @Bean(typeName="Foo")
+       public static class Foo {
+               public int id;
+       }
+
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/test/resources/org/apache/juneau/rest/BasicRestInfoProviderTest_swagger.json
 
b/juneau-rest/juneau-rest-server/src/test/resources/org/apache/juneau/rest/BasicRestInfoProviderTest_swagger.json
index 3e935ac..5047b03 100644
--- 
a/juneau-rest/juneau-rest-server/src/test/resources/org/apache/juneau/rest/BasicRestInfoProviderTest_swagger.json
+++ 
b/juneau-rest/juneau-rest-server/src/test/resources/org/apache/juneau/rest/BasicRestInfoProviderTest_swagger.json
@@ -61,10 +61,14 @@
                                externalDocs: {
                                        description: 's-description',
                                        url: 's-url'
-                               },
+                               }
+                       }
+               },
+               '/path/{foo}/query': {
+                       get: {
                                parameters: [
                                        {
-                                               name: 's-name',
+                                               name: 's-query-name',
                                                in: 'query',
                                                description: 's-description',
                                                type: 'string',
@@ -84,15 +88,156 @@
                                                exclusiveMaximum: true,
                                                uniqueItems: true,              
                                
                                                schemaInfo: {
+                                                       $ref: 
'#/definitions/Foo'
+                                               }                               
                
+                                       }
+                               ]
+                       }
+               },
+               '/path/{foo}/header': {
+                       get: {
+                               parameters: [
+                                       {
+                                               name: 's-header-name',
+                                               in: 'header',
+                                               description: 's-description',
+                                               type: 'string',
+                                               format: 's-format',
+                                               pattern: 's-pattern',
+                                               collectionFormat: 
's-collectionFormat',
+                                               minimum: 1.0,
+                                               maximum: 2.0,
+                                               multipleOf: 3.0,
+                                               minLength: 1,
+                                               maxLength: 2,
+                                               minItems: 3,
+                                               maxItems: 4,
+                                               required: true,
+                                               allowEmptyValue: true,
+                                               exclusiveMinimum: true,
+                                               exclusiveMaximum: true,
+                                               uniqueItems: true,              
                                
+                                               schemaInfo: {
+                                                       $ref: 
'#/definitions/Foo'
                                                }                               
                
                                        }
-                               ],
-                               responses: {
-                                       100: {description:'s-100-description'}
-                               },
-                               security: [
-                                       {foo_auth:['read:foo','write-foo']}
                                ]
+                       }
+               },
+               '/path/{foo}/path': {
+                       get: {
+                               parameters: [
+                                       {
+                                               name: 's-path-name',
+                                               in: 'path',
+                                               description: 's-description',
+                                               type: 'string',
+                                               format: 's-format',
+                                               pattern: 's-pattern',
+                                               collectionFormat: 
's-collectionFormat',
+                                               minimum: 1.0,
+                                               maximum: 2.0,
+                                               multipleOf: 3.0,
+                                               minLength: 1,
+                                               maxLength: 2,
+                                               minItems: 3,
+                                               maxItems: 4,
+                                               required: true,
+                                               allowEmptyValue: true,
+                                               exclusiveMinimum: true,
+                                               exclusiveMaximum: true,
+                                               uniqueItems: true,              
                                
+                                               schemaInfo: {
+                                                       $ref: 
'#/definitions/Foo'
+                                               }                               
                
+                                       }
+                               ]
+                       }
+               },
+               '/path/{foo}/formData': {
+                       get: {
+                               parameters: [
+                                       {
+                                               name: 's-formData-name',
+                                               in: 'formData',
+                                               description: 's-description',
+                                               type: 'string',
+                                               format: 's-format',
+                                               pattern: 's-pattern',
+                                               collectionFormat: 
's-collectionFormat',
+                                               minimum: 1.0,
+                                               maximum: 2.0,
+                                               multipleOf: 3.0,
+                                               minLength: 1,
+                                               maxLength: 2,
+                                               minItems: 3,
+                                               maxItems: 4,
+                                               required: true,
+                                               allowEmptyValue: true,
+                                               exclusiveMinimum: true,
+                                               exclusiveMaximum: true,
+                                               uniqueItems: true,              
                                
+                                               schemaInfo: {
+                                                       $ref: 
'#/definitions/Foo'
+                                               }                               
                
+                                       }
+                               ]
+                       }
+               },
+               '/path/{foo}/body': {
+                       get: {
+                               parameters: [
+                                       {
+                                               name: 's-body-name',
+                                               in: 'body',
+                                               description: 's-description',
+                                               type: 'string',
+                                               format: 's-format',
+                                               pattern: 's-pattern',
+                                               collectionFormat: 
's-collectionFormat',
+                                               minimum: 1.0,
+                                               maximum: 2.0,
+                                               multipleOf: 3.0,
+                                               minLength: 1,
+                                               maxLength: 2,
+                                               minItems: 3,
+                                               maxItems: 4,
+                                               required: true,
+                                               allowEmptyValue: true,
+                                               exclusiveMinimum: true,
+                                               exclusiveMaximum: true,
+                                               uniqueItems: true,              
                                
+                                               schemaInfo: {
+                                                       $ref: 
'#/definitions/Foo'
+                                               }                               
                
+                                       }
+                               ]
+                       }
+               },
+               '/path/{foo}/responses/100': {
+                       get: {
+                               responses: {
+                                       100: {
+                                               description:'s-100-description',
+                                               schema: {
+                                                       type: 'array',
+                                                       items: {
+                                                               $ref: 
'#/definitions/Foo'
+                                                       }
+                                               },
+                                               headers: {
+                                                       X-Foo: {
+                                                               type: 'integer',
+                                                               format: 'int32',
+                                                               description: 
's-description'
+                                                       }
+                                               },
+                                               examples: {
+                                                       foo: {bar:123},
+                                                       bar: 'baz'
+                                               }
+                                       }
+                               }
                        } 
                }
        },

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

Reply via email to