Repository: incubator-juneau
Updated Branches:
  refs/heads/master fc1e3fcfc -> 495c648d1


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
index 5d8070d..6f9c3db 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
@@ -12,6 +12,8 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.http;
 
+import static org.apache.juneau.internal.StringUtils.*;
+
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -64,9 +66,10 @@ public class MediaType implements Comparable<MediaType> {
        private final String type;                                              
                     // The media type (e.g. "text" for Accept, "utf-8" for 
Accept-Charset)
        private final String subType;                        // The media 
sub-type (e.g. "json" for Accept, not used for Accept-Charset)
        private final String[] subTypes;                     // The media 
sub-type (e.g. "json" for Accept, not used for Accept-Charset)
+       private final String[] subTypesSorted;               // Same as 
subTypes, but sorted so that it can be used for comparison.
        private final List<String> subTypesList;             // The media 
sub-type (e.g. "json" for Accept, not used for Accept-Charset)
        private final Map<String,Set<String>> parameters;    // The media type 
parameters (e.g. "text/html;level=1").  Does not include q!
-
+       private final boolean hasSubtypeMeta;                // The media 
subtype contains meta-character '*'.
 
        /**
         * Returns the media type for the specified string.
@@ -87,11 +90,11 @@ public class MediaType implements Comparable<MediaType> {
         * @param s
         *      The media type string.
         *      Will be lowercased.
-        *      Returns <jk>null</jk> if input is null.
+        *      Returns <jk>null</jk> if input is null or empty.
         * @return A cached media type object.
         */
        public static MediaType forString(String s) {
-               if (s == null)
+               if (isEmpty(s))
                        return null;
                MediaType mt = cache.get(s);
                if (mt == null) {
@@ -103,20 +106,40 @@ public class MediaType implements Comparable<MediaType> {
                return cache.get(s);
        }
 
+       /**
+        * Same as {@link #forString(String)} but allows you to construct an 
array of <code>MediaTypes</code> from an
+        * array of strings.
+        *
+        * @param s
+        *      The media type strings.
+        * @return
+        *      An array of <code>MediaType</code> objects.
+        *      <br>Always the same length as the input string array.
+        */
+       public static MediaType[] forStrings(String...s) {
+               MediaType[] mt = new MediaType[s.length];
+               for (int i = 0; i < s.length; i++)
+                       mt[i] = forString(s[i]);
+               return mt;
+       }
+
        MediaType(String mt) {
                Builder b = new Builder(mt);
                this.mediaType = b.mediaType;
                this.type = b.type;
                this.subType = b.subType;
                this.subTypes = b.subTypes;
+               this.subTypesSorted = b.subTypesSorted;
                this.subTypesList = 
Collections.unmodifiableList(Arrays.asList(subTypes));
                this.parameters = (b.parameters == null ? Collections.EMPTY_MAP 
: Collections.unmodifiableMap(b.parameters));
+               this.hasSubtypeMeta = b.hasSubtypeMeta;
        }
 
        private static class Builder {
                private String mediaType, type, subType;
-               private String[] subTypes;
+               private String[] subTypes, subTypesSorted;
                private Map<String,Set<String>> parameters;
+               private boolean hasSubtypeMeta;
 
                private Builder(String mt) {
                        mt = mt.trim();
@@ -149,6 +172,9 @@ public class MediaType implements Comparable<MediaType> {
                                subType = (i == -1 ? "*" : mt.substring(i+1));
                        }
                        this.subTypes = StringUtils.split(subType, '+');
+                       this.subTypesSorted = Arrays.copyOf(subTypes, 
subTypes.length);
+                       Arrays.sort(this.subTypesSorted);
+                       hasSubtypeMeta = ArrayUtils.contains("*", 
this.subTypes);
                }
        }
 
@@ -200,33 +226,28 @@ public class MediaType implements Comparable<MediaType> {
        }
 
        /**
-        * Returns <jk>true</jk> if this media type is a match for the 
specified media type.
-        *
-        * <p>
-        * Matches if any of the following is true:
-        * <ul>
-        *      <li>Both type and subtype are the same.
-        *      <li>One or both types are <js>'*'</js> and the subtypes are the 
same.
-        *      <li>One or both subtypes are <js>'*'</js> and the types are the 
same.
-        *      <li>Either is <js>'*\/*'</js>.
-        * </ul>
+        * Returns <jk>true</jk> if this media type contains the <js>'*'</js> 
meta character.
         *
-        * @param o The media type to compare with.
-        * @return <jk>true</jk> if the media types match.
+        * @return <jk>true</jk> if this media type contains the <js>'*'</js> 
meta character.
         */
-       public final boolean matches(MediaType o) {
-               return match(o) > 0;
+       public final boolean isMeta() {
+               return hasSubtypeMeta;
        }
 
        /**
         * Returns a match metric against the specified media type where a 
larger number represents a better match.
         *
+        * <p>
+        * This media type can contain <js>'*'</js> metacharacters.
+        * <br>The comparison media type must not.
+        *
         * <ul>
         *      <li>Exact matches (e.g. 
<js>"text/json"<js>/</js>"text/json"</js>) should match
         *              better than meta-character matches (e.g. 
<js>"text/*"<js>/</js>"text/json"</js>)
         *      <li>The comparison media type can have additional subtype 
tokens (e.g. <js>"text/json+foo"</js>)
-        *              that will not prevent a match.  The reverse is not 
true, e.g. the comparison media type
-        *              must contain all subtype tokens found in the comparing 
media type.
+        *              that will not prevent a match if the 
<code>allowExtraSubTypes</code> flag is set.
+        *              The reverse is not true, e.g. the comparison media type 
must contain all subtype tokens found in the
+        *              comparing media type.
         *              <ul>
         *                      <li>We want the {@link JsonSerializer} 
(<js>"text/json"</js>) class to be able to handle requests for 
<js>"text/json+foo"</js>.
         *                      <li>We want to make sure {@link 
org.apache.juneau.json.JsonSerializer.Simple} (<js>"text/json+simple"</js>) 
does not handle
@@ -235,43 +256,70 @@ public class MediaType implements Comparable<MediaType> {
         *              More token matches should result in a higher match 
number.
         * </ul>
         *
+        * The formula is as follows for <code>type/subTypes</code>:
+        * <ul>
+        *      <li>An exact match is <code>100,000</code>.
+        *      <li>Add the following for type (assuming subtype match is 
&lt;0):
+        *      <ul>
+        *              <li><code>10,000</code> for an exact match (e.g. 
<js>"text"</js>==<js>"text"</js>).
+        *              <li><code>5,000</code> for a meta match (e.g. 
<js>"*"</js>==<js>"text"</js>).
+        *      <ul>
+        *      <li>Add the following for subtype (assuming type match is 
&lt;0):
+        *      <ul>
+        *              <li><code>7,500</code> for an exact match (e.g. 
<js>"json+foo"</js>==<js>"json+foo"</js> or 
<js>"json+foo"</js>==<js>"foo+json"</js>)
+        *              <li><code>100</code> for every subtype entry match 
(e.g. <js>"json"</js>/<js>"json+foo"</js>)
+        *              <li><code>10</code> for a subtype entry meta match 
(e.g. <js>"*"</js>/<js>"json"</js> or <js>"json+*"</js>/<js>"json+foo"</js>)
+        *      </ul>
+        * </ul>
+        *
         * @param o The media type to compare with.
+        * @param allowExtraSubTypes If <jk>true</jk>,
         * @return <jk>true</jk> if the media types match.
         */
-       public final int match(MediaType o) {
+       public final int match(MediaType o, boolean allowExtraSubTypes) {
 
                // Perfect match
                if (this == o || (type.equals(o.type) && 
subType.equals(o.subType)))
-                       return Integer.MAX_VALUE;
+                       return 100000;
 
-               int c1 = 0, c2 = 0;
+               int c = 0;
 
                if (type.equals(o.type))
-                       c1 += 10000;
+                       c += 10000;
                else if ("*".equals(type) || "*".equals(o.type))
-                       c1 += 5000;
+                       c += 5000;
 
-               if (c1 == 0)
+               if (c == 0)
                        return 0;
 
-               // Give type slightly higher comparison value than subtype 
simply for deterministic results.
-               if (subType.equals(o.subType))
-                       return c1 + 9999;
-
-               int c3 = 0;
+               // Subtypes match but are ordered different
+               if (ArrayUtils.equals(subTypesSorted, o.subTypesSorted))
+                       return c + 7500;
 
                for (String st1 : subTypes) {
                        if ("*".equals(st1))
-                               c1++;
+                               c += 0;
                        else if (ArrayUtils.contains(st1, o.subTypes))
-                               c1 += 100;
-                       else if (ArrayUtils.contains("*", o.subTypes))
-                               c1 += 10;
+                               c += 100;
+                       else if (o.hasSubtypeMeta)
+                               c += 10;
                        else
                                return 0;
                }
+               for (String st2 : o.subTypes) {
+                       if ("*".equals(st2))
+                               c += 0;
+                       else if (ArrayUtils.contains(st2, subTypes))
+                               c += 100;
+                       else if (hasSubtypeMeta)
+                               c += 10;
+                       else if (! allowExtraSubTypes)
+                               return 0;
+                       else
+                               c += 10;
+               }
 
-               return c1 + c2 + c3;
+               return c;
        }
 
        /**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java
index 0267b3d..0cdfd99 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java
@@ -278,17 +278,4 @@ public final class MediaTypeRange implements 
Comparable<MediaTypeRange>  {
                int i = o.mediaType.toString().compareTo(mediaType.toString());
                return i;
        }
-
-       /**
-        * Matches the specified media type against this range and returns a 
q-value between 0 and 1 indicating the
-        * quality of the match.
-        *
-        * @param o The media type to match against.
-        * @return A float between 0 and 1.  1 is a perfect match.  0 is no 
match at all.
-        */
-       public float matches(MediaType o) {
-               if (this.mediaType == o || mediaType.matches(o))
-                       return qValue;
-               return 0;
-       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java
index c088cf8..9221bff 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java
@@ -416,4 +416,20 @@ public final class ArrayUtils {
                        r[i++] = StringUtils.toString(o);
                return r;
        }
+
+       /**
+        * Returns <jk>true</jk> if the following sorted arrays are equals.
+        *
+        * @param a1 Array #1.
+        * @param a2 Array #2.
+        * @return <jk>true</jk> if the following sorted arrays are equals.
+        */
+       public static boolean equals(String[] a1, String[] a2) {
+               if (a1.length != a2.length)
+                       return false;
+               for (int i = 0; i < a1.length; i++)
+                       if (! StringUtils.isEquals(a1[i], a2[i]))
+                               return false;
+               return true;
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
index ba25f7a..a42684c 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
@@ -456,7 +456,13 @@ public final class ClassUtils {
                        oc = oc.getSuperclass();
                }
 
-               ParameterizedType opt = 
(ParameterizedType)oc.getGenericSuperclass();
+               Type gsc = oc.getGenericSuperclass();
+               
+               // Not actually a parameterized type.
+               if (! (gsc instanceof ParameterizedType))
+                       return Object.class;
+
+               ParameterizedType opt = (ParameterizedType)gsc;
                Type actualType = opt.getActualTypeArguments()[index];
 
                if (typeMap.containsKey(actualType))

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
index 6cb332a..00eeae4 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
@@ -109,8 +109,8 @@ public final class JsonParserSession extends 
ReaderParserSession {
 
                if (eType == null)
                        eType = (ClassMeta<T>)object();
-               PojoSwap<T,Object> transform = 
(PojoSwap<T,Object>)eType.getPojoSwap();
-               ClassMeta<?> sType = eType.getSerializedClassMeta();
+               PojoSwap<T,Object> swap = 
(PojoSwap<T,Object>)eType.getPojoSwap(this);
+               ClassMeta<?> sType = swap == null ? eType : 
swap.getSwapClassMeta(this);
                setCurrentClass(sType);
                String wrapperAttr = 
sType.getExtendedMeta(JsonClassMeta.class).getWrapperAttr();
 
@@ -205,8 +205,8 @@ public final class JsonParserSession extends 
ReaderParserSession {
                if (wrapperAttr != null)
                        skipWrapperAttrEnd(r);
 
-               if (transform != null && o != null)
-                       o = transform.unswap(this, o, eType);
+               if (swap != null && o != null)
+                       o = swap.unswap(this, o, eType);
 
                if (outer != null)
                        setParent(eType, o, outer);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java
index 17e3a31..9a782ae 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java
@@ -72,7 +72,7 @@ public class JsonSchemaSerializerSession extends 
JsonSerializerSession {
 
                aType = push(attrName, eType, null);
 
-               sType = eType.getSerializedClassMeta();
+               sType = eType.getSerializedClassMeta(this);
                String type = null;
 
                if (sType.isEnum() || sType.isCharSequence() || sType.isChar())
@@ -90,7 +90,7 @@ public class JsonSchemaSerializerSession extends 
JsonSerializerSession {
 
                out.put("type", type);
                out.put("description", eType.toString());
-               PojoSwap f = eType.getPojoSwap();
+               PojoSwap f = eType.getPojoSwap(this);
                if (f != null)
                        out.put("transform", f);
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
index 0709660..5336f7b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -148,7 +148,7 @@ public class JsonSerializer extends WriterSerializer {
                                        .append(JSON_simpleMode, true)
                                        .append(SERIALIZER_quoteChar, '\''),
                                "application/json",
-                               "application/json+simple", "text/json+simple"
+                               "application/json+simple", 
"application/json+simple+*", "text/json+simple", "text/json+simple+*"
                        );
                }
        }
@@ -204,7 +204,7 @@ public class JsonSerializer extends WriterSerializer {
         *      The property store containing all the settings for this object.
         */
        public JsonSerializer(PropertyStore propertyStore) {
-               this(propertyStore, "application/json", "application/json", 
"text/json");
+               this(propertyStore, "application/json", "application/json", 
"application/json+*", "text/json", "text/json+*");
        }
 
        /**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
index c9266a2..e1eeec0 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
@@ -94,13 +94,14 @@ public class JsonSerializerSession extends 
WriterSerializerSession {
                        aType = object();
                }
 
-               sType = aType.getSerializedClassMeta();
+               sType = aType;
                String typeName = getBeanTypeName(eType, aType, pMeta);
 
                // Swap if necessary
-               PojoSwap swap = aType.getPojoSwap();
+               PojoSwap swap = aType.getPojoSwap(this);
                if (swap != null) {
                        o = swap.swap(this, o);
+                       sType = swap.getSwapClassMeta(this);
 
                        // If the getSwapClass() method returns Object, we need 
to figure out
                        // the actual type now.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
index 8827370..bd4e708 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
@@ -57,8 +57,8 @@ public final class MsgPackParserSession extends 
InputStreamParserSession {
 
                if (eType == null)
                        eType = (ClassMeta<T>)object();
-               PojoSwap<T,Object> transform = 
(PojoSwap<T,Object>)eType.getPojoSwap();
-               ClassMeta<?> sType = eType.getSerializedClassMeta();
+               PojoSwap<T,Object> swap = 
(PojoSwap<T,Object>)eType.getPojoSwap(this);
+               ClassMeta<?> sType = swap == null ? eType : 
swap.getSwapClassMeta(this);
                setCurrentClass(sType);
 
                Object o = null;
@@ -186,8 +186,8 @@ public final class MsgPackParserSession extends 
InputStreamParserSession {
                        }
                }
 
-               if (transform != null && o != null)
-                       o = transform.unswap(this, o, eType);
+               if (swap != null && o != null)
+                       o = swap.unswap(this, o, eType);
 
                if (outer != null)
                        setParent(eType, o, outer);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
index 9b81a16..6a2f4f4 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
@@ -107,13 +107,14 @@ public final class MsgPackSerializerSession extends 
OutputStreamSerializerSessio
                        aType = object();
                }
 
-               sType = aType.getSerializedClassMeta();
+               sType = aType;
                String typeName = getBeanTypeName(eType, aType, pMeta);
 
                // Swap if necessary
-               PojoSwap swap = aType.getPojoSwap();
+               PojoSwap swap = aType.getPojoSwap(this);
                if (swap != null) {
                        o = swap.swap(this, o);
+                       sType = swap.getSwapClassMeta(this);
 
                        // If the getSwapClass() method returns Object, we need 
to figure out
                        // the actual type now.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
index cbb2a85..7992a2e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -692,8 +692,8 @@ public abstract class ParserSession extends BeanSession {
 
                if (type == null)
                        type = (ClassMeta<T>)object();
-               PojoSwap transform = type.getPojoSwap();
-               ClassMeta<?> sType = type.getSerializedClassMeta();
+               PojoSwap swap = type.getPojoSwap(this);
+               ClassMeta<?> sType = swap == null ? type : 
swap.getSwapClassMeta(this);
 
                Object o = s;
                if (sType.isChar())
@@ -712,8 +712,8 @@ public abstract class ParserSession extends BeanSession {
                                throw new ParseException(getLastLocation(), 
"Invalid conversion from string to class ''{0}''", type);
                }
 
-               if (transform != null)
-                       o = transform.unswap(this, o, type);
+               if (swap != null)
+                       o = swap.unswap(this, o, type);
 
                return (T)o;
        }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index a243fcc..450fc2f 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -535,7 +535,7 @@ public abstract class SerializerSession extends BeanSession 
{
                try {
                        if (o == null)
                                return null;
-                       PojoSwap f = (type == null || type.isObject() ? 
getClassMeta(o.getClass()).getPojoSwap() : type.getPojoSwap());
+                       PojoSwap f = (type == null || type.isObject() ? 
getClassMeta(o.getClass()).getPojoSwap(this) : type.getPojoSwap(this));
                        if (f == null)
                                return o;
                        return f.swap(this, o);
@@ -744,8 +744,8 @@ public abstract class SerializerSession extends BeanSession 
{
                        StringBuilder sb = new 
StringBuilder().append('[').append(depth).append(']');
                        sb.append(isEmpty(name) ? "<noname>" : 
name).append(':');
                        sb.append(aType.toString(simple));
-                       if (aType != aType.getSerializedClassMeta())
-                               
sb.append('/').append(aType.getSerializedClassMeta().toString(simple));
+                       if (aType != aType.getSerializedClassMeta(null))
+                               
sb.append('/').append(aType.getSerializedClassMeta(null).toString(simple));
                        return sb.toString();
                }
        }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
index 8db7b53..d3d7859 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
@@ -17,6 +17,8 @@ import static org.apache.juneau.internal.ClassUtils.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
 
@@ -114,25 +116,31 @@ import org.apache.juneau.serializer.*;
  * @param <T> The normal form of the class.
  * @param <S> The swapped form of the class.
  */
+@SuppressWarnings({"unchecked","rawtypes","hiding"})
 public abstract class PojoSwap<T,S> {
 
        /**
         * Represents a non-existent pojo swap.
         */
-       @SuppressWarnings({ "unchecked", "rawtypes" })
-       public final static PojoSwap NULL = new PojoSwap(null, null) {};
+       public final static PojoSwap NULL = new PojoSwap((Class)null, 
(Class)null) {};
 
        private final Class<T> normalClass;
        private final Class<?> swapClass;
        private ClassMeta<?> swapClassMeta;
 
+       // Unfortunately these cannot be made final because we want to allow 
for PojoSwaps with no-arg constructors
+       // which simplifies
+       private MediaType[] forMediaTypes;
+       private String template;
+
        /**
         * Constructor.
         */
-       @SuppressWarnings("unchecked")
        protected PojoSwap() {
                normalClass = (Class<T>)resolveParameterType(PojoSwap.class, 0, 
this.getClass());
                swapClass = resolveParameterType(PojoSwap.class, 1, 
this.getClass());
+               forMediaTypes = forMediaTypes();
+               template = withTemplate();
        }
 
        /**
@@ -144,6 +152,49 @@ public abstract class PojoSwap<T,S> {
        protected PojoSwap(Class<T> normalClass, Class<?> swapClass) {
                this.normalClass = normalClass;
                this.swapClass = swapClass;
+               this.forMediaTypes = forMediaTypes();
+               this.template = withTemplate();
+       }
+
+       protected MediaType[] forMediaTypes() {
+               return null;
+       }
+
+       protected String withTemplate() {
+               return null;
+       }
+
+       public PojoSwap<T,?> forMediaTypes(MediaType[] mediaTypes) {
+               if (mediaTypes != null && mediaTypes.length > 0)
+                       this.forMediaTypes = mediaTypes;
+               return this;
+       }
+
+       public PojoSwap<T,?> withTemplate(String template) {
+               if (! StringUtils.isEmpty(template))
+                       this.template = template;
+               return this;
+       }
+
+//     /**
+//      * Returns <jk>true</jk> if this swap is valid for the specified 
session.
+//      *
+//      * <p>
+//      * If the swap has a media type associated with it, this method ensures 
that the media type matches the media
+//      * type defined on the session.
+//      *
+//      * @param session The bean session.
+//      * @return <jk>true</jk> if this swap is valid for the specified 
session.
+//      */
+       public int match(BeanSession session) {
+               if (forMediaTypes == null)
+                       return 1;
+               int i = 0;
+               MediaType mt = session.getMediaType();
+               if (forMediaTypes != null)
+                       for (MediaType mt2 : forMediaTypes)
+                               i = Math.max(i, mt2.match(mt, false)*2);
+               return i;
        }
 
        /**
@@ -176,6 +227,22 @@ public abstract class PojoSwap<T,S> {
         * @throws Exception If a problem occurred trying to convert the output.
         */
        public S swap(BeanSession session, T o) throws Exception {
+               return swap(session, o, template);
+       }
+
+       /**
+        * Same as {@link #swap(BeanSession, Object)}, but can be used if your 
swap has a template associated with it.
+        *
+        * @param session
+        *      The bean session to use to get the class meta.
+        *      This is always going to be the same bean context that created 
this swap.
+        * @param o The object to be transformed.
+        * @param template
+        *      The template string associated with this swap.
+        * @return The transformed object.
+        * @throws Exception If a problem occurred trying to convert the output.
+        */
+       public S swap(BeanSession session, T o, String template) throws 
Exception {
                throw new SerializeException("Swap method not implemented on 
PojoSwap ''{0}''", this.getClass().getName());
        }
 
@@ -195,6 +262,27 @@ public abstract class PojoSwap<T,S> {
         * @throws Exception If this method is not implemented.
         */
        public T unswap(BeanSession session, S f, ClassMeta<?> hint) throws 
Exception {
+               return unswap(session, f, hint, template);
+       }
+
+       /**
+        * Same as {@link #unswap(BeanSession, Object, ClassMeta)}, but can be 
used if your swap has a template associated with it.
+        *
+        * @param session
+        *      The bean session to use to get the class meta.
+        *      This is always going to be the same bean context that created 
this swap.
+        * @param f The transformed object.
+        * @param hint
+        *      If possible, the parser will try to tell you the object type 
being created.
+        *      For example, on a serialized date, this may tell you that the 
object being created must be of type
+        *      {@code GregorianCalendar}.
+        *      <br>This may be <jk>null</jk> if the parser cannot make this 
determination.
+        * @param template
+        *      The template string associated with this swap.
+        * @return The transformed object.
+        * @throws Exception If a problem occurred trying to convert the output.
+        */
+       public T unswap(BeanSession session, S f, ClassMeta<?> hint, String 
template) throws Exception {
                throw new ParseException("Unswap method not implemented on 
PojoSwap ''{0}''", this.getClass().getName());
        }
 
@@ -226,14 +314,14 @@ public abstract class PojoSwap<T,S> {
         * <p>
         * This value is cached for quick lookup.
         *
-        * @param beanContext
+        * @param session
         *      The bean context to use to get the class meta.
         *      This is always going to be the same bean context that created 
this swap.
         * @return The {@link ClassMeta} of the transformed class type.
         */
-       public ClassMeta<?> getSwapClassMeta(BeanContext beanContext) {
+       public ClassMeta<?> getSwapClassMeta(BeanSession session) {
                if (swapClassMeta == null)
-                       swapClassMeta = beanContext.getClassMeta(swapClass);
+                       swapClassMeta = session.getClassMeta(swapClass);
                return swapClassMeta;
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
index 9f731d4..c4974cd 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
@@ -122,8 +122,8 @@ public class UonParserSession extends ReaderParserSession {
 
                if (eType == null)
                        eType = (ClassMeta<T>)object();
-               PojoSwap<T,Object> transform = 
(PojoSwap<T,Object>)eType.getPojoSwap();
-               ClassMeta<?> sType = eType.getSerializedClassMeta();
+               PojoSwap<T,Object> swap = 
(PojoSwap<T,Object>)eType.getPojoSwap(this);
+               ClassMeta<?> sType = swap == null ? eType : 
swap.getSwapClassMeta(this);
 
                Object o = null;
 
@@ -248,8 +248,8 @@ public class UonParserSession extends ReaderParserSession {
 
                if (o == null && sType.isPrimitive())
                        o = sType.getPrimitiveDefault();
-               if (transform != null && o != null)
-                       o = transform.unswap(this, o, eType);
+               if (swap != null && o != null)
+                       o = swap.unswap(this, o, eType);
 
                if (outer != null)
                        setParent(eType, o, outer);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
index b6e8952..7730f1b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
@@ -129,13 +129,14 @@ public class UonSerializerSession extends 
WriterSerializerSession {
                        aType = object();
                }
 
-               sType = aType.getSerializedClassMeta();
+               sType = aType;
                String typeName = getBeanTypeName(eType, aType, pMeta);
 
                // Swap if necessary
-               PojoSwap swap = aType.getPojoSwap();
+               PojoSwap swap = aType.getPojoSwap(this);
                if (swap != null) {
                        o = swap.swap(this, o);
+                       sType = swap.getSwapClassMeta(this);
 
                        // If the getSwapClass() method returns Object, we need 
to figure out
                        // the actual type now.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
index f2a0c98..a3ebea4 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
@@ -59,7 +59,7 @@ public class UrlEncodingParserSession extends 
UonParserSession {
         * @return <jk>true</jk> if the specified bean property should be 
expanded as multiple key-value pairs.
         */
        public final boolean shouldUseExpandedParams(BeanPropertyMeta pMeta) {
-               ClassMeta<?> cm = pMeta.getClassMeta();
+               ClassMeta<?> cm = 
pMeta.getClassMeta().getSerializedClassMeta(this);
                if (cm.isCollectionOrArray()) {
                        if (expandedParams)
                                return true;
@@ -89,8 +89,8 @@ public class UrlEncodingParserSession extends 
UonParserSession {
 
                if (eType == null)
                        eType = (ClassMeta<T>)object();
-               PojoSwap<T,Object> transform = 
(PojoSwap<T,Object>)eType.getPojoSwap();
-               ClassMeta<?> sType = eType.getSerializedClassMeta();
+               PojoSwap<T,Object> swap = 
(PojoSwap<T,Object>)eType.getPojoSwap(this);
+               ClassMeta<?> sType = swap == null ? eType : 
swap.getSwapClassMeta(this);
 
                int c = r.peekSkipWs();
                if (c == '?')
@@ -139,8 +139,8 @@ public class UrlEncodingParserSession extends 
UonParserSession {
                        }
                }
 
-               if (transform != null && o != null)
-                       o = transform.unswap(this, o, eType);
+               if (swap != null && o != null)
+                       o = swap.unswap(this, o, eType);
 
                if (outer != null)
                        setParent(eType, o, outer);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
index cce9b4d..90e6b09 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
@@ -62,7 +62,7 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
         * Returns <jk>true</jk> if the specified bean property should be 
expanded as multiple key-value pairs.
         */
        private boolean shouldUseExpandedParams(BeanPropertyMeta pMeta) {
-               ClassMeta<?> cm = pMeta.getClassMeta();
+               ClassMeta<?> cm = 
pMeta.getClassMeta().getSerializedClassMeta(this);
                if (cm.isCollectionOrArray()) {
                        if (expandedParams)
                                return true;
@@ -78,7 +78,7 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
        private boolean shouldUseExpandedParams(Object value) {
                if (value == null || ! expandedParams)
                        return false;
-               ClassMeta<?> cm = 
getClassMetaForObject(value).getSerializedClassMeta();
+               ClassMeta<?> cm = 
getClassMetaForObject(value).getSerializedClassMeta(this);
                if (cm.isCollectionOrArray()) {
                        if (expandedParams)
                                return true;
@@ -104,13 +104,14 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
                if (aType == null)
                        aType = object();
 
-               sType = aType.getSerializedClassMeta();
+               sType = aType;
                String typeName = getBeanTypeName(object(), aType, null);
 
                // Swap if necessary
-               PojoSwap swap = aType.getPojoSwap();
+               PojoSwap swap = aType.getPojoSwap(this);
                if (swap != null) {
                        o = swap.swap(this, o);
+                       sType = swap.getSwapClassMeta(this);
 
                        // If the getSwapClass() method returns Object, we need 
to figure out
                        // the actual type now.
@@ -218,6 +219,7 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
                for (BeanPropertyValue p : m.getValues(isTrimNulls(), typeName 
!= null ? createBeanTypeNameProperty(m, typeName) : null)) {
                        BeanPropertyMeta pMeta = p.getMeta();
                        ClassMeta<?> cMeta = p.getClassMeta();
+                       ClassMeta<?> sMeta = cMeta.getSerializedClassMeta(this);
 
                        String key = p.getName();
                        Object value = p.getValue();
@@ -225,13 +227,13 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
                        if (t != null)
                                onBeanGetterException(pMeta, t);
 
-                       if (canIgnoreValue(cMeta, key, value))
+                       if (canIgnoreValue(sMeta, key, value))
                                continue;
 
                        if (value != null && shouldUseExpandedParams(pMeta)) {
                                // Transformed object array bean properties may 
be transformed resulting in ArrayLists,
                                // so we need to check type if we think it's an 
array.
-                               Iterator i = (cMeta.isCollection() || value 
instanceof Collection) ? ((Collection)value).iterator() : iterator(value);
+                               Iterator i = (sMeta.isCollection() || value 
instanceof Collection) ? ((Collection)value).iterator() : iterator(value);
                                while (i.hasNext()) {
                                        if (addAmp)
                                                out.cr(indent).append('&');

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
index 2a70b52..2b0cfcb 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
@@ -283,8 +283,8 @@ public class XmlParserSession extends ReaderParserSession {
 
                if (eType == null)
                        eType = (ClassMeta<T>)object();
-               PojoSwap<T,Object> transform = 
(PojoSwap<T,Object>)eType.getPojoSwap();
-               ClassMeta<?> sType = eType.getSerializedClassMeta();
+               PojoSwap<T,Object> swap = 
(PojoSwap<T,Object>)eType.getPojoSwap(this);
+               ClassMeta<?> sType = swap == null ? eType : 
swap.getSwapClassMeta(this);
                setCurrentClass(sType);
 
                String wrapperAttr = (isRoot && preserveRootElement) ? 
r.getName().getLocalPart() : null;
@@ -377,8 +377,8 @@ public class XmlParserSession extends ReaderParserSession {
                                sType.getInnerClass().getName(), 
sType.getNotABeanReason(), pMeta == null ? null : pMeta.getName());
                }
 
-               if (transform != null && o != null)
-                       o = transform.unswap(this, o, eType);
+               if (swap != null && o != null)
+                       o = swap.unswap(this, o, eType);
 
                if (outer != null)
                        setParent(eType, o, outer);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerSession.java
index 6de01ec..1046630 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerSession.java
@@ -62,7 +62,7 @@ public class XmlSchemaSerializerSession extends 
XmlSerializerSession {
                Namespace xs = xsNamespace;
                Namespace[] allNs = append(new Namespace[]{defaultNamespace}, 
namespaces);
 
-               Schemas schemas = new Schemas(xs, defaultNamespace, allNs);
+               Schemas schemas = new Schemas(this, xs, defaultNamespace, 
allNs);
                schemas.process(o);
                schemas.serializeTo(out.getWriter());
        }
@@ -144,12 +144,14 @@ public class XmlSchemaSerializerSession extends 
XmlSerializerSession {
                private static final long serialVersionUID = 1L;
 
                private Namespace defaultNs;
+               private BeanSession session;
                private LinkedList<QueueEntry>
                        elementQueue = new LinkedList<QueueEntry>(),
                        attributeQueue = new LinkedList<QueueEntry>(),
                        typeQueue = new LinkedList<QueueEntry>();
 
-               private Schemas(Namespace xs, Namespace defaultNs, Namespace[] 
allNs) throws IOException {
+               private Schemas(BeanSession session, Namespace xs, Namespace 
defaultNs, Namespace[] allNs) throws IOException {
+                       this.session = session;
                        this.defaultNs = defaultNs;
                        for (Namespace ns : allNs)
                                put(ns, new Schema(this, xs, ns, defaultNs, 
allNs));
@@ -264,7 +266,7 @@ public class XmlSchemaSerializerSession extends 
XmlSerializerSession {
                                return false;
                        processedElements.add(name);
 
-                       ClassMeta<?> ft = cm.getSerializedClassMeta();
+                       ClassMeta<?> ft = 
cm.getSerializedClassMeta(schemas.session);
                        if (name == null)
                                name = getElementName(ft);
                        Namespace ns = 
first(ft.getExtendedMeta(XmlClassMeta.class).getNamespace(), defaultNs);
@@ -302,7 +304,7 @@ public class XmlSchemaSerializerSession extends 
XmlSerializerSession {
 
                        int i = indent + 1;
 
-                       cm = cm.getSerializedClassMeta();
+                       cm = cm.getSerializedClassMeta(schemas.session);
                        XmlBeanMeta xbm = cm.isBean() ? 
cm.getBeanMeta().getExtendedMeta(XmlBeanMeta.class) : null;
 
                        w.oTag(i, "complexType")
@@ -477,7 +479,7 @@ public class XmlSchemaSerializerSession extends 
XmlSerializerSession {
                }
 
                private String getElementName(ClassMeta<?> cm) {
-                       cm = cm.getSerializedClassMeta();
+                       cm = cm.getSerializedClassMeta(schemas.session);
                        String name = cm.getDictionaryName();
 
                        if (name == null) {
@@ -507,7 +509,7 @@ public class XmlSchemaSerializerSession extends 
XmlSerializerSession {
 
                private String getXmlType(Namespace currentNs, ClassMeta<?> cm) 
{
                        String name = null;
-                       cm = cm.getSerializedClassMeta();
+                       cm = cm.getSerializedClassMeta(schemas.session);
                        if (currentNs == targetNs) {
                                if (cm.isPrimitive()) {
                                        if (cm.isBoolean())

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
index d1c348d..cf78f14 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
@@ -302,12 +302,13 @@ public class XmlSerializerSession extends 
WriterSerializerSession {
                                eType = aType = ((Delegate<?>)o).getClassMeta();
                        }
 
-                       sType = aType.getSerializedClassMeta();
+                       sType = aType;
 
                        // Swap if necessary
-                       PojoSwap swap = aType.getPojoSwap();
+                       PojoSwap swap = aType.getPojoSwap(this);
                        if (swap != null) {
                                o = swap.swap(this, o);
+                               sType = swap.getSwapClassMeta(this);
 
                                // If the getSwapClass() method returns Object, 
we need to figure out
                                // the actual type now.
@@ -315,7 +316,7 @@ public class XmlSerializerSession extends 
WriterSerializerSession {
                                        sType = getClassMetaForObject(o);
                        }
                } else {
-                       sType = eType.getSerializedClassMeta();
+                       sType = eType.getSerializedClassMeta(this);
                }
 
                // Does the actual type match the expected type?

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
index b7f0dd1..c26a2d1 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
@@ -17,6 +17,7 @@ import static javax.servlet.http.HttpServletResponse.*;
 import org.apache.juneau.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.rest.*;
+import org.apache.juneau.transform.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -54,8 +55,10 @@ public final class Introspectable implements RestConverter {
                if (method == null)
                        return o;
                try {
-                       if (cm.getPojoSwap() != null)
-                               o = cm.getPojoSwap().swap(req.getBeanSession(), 
o);
+                       BeanSession bs = req.getBeanSession();
+                       PojoSwap swap = cm.getPojoSwap(bs);
+                       if (swap != null)
+                               o = swap.swap(bs, o);
                        return new PojoIntrospector(o, 
JsonParser.DEFAULT).invokeMethod(method, args);
                } catch (Exception e) {
                        e.printStackTrace();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Traversable.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Traversable.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Traversable.java
index d551aa3..4768da2 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Traversable.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converters/Traversable.java
@@ -16,6 +16,7 @@ import javax.servlet.http.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.rest.*;
+import org.apache.juneau.transform.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -53,8 +54,10 @@ public final class Traversable implements RestConverter {
 
                if (req.getPathMatch().getRemainder() != null) {
                        try {
-                               if (cm.getPojoSwap() != null)
-                                       o = 
cm.getPojoSwap().swap(req.getBeanSession(), o);
+                               BeanSession bs = req.getBeanSession();
+                               PojoSwap swap = cm.getPojoSwap(bs);
+                               if (swap != null)
+                                       o = swap.swap(bs, o);
                                PojoRest p = new PojoRest(o, 
req.getBody().getReaderParser());
                                o = p.get(req.getPathMatch().getRemainder());
                        } catch (PojoRestException e) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/labels/BeanDescription.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/labels/BeanDescription.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/labels/BeanDescription.java
index 96c7904..327c220 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/labels/BeanDescription.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/labels/BeanDescription.java
@@ -67,7 +67,7 @@ public final class BeanDescription {
                 */
                public BeanPropertyDescription(String name, ClassMeta<?> type) {
                        this.name = name;
-                       this.type = type.getSerializedClassMeta().toString();
+                       this.type = 
type.getSerializedClassMeta(null).toString();
                }
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-rest/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/pojos/SwappedPojo.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/pojos/SwappedPojo.java
 
b/juneau-rest/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/pojos/SwappedPojo.java
index 25d914c..6d38a7c 100644
--- 
a/juneau-rest/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/pojos/SwappedPojo.java
+++ 
b/juneau-rest/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/pojos/SwappedPojo.java
@@ -14,7 +14,7 @@ package org.apache.juneau.rest.test.pojos;
 
 import org.apache.juneau.annotation.*;
 
-@Pojo(swap=SwappedPojoSwap.class)
+@Swap(SwappedPojoSwap.class)
 public class SwappedPojo {
        public boolean wasUnswapped;
 }
\ No newline at end of file


Reply via email to