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 2020/03/12 18:31:06 UTC

[juneau] branch master updated: Fix other locations that aren't search for all annotations.

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 0015190  Fix other locations that aren't search for all annotations.
0015190 is described below

commit 0015190a16d0ed612e18073967d78068145dc8d8
Author: JamesBognar <ja...@apache.org>
AuthorDate: Thu Mar 12 14:30:47 2020 -0400

    Fix other locations that aren't search for all annotations.
---
 .../java/org/apache/juneau/jena/RdfClassMeta.java  | 27 +++++++--------
 .../src/main/java/org/apache/juneau/BeanMeta.java  |  4 +--
 .../src/main/java/org/apache/juneau/ClassMeta.java | 16 ++-------
 .../java/org/apache/juneau/csv/CsvClassMeta.java   | 14 ++++----
 .../java/org/apache/juneau/html/HtmlClassMeta.java | 39 +++++++++++++---------
 .../org/apache/juneau/html/HtmlParserSession.java  | 12 +++++--
 .../apache/juneau/html/HtmlSerializerSession.java  | 13 ++++++--
 .../juneau/httppart/bean/RequestBeanMeta.java      |  2 +-
 .../java/org/apache/juneau/jso/JsoClassMeta.java   | 14 ++++----
 .../java/org/apache/juneau/json/JsonClassMeta.java | 25 +++++++-------
 .../juneau/jsonschema/JsonSchemaClassMeta.java     |  6 ++--
 .../jsonschema/JsonSchemaGeneratorSession.java     |  2 +-
 .../apache/juneau/msgpack/MsgPackClassMeta.java    | 14 ++++----
 .../org/apache/juneau/oapi/OpenApiClassMeta.java   | 14 ++++----
 .../juneau/plaintext/PlainTextClassMeta.java       | 14 ++++----
 .../org/apache/juneau/soap/SoapXmlClassMeta.java   | 14 ++++----
 .../java/org/apache/juneau/uon/UonClassMeta.java   | 14 ++++----
 .../juneau/urlencoding/UrlEncodingClassMeta.java   | 26 +++++++++------
 .../java/org/apache/juneau/xml/XmlClassMeta.java   | 34 +++++++++----------
 .../org/apache/juneau/rest/client/RestCall.java    |  2 +-
 20 files changed, 168 insertions(+), 138 deletions(-)

diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfClassMeta.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfClassMeta.java
index 5565c5d..fb57c7a 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfClassMeta.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfClassMeta.java
@@ -24,7 +24,7 @@ import org.apache.juneau.xml.*;
  */
 public class RdfClassMeta extends ExtendedClassMeta {
 
-	private final Rdf rdf;
+	private final List<Rdf> rdfs;
 	private final RdfCollectionFormat collectionFormat;
 	private final Namespace namespace;
 
@@ -36,24 +36,25 @@ public class RdfClassMeta extends ExtendedClassMeta {
 	 */
 	public RdfClassMeta(ClassMeta<?> cm, RdfMetaProvider mp) {
 		super(cm);
-		this.rdf = cm.getAnnotation(Rdf.class);
-		if (rdf != null) {
-			collectionFormat = rdf.collectionFormat();
-		} else {
-			collectionFormat = RdfCollectionFormat.DEFAULT;
-		}
-		List<Rdf> rdfs = cm.getAnnotationsParentFirst(Rdf.class);
-		List<RdfSchema> schemas = cm.getAnnotationsParentFirst(RdfSchema.class);
+		this.rdfs = cm.getAnnotations(Rdf.class);
+
+		RdfCollectionFormat _collectionFormat = RdfCollectionFormat.DEFAULT;
+		for (Rdf a : rdfs)
+			if (a.collectionFormat() != RdfCollectionFormat.DEFAULT)
+				_collectionFormat = a.collectionFormat();
+		this.collectionFormat = _collectionFormat;
+		
+		List<RdfSchema> schemas = cm.getAnnotations(RdfSchema.class);
 		this.namespace = RdfUtils.findNamespace(rdfs, schemas);
 	}
 
 	/**
-	 * Returns the {@link Rdf @Rdf} annotation defined on the class.
+	 * Returns the {@link Rdf @Rdf} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if annotation is not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected Rdf getAnnotation() {
-		return rdf;
+	protected List<Rdf> getAnnotations() {
+		return rdfs;
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index f24f082..fb2d70b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -180,14 +180,14 @@ public class BeanMeta<T> {
 					bdClasses.addAll(Arrays.asList(beanFilter.getBeanDictionary()));
 
 				boolean hasTypeName = false;
-				for (Bean b : classMeta.getAnnotationsParentFirst(Bean.class))
+				for (Bean b : classMeta.getAnnotations(Bean.class))
 					if (! b.typeName().isEmpty())
 						hasTypeName = true;
 				if (hasTypeName)
 					bdClasses.add(classMeta.innerClass);
 				this.beanRegistry = new BeanRegistry(ctx, null, bdClasses.toArray(new Class<?>[bdClasses.size()]));
 
-				for (Bean b : classMeta.getAnnotationsParentFirst(Bean.class))
+				for (Bean b : classMeta.getAnnotations(Bean.class))
 					if (! b.typePropertyName().isEmpty())
 						typePropertyName = b.typePropertyName();
 				if (typePropertyName == null)
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 2e68f3d..99b139d 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
@@ -2040,7 +2040,7 @@ public final class ClassMeta<T> implements Type {
 	 * @return <jk>true</jk> if the inner class has the annotation.
 	 */
 	public boolean hasAnnotation(Class<? extends Annotation> a) {
-		return getAnnotation(a) != null;
+		return getLastAnnotation(a) != null;
 	}
 
 	/**
@@ -2049,21 +2049,11 @@ public final class ClassMeta<T> implements Type {
 	 * @param a The annotation to retrieve.
 	 * @return The specified annotation, or <jk>null</jk> if the class does not have the specified annotation.
 	 */
-	public <A extends Annotation> A getAnnotation(Class<A> a) {
+	public <A extends Annotation> A getLastAnnotation(Class<A> a) {
 		return info.getLastAnnotation(a, beanContext == null ? BeanContext.DEFAULT : beanContext);
 	}
 
 	/**
-	 * Returns the declared annotation defined on this class.
-	 *
-	 * @param a The annotation to retrieve.
-	 * @return The specified annotation, or <jk>null</jk> if the class does not have the specified annotation.
-	 */
-//	public <A extends Annotation> A getDeclaredAnnotation(Class<A> a) {
-//		return info.getDeclaredAnnotation(a, beanContext == null ? BeanContext.DEFAULT : beanContext);
-//	}
-
-	/**
 	 * Returns all annotations of the specified type defined on the specified class or parent classes/interfaces in parent-to-child order.
 	 *
 	 * @param a
@@ -2071,7 +2061,7 @@ public final class ClassMeta<T> implements Type {
 	 * @return
 	 * 	A list of all matching annotations found or an empty list if none found.
 	 */
-	public <A extends Annotation> List<A> getAnnotationsParentFirst(Class<A> a) {
+	public <A extends Annotation> List<A> getAnnotations(Class<A> a) {
 		return info.getAnnotations(a, beanContext == null ? BeanContext.DEFAULT : beanContext);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvClassMeta.java
index 8ca7f3a..bcb1c31 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvClassMeta.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.csv;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.csv.annotation.*;
 
@@ -21,7 +23,7 @@ import org.apache.juneau.csv.annotation.*;
  */
 public class CsvClassMeta extends ExtendedClassMeta {
 
-	private final Csv csv;
+	private final List<Csv> csvs;
 
 	/**
 	 * Constructor.
@@ -31,15 +33,15 @@ public class CsvClassMeta extends ExtendedClassMeta {
 	 */
 	public CsvClassMeta(ClassMeta<?> cm, CsvMetaProvider mp) {
 		super(cm);
-		this.csv = cm.getAnnotation(Csv.class);
+		this.csvs = cm.getAnnotations(Csv.class);
 	}
 
 	/**
-	 * Returns the {@link Csv @Csv} annotation defined on the class.
+	 * Returns the {@link Csv @Csv} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected Csv getAnnotation() {
-		return csv;
+	protected List<Csv> getAnnotation() {
+		return csvs;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlClassMeta.java
index 260c3b6..411fcc3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlClassMeta.java
@@ -14,6 +14,8 @@ package org.apache.juneau.html;
 
 import static org.apache.juneau.internal.ClassUtils.*;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.html.annotation.*;
 
@@ -23,7 +25,7 @@ import org.apache.juneau.html.annotation.*;
  */
 public class HtmlClassMeta extends ExtendedClassMeta {
 
-	private final Html html;
+	private final List<Html> htmls;
 	private final boolean noTables, noTableHeaders;
 	private final HtmlFormat format;
 	private final HtmlRender<?> render;
@@ -36,27 +38,32 @@ public class HtmlClassMeta extends ExtendedClassMeta {
 	 */
 	public HtmlClassMeta(ClassMeta<?> cm, HtmlMetaProvider mp) {
 		super(cm);
-		this.html = cm.getAnnotation(Html.class);
-		if (html != null) {
-			format = html.format();
-			noTables = html.noTables();
-			noTableHeaders = html.noTableHeaders();
-			render = castOrCreate(HtmlRender.class, html.render());
-		} else {
-			format = HtmlFormat.HTML;
-			noTables = false;
-			noTableHeaders = false;
-			render = null;
+		this.htmls = cm.getAnnotations(Html.class);
+
+		boolean _noTables = false, _noTableHeaders = false;
+		HtmlRender<?> _render = null;
+		HtmlFormat _format = HtmlFormat.HTML;
+
+		for (Html a : this.htmls) {
+			_format = a.format();
+			_noTables = a.noTables();
+			_noTableHeaders = a.noTableHeaders();
+			_render = castOrCreate(HtmlRender.class, a.render());
 		}
+
+		this.noTables = _noTables;
+		this.noTableHeaders = _noTableHeaders;
+		this.render = _render;
+		this.format = _format;
 	}
 
 	/**
-	 * Returns the {@link Html @Html} annotation defined on the class.
+	 * Returns the {@link Html @Html} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected Html getAnnotation() {
-		return html;
+	protected List<Html> getAnnotations() {
+		return htmls;
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
index 6ab799b..dc00be3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
@@ -317,10 +317,16 @@ public final class HtmlParserSession extends XmlParserSession {
 		String href = r.getAttributeValue(null, "href");
 		String name = getElementText(r);
 		if (beanType.hasAnnotation(HtmlLink.class)) {
-			HtmlLink h = beanType.getAnnotation(HtmlLink.class);
+			String uriProperty = "", nameProperty = "";
+			for (HtmlLink a : beanType.getAnnotations(HtmlLink.class)) {
+				if (! a.uriProperty().isEmpty())
+					uriProperty = a.uriProperty();
+				if (! a.nameProperty().isEmpty())
+					nameProperty = a.nameProperty();
+			}
 			BeanMap<T> m = newBeanMap(beanType.getInnerClass());
-			m.put(h.uriProperty(), href);
-			m.put(h.nameProperty(), name);
+			m.put(uriProperty, href);
+			m.put(nameProperty, name);
 			return m.getBean();
 		}
 		return convertToType(href, beanType);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
index be185ca..72dac32 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
@@ -347,9 +347,16 @@ public class HtmlSerializerSession extends XmlSerializerSession {
 			} else if (sType.isBean()) {
 				BeanMap m = toBeanMap(o);
 				if (aType.hasAnnotation(HtmlLink.class)) {
-					HtmlLink h = aType.getAnnotation(HtmlLink.class);
-					Object urlProp = m.get(h.uriProperty());
-					Object nameProp = m.get(h.nameProperty());
+					String uriProperty = "", nameProperty = "";
+					for (HtmlLink a : aType.getAnnotations(HtmlLink.class)) {
+						if (! a.uriProperty().isEmpty())
+							uriProperty = a.uriProperty();
+						if (! a.nameProperty().isEmpty())
+							nameProperty = a.nameProperty();
+					}
+					Object urlProp = m.get(uriProperty);
+					Object nameProp = m.get(nameProperty);
+
 					out.oTag("a").attrUri("href", urlProp).append('>').text(nameProp).eTag("a");
 					cr = CR_MIXED;
 				} else {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanMeta.java
index dfc6c5c..395724d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanMeta.java
@@ -96,7 +96,7 @@ public class RequestBeanMeta {
 
 		Builder apply(Class<?> c) {
 			this.cm = BeanContext.DEFAULT.getClassMeta(c);
-			apply(cm.getAnnotation(Request.class));
+			apply(cm.getLastAnnotation(Request.class));
 			for (MethodInfo m : cm.getInfo().getAllMethods()) {
 
 				if (m.isPublic()) {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoClassMeta.java
index d43432d..82e8ffb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoClassMeta.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.jso;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.jso.annotation.*;
 
@@ -21,7 +23,7 @@ import org.apache.juneau.jso.annotation.*;
  */
 public class JsoClassMeta extends ExtendedClassMeta {
 
-	private final Jso jso;
+	private final List<Jso> jsos;
 
 	/**
 	 * Constructor.
@@ -31,15 +33,15 @@ public class JsoClassMeta extends ExtendedClassMeta {
 	 */
 	public JsoClassMeta(ClassMeta<?> cm, JsoMetaProvider mp) {
 		super(cm);
-		this.jso = cm.getAnnotation(Jso.class);
+		this.jsos = cm.getAnnotations(Jso.class);
 	}
 
 	/**
-	 * Returns the {@link Jso @Jso} annotation defined on the class.
+	 * Returns the {@link Jso @Jso} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected Jso getAnnotation() {
-		return jso;
+	protected List<Jso> getAnnotations() {
+		return jsos;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonClassMeta.java
index 69dcdeb..362924a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonClassMeta.java
@@ -12,7 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.json;
 
-import static org.apache.juneau.internal.StringUtils.*;
+import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.json.annotation.*;
@@ -23,7 +23,7 @@ import org.apache.juneau.json.annotation.*;
  */
 public class JsonClassMeta extends ExtendedClassMeta {
 
-	private final Json json;
+	private final List<Json> jsons;
 	private final String wrapperAttr;
 
 	/**
@@ -34,21 +34,22 @@ public class JsonClassMeta extends ExtendedClassMeta {
 	 */
 	public JsonClassMeta(ClassMeta<?> cm, JsonMetaProvider mp) {
 		super(cm);
-		this.json = cm.getAnnotation(Json.class);
-		if (json != null) {
-			wrapperAttr = nullIfEmpty(json.wrapperAttr());
-		} else {
-			wrapperAttr = null;
-		}
+		this.jsons = cm.getAnnotations(Json.class);
+		
+		String _wrapperAttr = null;
+		for (Json a : this.jsons)
+			if (! a.wrapperAttr().isEmpty())
+				_wrapperAttr = a.wrapperAttr();
+		this.wrapperAttr = _wrapperAttr;
 	}
 
 	/**
-	 * Returns the {@link Json @Json} annotation defined on the class.
+	 * Returns the {@link Json @Json} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected Json getAnnotation() {
-		return json;
+	protected List<Json> getAnnotations() {
+		return jsons;
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaClassMeta.java
index 5016ecb..66ed5e4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaClassMeta.java
@@ -22,7 +22,7 @@ import org.apache.juneau.parser.*;
  */
 public class JsonSchemaClassMeta extends ExtendedClassMeta {
 
-	private final ObjectMap schema;
+	private final ObjectMap schema = new ObjectMap();
 
 	/**
 	 * Constructor.
@@ -33,8 +33,8 @@ public class JsonSchemaClassMeta extends ExtendedClassMeta {
 	public JsonSchemaClassMeta(ClassMeta<?> cm, JsonSchemaMetaProvider mp) {
 		super(cm);
 		try {
-			Schema s = cm.getAnnotation(Schema.class);
-			schema = s == null ? ObjectMap.EMPTY_MAP : SchemaUtils.asMap(s);
+			for (Schema a : cm.getAnnotations(Schema.class))
+				schema.appendAll(SchemaUtils.asMap(a));
 		} catch (ParseException e) {
 			throw new RuntimeException(e);
 		}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
index 016a427..e3fc56b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
@@ -140,7 +140,7 @@ public class JsonSchemaGeneratorSession extends BeanTraverseSession {
 
 		JsonSchemaClassMeta jscm = null;
 		ClassMeta pojoSwapCM = pojoSwap == null ? null : getClassMeta(pojoSwap.getClass());
-		if (pojoSwapCM != null && pojoSwapCM.getAnnotation(Schema.class) != null)
+		if (pojoSwapCM != null && pojoSwapCM.hasAnnotation(Schema.class))
 			jscm = getJsonSchemaClassMeta(pojoSwapCM);
 		if (jscm == null)
 			jscm = getJsonSchemaClassMeta(sType);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackClassMeta.java
index 662db82..7f6532b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackClassMeta.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.msgpack;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.msgpack.annotation.*;
 
@@ -21,7 +23,7 @@ import org.apache.juneau.msgpack.annotation.*;
  */
 public class MsgPackClassMeta extends ExtendedClassMeta {
 
-	private final MsgPack msgPack;
+	private final List<MsgPack> msgPacks;
 
 	/**
 	 * Constructor.
@@ -31,15 +33,15 @@ public class MsgPackClassMeta extends ExtendedClassMeta {
 	 */
 	public MsgPackClassMeta(ClassMeta<?> cm, MsgPackMetaProvider mp) {
 		super(cm);
-		this.msgPack = cm.getAnnotation(MsgPack.class);
+		this.msgPacks = cm.getAnnotations(MsgPack.class);
 	}
 
 	/**
-	 * Returns the {@link MsgPack @MsgPack} annotation defined on the class.
+	 * Returns the {@link MsgPack @MsgPack} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected MsgPack getAnnotation() {
-		return msgPack;
+	protected List<MsgPack> getAnnotations() {
+		return msgPacks;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiClassMeta.java
index 0cba4ba..86d5dd9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiClassMeta.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.oapi;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.oapi.annotation.*;
 
@@ -21,7 +23,7 @@ import org.apache.juneau.oapi.annotation.*;
  */
 public class OpenApiClassMeta extends ExtendedClassMeta {
 
-	private final OpenApi openApi;
+	private final List<OpenApi> openApis;
 
 	/**
 	 * Constructor.
@@ -31,15 +33,15 @@ public class OpenApiClassMeta extends ExtendedClassMeta {
 	 */
 	public OpenApiClassMeta(ClassMeta<?> cm, OpenApiMetaProvider mp) {
 		super(cm);
-		this.openApi = cm.getAnnotation(OpenApi.class);
+		this.openApis = cm.getAnnotations(OpenApi.class);
 	}
 
 	/**
-	 * Returns the {@link OpenApi @OpenApi} annotation defined on the class.
+	 * Returns the {@link OpenApi @OpenApi} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected OpenApi getAnnotation() {
-		return openApi;
+	protected List<OpenApi> getAnnotations() {
+		return openApis;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextClassMeta.java
index fda5b6d..fef29ca 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextClassMeta.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.plaintext;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.plaintext.annotation.*;
 
@@ -21,7 +23,7 @@ import org.apache.juneau.plaintext.annotation.*;
  */
 public class PlainTextClassMeta extends ExtendedClassMeta {
 
-	private final PlainText plainText;
+	private final List<PlainText> plainTexts;
 
 	/**
 	 * Constructor.
@@ -31,15 +33,15 @@ public class PlainTextClassMeta extends ExtendedClassMeta {
 	 */
 	public PlainTextClassMeta(ClassMeta<?> cm, PlainTextMetaProvider mp) {
 		super(cm);
-		this.plainText = cm.getAnnotation(PlainText.class);
+		this.plainTexts = cm.getAnnotations(PlainText.class);
 	}
 
 	/**
-	 * Returns the {@link PlainText @PlainText} annotation defined on the class.
+	 * Returns the {@link PlainText @PlainText} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected PlainText getAnnotation() {
-		return plainText;
+	protected List<PlainText> getAnnotations() {
+		return plainTexts;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlClassMeta.java
index e542343..c239d19 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlClassMeta.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.soap;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.soap.annotation.*;
 
@@ -21,7 +23,7 @@ import org.apache.juneau.soap.annotation.*;
  */
 public class SoapXmlClassMeta extends ExtendedClassMeta {
 
-	private final SoapXml soapXml;
+	private final List<SoapXml> soapXmls;
 
 	/**
 	 * Constructor.
@@ -31,15 +33,15 @@ public class SoapXmlClassMeta extends ExtendedClassMeta {
 	 */
 	public SoapXmlClassMeta(ClassMeta<?> cm, SoapXmlMetaProvider mp) {
 		super(cm);
-		this.soapXml = cm.getAnnotation(SoapXml.class);
+		this.soapXmls = cm.getAnnotations(SoapXml.class);
 	}
 
 	/**
-	 * Returns the {@link SoapXml @SoapXml} annotation defined on the class.
+	 * Returns the {@link SoapXml @SoapXml} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected SoapXml getAnnotation() {
-		return soapXml;
+	protected List<SoapXml> getAnnotations() {
+		return soapXmls;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonClassMeta.java
index 3da35da..734d0247 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonClassMeta.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.uon;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.uon.annotation.*;
 
@@ -21,7 +23,7 @@ import org.apache.juneau.uon.annotation.*;
  */
 public class UonClassMeta extends ExtendedClassMeta {
 
-	private final Uon uon;
+	private final List<Uon> uons;
 
 	/**
 	 * Constructor.
@@ -31,15 +33,15 @@ public class UonClassMeta extends ExtendedClassMeta {
 	 */
 	public UonClassMeta(ClassMeta<?> cm, UonMetaProvider mp) {
 		super(cm);
-		this.uon = cm.getAnnotation(Uon.class);
+		this.uons = cm.getAnnotations(Uon.class);
 	}
 
 	/**
-	 * Returns the {@link Uon @Uon} annotation defined on the class.
+	 * Returns the {@link Uon @Uon} annotations defined on the class.
 	 *
-	 * @return The value of the annotation, or <jk>null</jk> if not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected Uon getAnnotation() {
-		return uon;
+	protected List<Uon> getAnnotations() {
+		return uons;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingClassMeta.java
index c50ec0e..6be519d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingClassMeta.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.urlencoding;
 
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.urlencoding.annotation.*;
 
@@ -20,7 +22,7 @@ import org.apache.juneau.urlencoding.annotation.*;
  */
 public class UrlEncodingClassMeta extends ExtendedClassMeta {
 
-	private final UrlEncoding urlEncoding;
+	private final List<UrlEncoding> urlEncodings;
 	private final boolean expandedParams;
 
 	/**
@@ -31,21 +33,23 @@ public class UrlEncodingClassMeta extends ExtendedClassMeta {
 	 */
 	public UrlEncodingClassMeta(ClassMeta<?> cm, UrlEncodingMetaProvider mp) {
 		super(cm);
-		this.urlEncoding = cm.getAnnotation(UrlEncoding.class);
-		if (urlEncoding != null) {
-			expandedParams = urlEncoding.expandedParams();
-		} else {
-			expandedParams = false;
-		}
+		this.urlEncodings = cm.getAnnotations(UrlEncoding.class);
+
+		boolean _expandedParams = false;
+		for (UrlEncoding a : urlEncodings)
+			if (a.expandedParams())
+				_expandedParams = true;
+
+		this.expandedParams = _expandedParams;
 	}
 
 	/**
-	 * Returns the {@link UrlEncoding} annotation defined on the class.
+	 * Returns the {@link UrlEncoding} annotations defined on the class.
 	 *
-	 * @return The value of the {@link UrlEncoding} annotation, or <jk>null</jk> if annotation is not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected UrlEncoding getAnnotation() {
-		return urlEncoding;
+	protected List<UrlEncoding> getAnnotations() {
+		return urlEncodings;
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlClassMeta.java
index bf1e0af..2ada7dc 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlClassMeta.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.xml;
 
-import static org.apache.juneau.internal.StringUtils.*;
-
 import java.util.*;
 
 import org.apache.juneau.*;
@@ -26,7 +24,7 @@ import org.apache.juneau.xml.annotation.*;
 public class XmlClassMeta extends ExtendedClassMeta {
 
 	private final Namespace namespace;
-	private final Xml xml;
+	private final List<Xml> xmls;
 	private final XmlFormat format;
 	private final String childName;
 
@@ -39,25 +37,27 @@ public class XmlClassMeta extends ExtendedClassMeta {
 	public XmlClassMeta(ClassMeta<?> cm, XmlMetaProvider mp) {
 		super(cm);
 		this.namespace = findNamespace(cm, mp);
-		this.xml = cm.getAnnotation(Xml.class);
-		if (xml != null) {
-			this.format = xml.format();
-			this.childName = nullIfEmpty(xml.childName());
+		this.xmls = cm.getAnnotations(Xml.class);
 
-		} else {
-			this.format = XmlFormat.DEFAULT;
-			this.childName = null;
+		String _childName = null;
+		XmlFormat _format = XmlFormat.DEFAULT;
+		for (Xml a : xmls) {
+			if (a.format() != XmlFormat.DEFAULT)
+				_format = a.format();
+			if (! a.childName().isEmpty())
+				_childName = a.childName();
 		}
+		this.format = _format;
+		this.childName = _childName;
 	}
 
 	/**
-	 * Returns the {@link Xml @Xml} annotation defined on the class.
+	 * Returns the {@link Xml @Xml} annotations defined on the class.
 	 *
-	 * @return
-	 * 	The value of the annotation defined on the class, or <jk>null</jk> if annotation is not specified.
+	 * @return An unmodifiable list of annotations ordered parent-to-child, or an empty list if not found.
 	 */
-	protected Xml getAnnotation() {
-		return xml;
+	protected List<Xml> getAnnotations() {
+		return xmls;
 	}
 
 	/**
@@ -101,8 +101,8 @@ public class XmlClassMeta extends ExtendedClassMeta {
 	private static Namespace findNamespace(ClassMeta<?> cm, MetaProvider mp) {
 		if (cm == null)
 			return null;
-		List<Xml> xmls = cm.getAnnotationsParentFirst(Xml.class);
-		List<XmlSchema> schemas = cm.getAnnotationsParentFirst(XmlSchema.class);
+		List<Xml> xmls = cm.getAnnotations(Xml.class);
+		List<XmlSchema> schemas = cm.getAnnotations(XmlSchema.class);
 		return XmlUtils.findNamespace(xmls, schemas);
 	}
 }
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
index 358fe1f..164b6a1 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
@@ -1688,7 +1688,7 @@ public final class RestCall extends BeanSession implements Closeable {
 
 			int[] expected = new int[0];
 			if (bodyType != null && bodyType.hasAnnotation(Response.class))
-				expected = bodyType.getAnnotation(Response.class).code();
+				expected = bodyType.getLastAnnotation(Response.class).code();
 
 			if (sc >= 400 && ! ignoreErrors && ! ArrayUtils.contains(sc, expected)) {
 				throw new RestCallException(sc, sl.getReasonPhrase(), method, request.getURI(), getResponseAsString())