You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2018/06/06 16:43:18 UTC

[juneau] branch master updated: Swagger improvments.

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 f3b7f47  Swagger improvments.
f3b7f47 is described below

commit f3b7f47156538682be2d5e7e312304e34f761766
Author: JamesBognar <ja...@apache.org>
AuthorDate: Wed Jun 6 12:42:52 2018 -0400

    Swagger improvments.
---
 .../main/java/org/apache/juneau/ObjectList.java    | 64 ++++++++++++++++++++++
 .../src/main/java/org/apache/juneau/ObjectMap.java | 59 ++++++++++++++++++++
 juneau-doc/src/main/javadoc/overview.html          | 16 ++++++
 .../apache/juneau/rest/BasicRestInfoProvider.java  |  3 +-
 .../org/apache/juneau/rest/RestMethodParam.java    |  2 +-
 .../org/apache/juneau/rest/RestMethodReturn.java   |  7 ++-
 .../org/apache/juneau/rest/RestMethodThrown.java   |  7 ++-
 .../org/apache/juneau/rest/RestParamDefaults.java  |  3 +
 .../org/apache/juneau/rest/util/RestUtils.java     | 46 +++++++---------
 .../juneau/rest/BasicRestInfoProviderTest.java     | 22 ++++++++
 10 files changed, 196 insertions(+), 33 deletions(-)

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 cec754d..8e129ae 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
@@ -719,6 +719,37 @@ public class ObjectList extends LinkedList<Object> {
 	}
 
 	/**
+	 * Returns <jk>true</jk> if this list is unmodifiable.
+	 * 
+	 * @return <jk>true</jk> if this list is unmodifiable.
+	 */
+	public boolean isUnmodifiable() {
+		return false;
+	}
+	
+	/**
+	 * Returns a modifiable copy of this list if it's unmodifiable.
+	 * 
+	 * @return A modifiable copy of this list if it's unmodifiable, or this list if it is already modifiable.
+	 */
+	public ObjectList modifiable() {
+		if (isUnmodifiable()) 
+			return new ObjectList(this);
+		return this;
+	}
+	
+	/**
+	 * Returns an unmodifiable copy of this list if it's modifiable.
+	 * 
+	 * @return An unmodifiable copy of this list if it's modifiable, or this list if it is already unmodifiable.
+	 */
+	public ObjectList unmodifiable() {
+		if (this instanceof UnmodifiableObjectList)
+			return this;
+		return new UnmodifiableObjectList(this);
+	}
+
+	/**
 	 * Serialize this array to JSON using the {@link JsonSerializer#DEFAULT} serializer.
 	 */
 	@Override /* Object */
@@ -759,6 +790,39 @@ public class ObjectList extends LinkedList<Object> {
 		}
 	}
 	
+	private static final class UnmodifiableObjectList extends ObjectList {
+		private static final long serialVersionUID = 1L;
+
+		UnmodifiableObjectList(ObjectList contents) {
+			super();
+			if (contents != null) {
+				for (Object e : this) {
+					super.add(e);
+				}
+			}
+		}
+		
+		@Override /* List */
+		public void add(int location, Object object) {
+			throw new UnsupportedOperationException("ObjectList is read-only.");
+		}
+
+		@Override /* List */
+		public Object remove(int location) {
+			throw new UnsupportedOperationException("ObjectList is read-only.");
+		}
+
+		@Override /* List */
+		public Object set(int location, Object object) {
+			throw new UnsupportedOperationException("ObjectList is read-only.");
+		}
+		
+		@Override
+		public final boolean isUnmodifiable() {
+			return true;
+		}
+	}
+
 	BeanSession bs() {
 		if (session == null)
 			session = BeanContext.DEFAULT.createBeanSession();
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 6718064..cdf2ee0 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
@@ -1543,6 +1543,37 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 		JsonSerializer.DEFAULT.serialize(this);
 		return this;
 	}
+	
+	/**
+	 * Returns <jk>true</jk> if this map is unmodifiable.
+	 * 
+	 * @return <jk>true</jk> if this map is unmodifiable.
+	 */
+	public boolean isUnmodifiable() {
+		return false;
+	}
+	
+	/**
+	 * Returns a modifiable copy of this map if it's unmodifiable.
+	 * 
+	 * @return A modifiable copy of this map if it's unmodifiable, or this map if it is already modifiable.
+	 */
+	public ObjectMap modifiable() {
+		if (isUnmodifiable()) 
+			return new ObjectMap(this);
+		return this;
+	}
+	
+	/**
+	 * Returns an unmodifiable copy of this map if it's modifiable.
+	 * 
+	 * @return An unmodifiable copy of this map if it's modifiable, or this map if it is already unmodifiable.
+	 */
+	public ObjectMap unmodifiable() {
+		if (this instanceof UnmodifiableObjectMap)
+			return this;
+		return new UnmodifiableObjectMap(this);
+	}
 
 	@Override /* Map */
 	public Set<String> keySet() {
@@ -1610,6 +1641,34 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 		};
 	}
 	
+	private static final class UnmodifiableObjectMap extends ObjectMap {
+		private static final long serialVersionUID = 1L;
+
+		UnmodifiableObjectMap(ObjectMap contents) {
+			super();
+			if (contents != null) {
+				for (Map.Entry<String,Object> e : contents.entrySet()) {
+					super.put(e.getKey(), e.getValue());
+				}
+			}
+		}
+		
+		@Override
+		public final Object put(String key, Object val) {
+			throw new UnsupportedOperationException("ObjectMap is read-only.");
+		}
+
+		@Override
+		public final Object remove(Object key) {
+			throw new UnsupportedOperationException("ObjectMap is read-only.");
+		}
+		
+		@Override
+		public final boolean isUnmodifiable() {
+			return true;
+		}
+	}
+
 	private BeanSession bs() {
 		if (session == null)
 			session = BeanContext.DEFAULT.createBeanSession();
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index 5895c90..58a15da 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -21629,6 +21629,22 @@
 				Serializers now allow for q-values on the media types they handle.
 				<br>For example, the accept media type on <code>JsonSerializer.Simple</code> is <js>"application/json+simple,application/json;q=0.9"</js>.
 				<br>This means the serializer CAN handle requests for <js>"application/json"</js> if no other serializers provide a better match.
+			<li>
+				New methods for creating unmodifiable {@link org.apache.juneau.ObjectMap ObjectMaps} and {@link org.apache.juneau.ObjectList ObjectLists}.
+				<ul class='doctree'>
+					<li class='jc'>{@link org.apache.juneau.ObjectMap}
+					<ul>
+						<li class='jm'>{@link org.apache.juneau.ObjectMap#isUnmodifiable() isUnmodifable()}
+						<li class='jm'>{@link org.apache.juneau.ObjectMap#unmodifiable() unmodifiable()}
+						<li class='jm'>{@link org.apache.juneau.ObjectMap#modifiable() modifiable()}
+					</ul>
+					<li class='jp'>{@link org.apache.juneau.ObjectList}
+					<ul>
+						<li class='jm'>{@link org.apache.juneau.ObjectList#isUnmodifiable() isUnmodifable()}
+						<li class='jm'>{@link org.apache.juneau.ObjectList#unmodifiable() unmodifiable()}
+						<li class='jm'>{@link org.apache.juneau.ObjectList#modifiable() modifiable()}
+					</ul>
+				</ul>
 		</ul>
 		
 		<h5 class='topic w800'>juneau-dto</h5>
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 e56e5a5..74204bb 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
@@ -409,7 +409,7 @@ public class BasicRestInfoProvider implements RestInfoProvider {
 				
 				ObjectMap pi = mp.getMetaData();
 				if (pi.containsKey("_api"))
-					param.putAll(parseMap(pi.getString("_api"), vr, true, false, "@Body(api) on class {0} method {1}"));
+					param.putAll(parseMap(pi.getString("_api"), vr, true, false, "@Body(api) on class {0} method {1}", c, m));
 
 				// Common to all
 				param.appendSkipEmpty("description", vr.resolve(pi.getString("description")));
@@ -609,7 +609,6 @@ public class BasicRestInfoProvider implements RestInfoProvider {
 		return swagger;
 	}
 
-	
 	//=================================================================================================================
 	// Utility methods
 	//=================================================================================================================
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodParam.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodParam.java
index 31692dc..e3df438 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodParam.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodParam.java
@@ -138,7 +138,7 @@ public abstract class RestMethodParam {
 		this.name = name;
 		this.type = type;
 		this.c = type instanceof Class ? (Class<?>)type : type instanceof ParameterizedType ? (Class<?>)((ParameterizedType)type).getRawType() : null;
-		this.metaData = metaData;
+		this.metaData = metaData.unmodifiable();
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodReturn.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodReturn.java
index 84e6460..5ac5d0f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodReturn.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodReturn.java
@@ -31,14 +31,17 @@ public class RestMethodReturn {
 	
 	RestMethodReturn(Type type) {
 		this.type = type;
-		this.metaData = new ObjectMap();
+		
+		ObjectMap om = new ObjectMap();
 		
 		int code = 200;
 		if (type instanceof Class)
 		for (Response ri : ReflectionUtils.findAnnotationsParentFirst(Response.class, (Class<?>)type)) {
 			code = ObjectUtils.firstNonZero(ri.code(), code);
-			merge(metaData, ri);
+			om = merge(om, ri);
 		}
+		
+		this.metaData = om.unmodifiable();
 		 
 		this.code = code;
 	}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodThrown.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodThrown.java
index 7c2fe7e..d2a2b5b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodThrown.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodThrown.java
@@ -31,14 +31,17 @@ public class RestMethodThrown {
 	
 	RestMethodThrown(Class<?> type) {
 		this.type = type;
-		this.metaData = new ObjectMap();
+		
+		ObjectMap om = new ObjectMap();
 		
 		int code = 500;
 		for (Response ri : ReflectionUtils.findAnnotationsParentFirst(Response.class, type)) {
 			code = ObjectUtils.firstNonZero(ri.code(), code);
-			merge(metaData, ri);
+			om = merge(om, ri);
 		}
 		
+		this.metaData = om.unmodifiable();
+
 		this.code = code;
 	}
 	
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 bd196a5..76315e2 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
@@ -658,6 +658,7 @@ class RestParamDefaults {
 			ObjectMap om = existing == null ? new ObjectMap() : existing.metaData;
 			if (a == null)
 				return om;
+			om = om.modifiable();
 			List<Integer> codes = new ArrayList<>();
 			if (a.code() != 0)
 				codes.add(a.code());
@@ -708,6 +709,7 @@ class RestParamDefaults {
 			ObjectMap om = existing == null ? new ObjectMap() : existing.metaData;
 			if (a == null)
 				return om;
+			om = om.modifiable();
 			int status = ObjectUtils.firstNonZero(a.code(), 200);
 			merge(om.getObjectMap(String.valueOf(status), true), a);
 			return om;
@@ -750,6 +752,7 @@ class RestParamDefaults {
 			ObjectMap om = existing == null ? new ObjectMap() : existing.metaData;
 			if (a == null)
 				return om;
+			om = om.modifiable();
 			int status = firstNonZero(a.code(), a.value(), 200);
 			ObjectMap om2 = om.getObjectMap(String.valueOf(status), true);
 			om2
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/RestUtils.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/RestUtils.java
index 1df6c1d..9bd796d 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/RestUtils.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/RestUtils.java
@@ -420,6 +420,12 @@ public final class RestUtils {
 	// Methods for merging annotation values.
 	//=================================================================================================================
 	
+	private static ObjectMap newMap(ObjectMap om) {
+		if (om == null)
+			return new ObjectMap();
+		return om.modifiable();
+	}
+	
 	/**
 	 * Merges the contents of the specified annotation into the specified map.
 	 * 
@@ -430,8 +436,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, Body a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om
 			.appendSkipEmpty("_api", joinnl(a.api()))
 			.appendSkipEmpty("description", joinnl(a.description()))
@@ -451,8 +456,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, ExternalDocs a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om
 			.appendSkipEmpty("_api", joinnl(a.value()))
 			.appendSkipEmpty("description", joinnl(a.description()))
@@ -469,8 +473,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, Schema a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om
 			.appendSkipEmpty("_api", joinnl(a.value()))
 			.appendSkipEmpty("$ref", a.$ref())
@@ -517,16 +520,14 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, Response a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
-		om
+		om = newMap(om);
+		return om
 			.appendSkipEmpty("_api", joinnl(a.api()))
 			.appendSkipEmpty("description", joinnl(a.description()))
 			.appendSkipEmpty("example", joinnl(a.example()))
 			.appendSkipEmpty("examples", joinnl(a.examples()))
 			.append("schema", merge(om.getObjectMap("schema"), a.schema()))
 			.append("headers", merge(om.getObjectMap("headers"), a.headers()));
-		return om;
 	}	
 	
 	/**
@@ -539,8 +540,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, ResponseHeader[] a) {
 		if (a.length == 0)
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		for (ResponseHeader aa : a) {
 			String name = firstNonEmpty(aa.name(), aa.value());
 			if (isEmpty(name))
@@ -560,8 +560,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, Items a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om
 			.appendSkipEmpty("_api", joinnl(a.value()))
 			.appendSkipEmpty("type", a.type())
@@ -593,8 +592,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, ResponseHeader a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om 
 			.appendSkipEmpty("_api", joinnl(a.api()))
 			.appendSkipEmpty("$ref", a.$ref())
@@ -629,8 +627,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, Path a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om
 			.appendSkipEmpty("_api", joinnl(a.api()))
 			.appendSkipEmpty("description", joinnl(a.description()))
@@ -660,8 +657,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, Query a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om
 			.appendSkipEmpty("_api", joinnl(a.api()))
 			.appendSkipEmpty("description", joinnl(a.description()))
@@ -698,8 +694,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, Header a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om
 			.appendSkipEmpty("_api", joinnl(a.api()))
 			.appendSkipEmpty("description", joinnl(a.description()))
@@ -736,8 +731,7 @@ public final class RestUtils {
 	public static ObjectMap merge(ObjectMap om, FormData a) {
 		if (empty(a))
 			return om;
-		if (om == null)
-			om = new ObjectMap();
+		om = newMap(om);
 		return om
 			.appendSkipEmpty("_api", joinnl(a.api()))
 			.appendSkipEmpty("description", joinnl(a.description()))
@@ -835,7 +829,7 @@ public final class RestUtils {
 		if (a == null)
 			return true;
 		return 
-			empty(a.description(), a.example(), a.examples())
+			empty(a.description(), a.example(), a.examples(), a.api())
 			&& a.headers().length == 0
 			&& empty(a.schema())
 		;
@@ -906,7 +900,7 @@ public final class RestUtils {
 		if (a == null)
 			return true;
 		return 
-			empty(a.description(), a.example(), a.examples()) 
+			empty(a.description(), a.example(), a.examples(), a.api()) 
 			&& empty(a.required())
 			&& empty(a.schema());
 	}
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 a8ae336..18e035f 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
@@ -4761,6 +4761,20 @@ public class BasicRestInfoProviderTest {
 		@RestMethod(name=GET,path="/basic")
 		public void ta00(TA00 h) {}
 
+		@Body(
+			api={
+				"description:'a\nb',",
+				"required:true,",
+				"schema:{type:'a'},",
+				"examples:{foo:'bar'}"
+			}
+		)
+		public static class TA01 {
+			public TA01(String x) {}
+		}
+		
+		@RestMethod(name=GET,path="/api")
+		public void ta01(TA01 h) {}
 
 		@Body(schema=@Schema(" type:'b' "))
 		public static class TA18b {}
@@ -4814,6 +4828,14 @@ public class BasicRestInfoProviderTest {
 		assertObjectEquals("'a'", x.getExample());
 		assertObjectEquals("{foo:'bar'}", x.getExamples());
 	}
+//	@Test
+//	public void ta01_Body_onPojo_api() throws Exception {
+//		ParameterInfo x = getSwagger(new TA()).getPaths().get("/api").get("get").getParameter("body", null);
+//		assertEquals("a\nb", x.getDescription());
+//		assertObjectEquals("true", x.getRequired());
+//		assertObjectEquals("{type:'a'}", x.getSchema());
+//		assertObjectEquals("{foo:'bar'}", x.getExamples());
+//	}
 	@Test
 	public void ta18b_Body_onPojo_schema2() throws Exception {
 		ParameterInfo x = getSwagger(new TA()).getPaths().get("/schema2").get("get").getParameter("body", null);

-- 
To stop receiving notification emails like this one, please contact
jamesbognar@apache.org.