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 2017/09/04 23:54:07 UTC
[2/2] incubator-juneau git commit: Add multi-swap support (part 1).
Add multi-swap support (part 1).
Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/495c648d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/495c648d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/495c648d
Branch: refs/heads/master
Commit: 495c648d1f8934ebb41ae93c2b9d541371de2dd6
Parents: fc1e3fc
Author: JamesBognar <ja...@apache.org>
Authored: Mon Sep 4 19:54:11 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Mon Sep 4 19:54:11 2017 -0400
----------------------------------------------------------------------
.../java/org/apache/juneau/ClassMetaTest.java | 148 +++---
.../a/rttests/RoundTripTransformBeansTest.java | 2 +-
.../org/apache/juneau/https/AcceptTest.java | 74 ++-
.../juneau/serializer/SerializerGroupTest.java | 6 +-
.../apache/juneau/test/pojos/SwappedPojo.java | 2 +-
.../juneau/transforms/ReaderObjectSwapTest.java | 8 +-
.../transforms/SwapsAnnotationComboTest.java | 478 +++++++++++++++++++
.../apache/juneau/jena/RdfParserSession.java | 8 +-
.../juneau/jena/RdfSerializerSession.java | 7 +-
.../org/apache/juneau/BeanPropertyMeta.java | 2 +-
.../java/org/apache/juneau/BeanSession.java | 16 +-
.../main/java/org/apache/juneau/ClassMeta.java | 129 +++--
.../java/org/apache/juneau/annotation/Pojo.java | 84 ----
.../java/org/apache/juneau/annotation/Swap.java | 31 ++
.../org/apache/juneau/annotation/Swaps.java | 27 ++
.../apache/juneau/html/HtmlParserSession.java | 4 +-
.../html/HtmlSchemaDocSerializerSession.java | 4 +-
.../juneau/html/HtmlSerializerSession.java | 33 +-
.../java/org/apache/juneau/http/Accept.java | 3 +-
.../org/apache/juneau/http/ContentType.java | 2 +-
.../java/org/apache/juneau/http/MediaType.java | 120 +++--
.../org/apache/juneau/http/MediaTypeRange.java | 13 -
.../org/apache/juneau/internal/ArrayUtils.java | 16 +
.../org/apache/juneau/internal/ClassUtils.java | 8 +-
.../apache/juneau/json/JsonParserSession.java | 8 +-
.../json/JsonSchemaSerializerSession.java | 4 +-
.../org/apache/juneau/json/JsonSerializer.java | 4 +-
.../juneau/json/JsonSerializerSession.java | 5 +-
.../juneau/msgpack/MsgPackParserSession.java | 8 +-
.../msgpack/MsgPackSerializerSession.java | 5 +-
.../org/apache/juneau/parser/ParserSession.java | 8 +-
.../juneau/serializer/SerializerSession.java | 6 +-
.../org/apache/juneau/transform/PojoSwap.java | 100 +++-
.../org/apache/juneau/uon/UonParserSession.java | 8 +-
.../apache/juneau/uon/UonSerializerSession.java | 5 +-
.../urlencoding/UrlEncodingParserSession.java | 10 +-
.../UrlEncodingSerializerSession.java | 14 +-
.../org/apache/juneau/xml/XmlParserSession.java | 8 +-
.../juneau/xml/XmlSchemaSerializerSession.java | 14 +-
.../apache/juneau/xml/XmlSerializerSession.java | 7 +-
.../juneau/rest/converters/Introspectable.java | 7 +-
.../juneau/rest/converters/Traversable.java | 7 +-
.../juneau/rest/labels/BeanDescription.java | 2 +-
.../juneau/rest/test/pojos/SwappedPojo.java | 2 +-
44 files changed, 1081 insertions(+), 376 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java
index e01e5d5..4559d78 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java
@@ -114,8 +114,10 @@ public class ClassMetaTest {
public void testSwaps() throws Exception {
BeanContext bc;
ClassMeta<?> ooo, hi1, hc1, hi2, hc2;
+ BeanSession bs;
bc = PropertyStore.create().getBeanContext();
+ bs = bc.createSession();
ooo = bc.getClassMeta(Object.class);
hi1 = bc.getClassMeta(HI1.class);
hc1 = bc.getClassMeta(HC1.class);
@@ -126,18 +128,19 @@ public class ClassMetaTest {
assertFalse(hc1.hasChildPojoSwaps());
assertFalse(hi2.hasChildPojoSwaps());
assertFalse(hc2.hasChildPojoSwaps());
- assertNull(ooo.getPojoSwap());
- assertNull(hi1.getPojoSwap());
- assertNull(hc1.getPojoSwap());
- assertNull(hi2.getPojoSwap());
- assertNull(hc2.getPojoSwap());
- assertEquals(ooo.getSerializedClassMeta().getInnerClass(), Object.class);
- assertEquals(hi1.getSerializedClassMeta().getInnerClass(), HI1.class);
- assertEquals(hc1.getSerializedClassMeta().getInnerClass(), HC1.class);
- assertEquals(hi2.getSerializedClassMeta().getInnerClass(), HI2.class);
- assertEquals(hc2.getSerializedClassMeta().getInnerClass(), HC2.class);
+ assertNull(ooo.getPojoSwap(bs));
+ assertNull(hi1.getPojoSwap(bs));
+ assertNull(hc1.getPojoSwap(bs));
+ assertNull(hi2.getPojoSwap(bs));
+ assertNull(hc2.getPojoSwap(bs));
+ assertEquals(ooo.getSerializedClassMeta(bs).getInnerClass(), Object.class);
+ assertEquals(hi1.getSerializedClassMeta(bs).getInnerClass(), HI1.class);
+ assertEquals(hc1.getSerializedClassMeta(bs).getInnerClass(), HC1.class);
+ assertEquals(hi2.getSerializedClassMeta(bs).getInnerClass(), HI2.class);
+ assertEquals(hc2.getSerializedClassMeta(bs).getInnerClass(), HC2.class);
bc = PropertyStore.create().setPojoSwaps(HI1Swap.class).getBeanContext();
+ bs = bc.createSession();
ooo = bc.getClassMeta(Object.class);
hi1 = bc.getClassMeta(HI1.class);
hc1 = bc.getClassMeta(HC1.class);
@@ -148,18 +151,19 @@ public class ClassMetaTest {
assertFalse(hc1.hasChildPojoSwaps());
assertFalse(hi2.hasChildPojoSwaps());
assertFalse(hc2.hasChildPojoSwaps());
- assertNull(ooo.getPojoSwap());
- assertEquals(hi1.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(hc1.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(hi2.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(hc2.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(ooo.getSerializedClassMeta().getInnerClass(), Object.class);
- assertEquals(hi1.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hc1.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hi2.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
+ assertNull(ooo.getPojoSwap(bs));
+ assertEquals(hi1.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(hc1.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(hi2.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(hc2.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(ooo.getSerializedClassMeta(bs).getInnerClass(), Object.class);
+ assertEquals(hi1.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hc1.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hi2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hc2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
bc = PropertyStore.create().setPojoSwaps(HC1Swap.class).getBeanContext();
+ bs = bc.createSession();
ooo = bc.getClassMeta(Object.class);
hi1 = bc.getClassMeta(HI1.class);
hc1 = bc.getClassMeta(HC1.class);
@@ -170,18 +174,19 @@ public class ClassMetaTest {
assertTrue(hc1.hasChildPojoSwaps());
assertFalse(hi2.hasChildPojoSwaps());
assertFalse(hc2.hasChildPojoSwaps());
- assertNull(ooo.getPojoSwap());
- assertNull(hi1.getPojoSwap());
- assertEquals(hc1.getPojoSwap().getClass(), HC1Swap.class);
- assertNull(hi2.getPojoSwap());
- assertEquals(hc2.getPojoSwap().getClass(), HC1Swap.class);
- assertEquals(ooo.getSerializedClassMeta().getInnerClass(), Object.class);
- assertEquals(hi1.getSerializedClassMeta().getInnerClass(), HI1.class);
- assertEquals(hc1.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hi2.getSerializedClassMeta().getInnerClass(), HI2.class);
- assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
+ assertNull(ooo.getPojoSwap(bs));
+ assertNull(hi1.getPojoSwap(bs));
+ assertEquals(hc1.getPojoSwap(bs).getClass(), HC1Swap.class);
+ assertNull(hi2.getPojoSwap(bs));
+ assertEquals(hc2.getPojoSwap(bs).getClass(), HC1Swap.class);
+ assertEquals(ooo.getSerializedClassMeta(bs).getInnerClass(), Object.class);
+ assertEquals(hi1.getSerializedClassMeta(bs).getInnerClass(), HI1.class);
+ assertEquals(hc1.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hi2.getSerializedClassMeta(bs).getInnerClass(), HI2.class);
+ assertEquals(hc2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
bc = PropertyStore.create().setPojoSwaps(HI2Swap.class).getBeanContext();
+ bs = bc.createSession();
ooo = bc.getClassMeta(Object.class);
hi1 = bc.getClassMeta(HI1.class);
hc1 = bc.getClassMeta(HC1.class);
@@ -192,18 +197,19 @@ public class ClassMetaTest {
assertFalse(hc1.hasChildPojoSwaps());
assertTrue(hi2.hasChildPojoSwaps());
assertFalse(hc2.hasChildPojoSwaps());
- assertNull(ooo.getPojoSwap());
- assertNull(hi1.getPojoSwap());
- assertNull(hc1.getPojoSwap());
- assertEquals(hi2.getPojoSwap().getClass(), HI2Swap.class);
- assertEquals(hc2.getPojoSwap().getClass(), HI2Swap.class);
- assertEquals(ooo.getSerializedClassMeta().getInnerClass(), Object.class);
- assertEquals(hi1.getSerializedClassMeta().getInnerClass(), HI1.class);
- assertEquals(hc1.getSerializedClassMeta().getInnerClass(), HC1.class);
- assertEquals(hi2.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
+ assertNull(ooo.getPojoSwap(bs));
+ assertNull(hi1.getPojoSwap(bs));
+ assertNull(hc1.getPojoSwap(bs));
+ assertEquals(hi2.getPojoSwap(bs).getClass(), HI2Swap.class);
+ assertEquals(hc2.getPojoSwap(bs).getClass(), HI2Swap.class);
+ assertEquals(ooo.getSerializedClassMeta(bs).getInnerClass(), Object.class);
+ assertEquals(hi1.getSerializedClassMeta(bs).getInnerClass(), HI1.class);
+ assertEquals(hc1.getSerializedClassMeta(bs).getInnerClass(), HC1.class);
+ assertEquals(hi2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hc2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
bc = PropertyStore.create().setPojoSwaps(HC2Swap.class).getBeanContext();
+ bs = bc.createSession();
ooo = bc.getClassMeta(Object.class);
hi1 = bc.getClassMeta(HI1.class);
hc1 = bc.getClassMeta(HC1.class);
@@ -214,18 +220,19 @@ public class ClassMetaTest {
assertTrue(hc1.hasChildPojoSwaps());
assertTrue(hi2.hasChildPojoSwaps());
assertTrue(hc2.hasChildPojoSwaps());
- assertNull(ooo.getPojoSwap());
- assertNull(hi1.getPojoSwap());
- assertNull(hc1.getPojoSwap());
- assertNull(hi2.getPojoSwap());
- assertEquals(hc2.getPojoSwap().getClass(), HC2Swap.class);
- assertEquals(ooo.getSerializedClassMeta().getInnerClass(), Object.class);
- assertEquals(hi1.getSerializedClassMeta().getInnerClass(), HI1.class);
- assertEquals(hc1.getSerializedClassMeta().getInnerClass(), HC1.class);
- assertEquals(hi2.getSerializedClassMeta().getInnerClass(), HI2.class);
- assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
+ assertNull(ooo.getPojoSwap(bs));
+ assertNull(hi1.getPojoSwap(bs));
+ assertNull(hc1.getPojoSwap(bs));
+ assertNull(hi2.getPojoSwap(bs));
+ assertEquals(hc2.getPojoSwap(bs).getClass(), HC2Swap.class);
+ assertEquals(ooo.getSerializedClassMeta(bs).getInnerClass(), Object.class);
+ assertEquals(hi1.getSerializedClassMeta(bs).getInnerClass(), HI1.class);
+ assertEquals(hc1.getSerializedClassMeta(bs).getInnerClass(), HC1.class);
+ assertEquals(hi2.getSerializedClassMeta(bs).getInnerClass(), HI2.class);
+ assertEquals(hc2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
bc = PropertyStore.create().setPojoSwaps(HI1Swap.class,HC1Swap.class,HI2Swap.class,HC2Swap.class).getBeanContext();
+ bs = bc.createSession();
ooo = bc.getClassMeta(Object.class);
hi1 = bc.getClassMeta(HI1.class);
hc1 = bc.getClassMeta(HC1.class);
@@ -236,18 +243,19 @@ public class ClassMetaTest {
assertTrue(hc1.hasChildPojoSwaps());
assertTrue(hi2.hasChildPojoSwaps());
assertTrue(hc2.hasChildPojoSwaps());
- assertNull(ooo.getPojoSwap());
- assertEquals(hi1.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(hc1.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(hi2.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(hc2.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(ooo.getSerializedClassMeta().getInnerClass(), Object.class);
- assertEquals(hi1.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hc1.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hi2.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
+ assertNull(ooo.getPojoSwap(bs));
+ assertEquals(hi1.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(hc1.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(hi2.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(hc2.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(ooo.getSerializedClassMeta(bs).getInnerClass(), Object.class);
+ assertEquals(hi1.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hc1.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hi2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hc2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
bc = PropertyStore.create().setPojoSwaps(HC2Swap.class,HI2Swap.class,HC1Swap.class,HI1Swap.class).getBeanContext();
+ bs = bc.createSession();
ooo = bc.getClassMeta(Object.class);
hi1 = bc.getClassMeta(HI1.class);
hc1 = bc.getClassMeta(HC1.class);
@@ -258,16 +266,16 @@ public class ClassMetaTest {
assertTrue(hc1.hasChildPojoSwaps());
assertTrue(hi2.hasChildPojoSwaps());
assertTrue(hc2.hasChildPojoSwaps());
- assertNull(ooo.getPojoSwap());
- assertEquals(hi1.getPojoSwap().getClass(), HI1Swap.class);
- assertEquals(hc1.getPojoSwap().getClass(), HC1Swap.class);
- assertEquals(hi2.getPojoSwap().getClass(), HI2Swap.class);
- assertEquals(hc2.getPojoSwap().getClass(), HC2Swap.class);
- assertEquals(ooo.getSerializedClassMeta().getInnerClass(), Object.class);
- assertEquals(hi1.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hc1.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hi2.getSerializedClassMeta().getInnerClass(), Map.class);
- assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
+ assertNull(ooo.getPojoSwap(bs));
+ assertEquals(hi1.getPojoSwap(bs).getClass(), HI1Swap.class);
+ assertEquals(hc1.getPojoSwap(bs).getClass(), HC1Swap.class);
+ assertEquals(hi2.getPojoSwap(bs).getClass(), HI2Swap.class);
+ assertEquals(hc2.getPojoSwap(bs).getClass(), HC2Swap.class);
+ assertEquals(ooo.getSerializedClassMeta(bs).getInnerClass(), Object.class);
+ assertEquals(hi1.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hc1.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hi2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
+ assertEquals(hc2.getSerializedClassMeta(bs).getInnerClass(), Map.class);
}
public interface HI1 {}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java
index 7ea011c..f05026c 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java
@@ -224,7 +224,7 @@ public class RoundTripTransformBeansTest extends RoundTripTest {
assertEquals("bar", t.f1);
}
- @Pojo(swap=BSwap.class)
+ @Swap(BSwap.class)
public static class B {
public String f1;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptTest.java
index 6f44506..d8fb3a7 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptTest.java
@@ -47,17 +47,17 @@ public class AcceptTest {
{ "MetaMatch-1", "text/*", "['text/a','text/b+c','text/b+d+e']", 2 },
{ "MetaMatch-2", "text/b+*", "['text/a','text/b+c','text/b+d+e']", 2 },
{ "MetaMatch-3", "text/c+*", "['text/a','text/b+c','text/b+d+e']", 1 },
- { "MetaMatch-4", "text/b+d+e", "['text/a','text/b+c','text/b+d']", 2 },
- { "MetaMatch-5", "text/b+*", "['text/a','text/b+c','text/b+d']", 1 },
+ { "MetaMatch-4", "text/b+d+e", "['text/a','text/b+c','text/b+d']", -1 },
+ { "MetaMatch-5", "text/b+*", "['text/a','text/b+c','text/b+d+e']", 2 },
{ "MetaMatch-6", "text/d+e+*", "['text/a','text/b+c','text/b+d+e']", 2 },
- { "MetaMatch-7", "*/a", "['text/a','application/a']", 0 },
+ { "MetaMatch-7", "*/a", "['text/a','application/b']", 0 },
{ "MetaMatch-8", "*/*", "['text/a','text/b+c']", 1 },
{ "MetaMatch-9", "*/*", "['text/b+c','text/a']", 0 },
// Reverse meta-character matches
{ "RevMetaMatch-1", "text/a", "['text/*']", 0 },
- { "RevMetaMatch-3", "text/a", "['*/a']", 0 },
+ { "RevMetaMatch-2", "text/a", "['*/a']", 0 },
{ "RevMetaMatch-3", "text/a", "['*/*']", 0 },
// Meta-character mixture matches
@@ -72,28 +72,32 @@ public class AcceptTest {
{ "Fuzzy-1", "text/1+2", "['text/1+2']", 0 },
// Order of subtype parts shouldn't matter.
{ "Fuzzy-2", "text/2+1", "['text/1+2']", 0 },
+
// Should match if Accept has 'extra' subtypes.
// For example, "Accept: text/json+activity" should match against the "text/json" serializer.
- { "Fuzzy-3", "text/1+2", "['text/1']", 0 },
+ { "Fuzzy-3", "text/json+foo", "['text/json+*']", 0 },
+
// Shouldn't match because the accept media type must be at least a subset of the real media type
// For example, "Accept: text/json" should not match against the "text/json+lax" serializer.
- { "Fuzzy-4", "text/1", "['text/1+2']", -1 },
- { "Fuzzy-5", "text/1+2", "['text/1','text/1+3']", 0 },
+ { "Fuzzy-4", "text/json", "['text/json+lax']", -1 },
+
+ { "Fuzzy-5", "text/1+2", "['text/1','text/1+3']", -1 },
+
// "text/1+2" should be a better match than just "text/1"
{ "Fuzzy-6", "text/1+2", "['text/1','text/1+2','text/1+2+3']", 1 },
// Same as last, but mix up the order a bit.
{ "Fuzzy-7", "text/1+2", "['text/1+2+3','text/1','text/1+2']", 2 },
// Same as last, but mix up the order of the subtypes as well.
{ "Fuzzy-8", "text/1+2", "['text/3+2+1','text/1','text/2+1']", 2 },
- { "Fuzzy-9", "text/1+2+3+4", "['text/1+2','text/1+2+3']", 1 },
- { "Fuzzy-10", "text/1+2+3+4", "['text/1+2+3','text/1+2']", 0 },
- { "Fuzzy-11", "text/4+2+3+1", "['text/1+2+3','text/1+2']", 0 },
- { "Fuzzy-12", "text/4+2+3+1", "['text/1+2','text/1+2+3']", 1 },
+ { "Fuzzy-9", "text/1+2+3+4", "['text/1+2','text/1+2+3']", -1 },
+ { "Fuzzy-10", "text/1+2+3+4", "['text/1+2+3','text/1+2']", -1 },
+ { "Fuzzy-11", "text/4+2+3+1", "['text/1+2+3','text/1+2']", -1 },
+ { "Fuzzy-12", "text/4+2+3+1", "['text/1+2','text/1+2+3']", -1 },
// Q metrics
{ "Q-1", "text/A;q=0.9,text/B;q=0.1", "['text/A','text/B']", 0 },
{ "Q-2", "text/A;q=0.9,text/B;q=0.1", "['text/B','text/A']", 1 },
- { "Q-3", "text/A+1;q=0.9,text/B;q=0.1", "['text/A','text/B']", 0 },
+ { "Q-3", "text/A+1;q=0.9,text/B;q=0.1", "['text/A','text/B']", 1 },
{ "Q-4", "text/A;q=0.9,text/B+1;q=0.1", "['text/A','text/B+1']", 0 },
{ "Q-5", "text/A;q=0.9,text/A+1;q=0.1", "['text/A+1','text/A']", 1 },
@@ -104,6 +108,42 @@ public class AcceptTest {
// Test media types with parameters
{ "Parms-1", "text/A", "['text/A;foo=bar','text/B']", 0 },
{ "Parms-2", "text/A;foo=bar", "['text/A','text/B']", 0 },
+
+ // Real-world JSON
+ { "Json-1a", "text/json", "['text/json','text/json+*','text/*','text/json+lax','text/json+lax+*','text/foo']", 0 },
+ { "Json-1b", "text/json", "['text/json+*','text/*','text/json+lax','text/json+lax+*','text/foo','text/json']", 5 },
+ { "Json-1c", "text/json", "['text/json+*','text/*','text/json+lax','text/json+lax+*','text/foo']", 0 },
+ { "Json-1d", "text/json", "['text/*','text/json+lax','text/json+lax+*','text/foo']", 0 },
+ { "Json-1e", "text/json", "['text/json+lax','text/json+lax+*','text/foo']", -1 },
+
+ { "Json-2a", "text/json+lax", "['text/json+lax','text/json+lax+*','text/json+*','text/lax+*','text/*','text/json','text/lax']", 0 },
+ { "Json-2b", "text/json+lax", "['text/json+lax+*','text/json+*','text/lax+*','text/*','text/json','text/lax']", 0 },
+ { "Json-2c", "text/json+lax", "['text/json+*','text/lax+foo+*','text/*','text/json','text/lax']", 0 },
+ { "Json-2d", "text/json+lax", "['text/lax+*','text/*','text/json','text/lax']", 0 },
+ { "Json-2e", "text/json+lax", "['text/*','text/json','text/lax']", 0 },
+ { "Json-2f", "text/json+lax", "['text/json','text/lax']", -1 },
+
+ { "Json-3a", "text/json+activity", "['text/json+activity','text/activity+json','text/json+activity+*','text/json+*','text/*','text/json','text/json+lax','text/json+lax+*','text/foo']", 0 },
+ { "Json-3b", "text/json+activity", "['text/activity+json','text/json+activity+*','text/json+*','text/*','text/json','text/json+lax','text/json+lax+*','text/foo']", 0 },
+ { "Json-3c", "text/json+activity", "['text/json+activity+*','text/json+*','text/*','text/json','text/json+lax','text/json+lax+*','text/foo']", 0 },
+ { "Json-3d", "text/json+activity", "['text/json+*','text/*','text/json','text/json+lax','text/json+lax+*','text/foo']", 0 },
+ { "Json-3e", "text/json+activity", "['text/*','text/json','text/json+lax','text/json+lax+*','text/foo']", 0 },
+ { "Json-3f", "text/json+activity", "['text/json','text/json+lax','text/json+lax+*','text/foo']", -1 },
+
+ // Real-world XML
+ { "Xml-1a", "text/xml", "['text/xml','text/xml+*','text/xml+rdf','text/foo']", 0 },
+ { "Xml-1b", "text/xml", "['text/xml+*','text/xml+rdf','text/foo']", 0 },
+ { "Xml-1c", "text/xml", "['text/xml+rdf','text/foo']", -1 },
+ { "Xml-1d", "text/xml", "['text/foo']", -1 },
+
+ { "Xml-2a", "text/xml+id", "['text/xml+*','text/xml','text/xml+rdf']", 0 },
+ { "Xml-2b", "text/xml+id", "['text/xml','text/xml+rdf']", -1 },
+ { "Xml-2c", "text/xml+id", "['text/xml+rdf']", -1 },
+
+ // Real-world RDF
+ { "Rdf-1a", "text/xml+rdf", "['text/xml+rdf','text/xml+*','text/xml']", 0 },
+ { "Rdf-1b", "text/xml+rdf", "['text/xml+*','text/xml']", 0 },
+ { "Rdf-1c", "text/xml+rdf", "['text/xml']", -1 },
});
}
@@ -124,4 +164,14 @@ public class AcceptTest {
int r = accept.findMatch(mt);
TestUtils.assertEquals(expected, r, "{0} failed", label);
}
+
+ @Test
+ public void testReversed() throws Exception {
+ Accept accept = Accept.forString(this.accept);
+ MediaType[] mt = JsonParser.DEFAULT.parse(mediaTypes, MediaType[].class);
+ Collections.reverse(Arrays.asList(mt));
+ int r = accept.findMatch(mt);
+ int expected2 = expected == -1 ? -1 : mt.length-expected-1;
+ TestUtils.assertEquals(expected2, r, "{0} failed", label);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java
index b5e2db9..a9839d4 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java
@@ -52,19 +52,19 @@ public class SerializerGroupTest {
public static class SA1 extends JsonSerializer {
public SA1(PropertyStore propertyStore) {
- super(propertyStore, "application/json", "text/foo", "text/foo_a");
+ super(propertyStore, "application/json", "text/foo+*", "text/foo_a+*");
}
}
public static class SA2 extends JsonSerializer {
public SA2(PropertyStore propertyStore) {
- super(propertyStore, "application/json", "text/foo+bar", "text/foo+bar_a");
+ super(propertyStore, "application/json", "text/foo+bar+*", "text/foo+bar_a+*");
}
}
public static class SA3 extends JsonSerializer {
public SA3(PropertyStore propertyStore) {
- super(propertyStore, "application/json", "text/baz", "text/baz_a");
+ super(propertyStore, "application/json", "text/baz+*", "text/baz_a+*");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/test/pojos/SwappedPojo.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/test/pojos/SwappedPojo.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/test/pojos/SwappedPojo.java
index 605fd25..2cba47c 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/test/pojos/SwappedPojo.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/test/pojos/SwappedPojo.java
@@ -14,7 +14,7 @@ package org.apache.juneau.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
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java
index 5bc0e65..edd1328 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java
@@ -349,7 +349,7 @@ public class ReaderObjectSwapTest extends ComboSerializeTest {
super(comboInput);
}
- @Pojo(swap=PojoToSimpleReaderSwap.class)
+ @Swap(PojoToSimpleReaderSwap.class)
public static class PojoToSimpleReader {}
public static class PojoToSimpleReaderSwap extends PojoSwap<PojoToSimpleReader,Reader> {
@@ -358,7 +358,7 @@ public class ReaderObjectSwapTest extends ComboSerializeTest {
}
}
- @Pojo(swap=PojoToDynamicReaderSwap.class)
+ @Swap(PojoToDynamicReaderSwap.class)
public static class PojoToDynamicReader {
private String f;
public PojoToDynamicReader(String f) {
@@ -372,7 +372,7 @@ public class ReaderObjectSwapTest extends ComboSerializeTest {
}
}
- @Pojo(swap=SometimesSwappedBeanSwap1.class)
+ @Swap(SometimesSwappedBeanSwap1.class)
public static class SometimesSwappedBean1 {
public String f;
public SometimesSwappedBean1(String f) {
@@ -389,7 +389,7 @@ public class ReaderObjectSwapTest extends ComboSerializeTest {
}
}
- @Pojo(swap=SometimesSwappedBeanSwap2.class)
+ @Swap(SometimesSwappedBeanSwap2.class)
public static class SometimesSwappedBean2 {
public String f;
public SometimesSwappedBean2(String f) {
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/SwapsAnnotationComboTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/SwapsAnnotationComboTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/SwapsAnnotationComboTest.java
new file mode 100644
index 0000000..c873ebe
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/transforms/SwapsAnnotationComboTest.java
@@ -0,0 +1,478 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.transforms;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
+
+/**
+ * Exhaustive serialization tests for the CalendarSwap class.
+ */
+@RunWith(Parameterized.class)
+@SuppressWarnings({"javadoc"})
+public class SwapsAnnotationComboTest extends ComboSerializeTest {
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> getParameters() {
+ return Arrays.asList(new Object[][] {
+ { /* 0 */
+ new ComboInput<TestMediaTypeLiterals>(
+ "TestMediaTypeLiterals",
+ TestMediaTypeLiterals.class,
+ new TestMediaTypeLiterals(),
+ /* Json */ "'JSON'",
+ /* JsonT */ "'JSON'",
+ /* JsonR */ "'JSON'",
+ /* Xml */ "<string>XML</string>",
+ /* XmlT */ "<string>XML</string>",
+ /* XmlR */ "<string>XML</string>\n",
+ /* XmlNs */ "<string>XML</string>",
+ /* Html */ "<string>HTML</string>",
+ /* HtmlT */ "<string>HTML</string>",
+ /* HtmlR */ "<string>HTML</string>",
+ /* Uon */ "UON",
+ /* UonT */ "UON",
+ /* UonR */ "UON",
+ /* UrlEnc */ "_value=URLENCODING",
+ /* UrlEncT */ "_value=URLENCODING",
+ /* UrlEncR */ "_value=URLENCODING",
+ /* MsgPack */ "A74D53475041434B",
+ /* MsgPackT */ "A74D53475041434B",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>RDFXML</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+ { /* 1 */
+ new ComboInput<TestMediaTypePatterns>(
+ "TestMediaTypePatterns",
+ TestMediaTypePatterns.class,
+ new TestMediaTypePatterns(),
+ /* Json */ "'JSON'",
+ /* JsonT */ "'JSON'",
+ /* JsonR */ "'JSON'",
+ /* Xml */ "<string>XML</string>",
+ /* XmlT */ "<string>XML</string>",
+ /* XmlR */ "<string>XML</string>\n",
+ /* XmlNs */ "<string>XML</string>",
+ /* Html */ "<string>HTML</string>",
+ /* HtmlT */ "<string>HTML</string>",
+ /* HtmlR */ "<string>HTML</string>",
+ /* Uon */ "UON",
+ /* UonT */ "UON",
+ /* UonR */ "UON",
+ /* UrlEnc */ "_value=URLENCODING",
+ /* UrlEncT */ "_value=URLENCODING",
+ /* UrlEncR */ "_value=URLENCODING",
+ /* MsgPack */ "A74D53475041434B",
+ /* MsgPackT */ "A74D53475041434B",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>RDFXML</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+ { /* 2 */
+ new ComboInput<TestMediaTypePatternsReversed>(
+ "TestMediaTypePatternsReversed",
+ TestMediaTypePatternsReversed.class,
+ new TestMediaTypePatternsReversed(),
+ /* Json */ "'JSON'",
+ /* JsonT */ "'JSON'",
+ /* JsonR */ "'JSON'",
+ /* Xml */ "<string>XML</string>",
+ /* XmlT */ "<string>XML</string>",
+ /* XmlR */ "<string>XML</string>\n",
+ /* XmlNs */ "<string>XML</string>",
+ /* Html */ "<string>HTML</string>",
+ /* HtmlT */ "<string>HTML</string>",
+ /* HtmlR */ "<string>HTML</string>",
+ /* Uon */ "UON",
+ /* UonT */ "UON",
+ /* UonR */ "UON",
+ /* UrlEnc */ "_value=URLENCODING",
+ /* UrlEncT */ "_value=URLENCODING",
+ /* UrlEncR */ "_value=URLENCODING",
+ /* MsgPack */ "A74D53475041434B",
+ /* MsgPackT */ "A74D53475041434B",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>RDFXML</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+ { /* 3 */
+ new ComboInput<TestMediaTypePatternsMulti>(
+ "TestMediaTypePatternsMulti",
+ TestMediaTypePatternsMulti.class,
+ new TestMediaTypePatternsMulti(),
+ /* Json */ "'JSON'",
+ /* JsonT */ "'JSON'",
+ /* JsonR */ "'JSON'",
+ /* Xml */ "<string>XML</string>",
+ /* XmlT */ "<string>XML</string>",
+ /* XmlR */ "<string>XML</string>\n",
+ /* XmlNs */ "<string>XML</string>",
+ /* Html */ "<string>HTML</string>",
+ /* HtmlT */ "<string>HTML</string>",
+ /* HtmlR */ "<string>HTML</string>",
+ /* Uon */ "UON",
+ /* UonT */ "UON",
+ /* UonR */ "UON",
+ /* UrlEnc */ "_value=URLENCODING",
+ /* UrlEncT */ "_value=URLENCODING",
+ /* UrlEncR */ "_value=URLENCODING",
+ /* MsgPack */ "A74D53475041434B",
+ /* MsgPackT */ "A74D53475041434B",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>RDFXML</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+ { /* 4 */
+ // In this case, "text/xml" should NOT match "text/xml+rdf".
+ new ComboInput<TestMediaTypePatternsPartial1>(
+ "TestMediaTypePatternsPartial1",
+ TestMediaTypePatternsPartial1.class,
+ new TestMediaTypePatternsPartial1(),
+ /* Json */ "'JSON'",
+ /* JsonT */ "'JSON'",
+ /* JsonR */ "'JSON'",
+ /* Xml */ "<string>XML</string>",
+ /* XmlT */ "<string>XML</string>",
+ /* XmlR */ "<string>XML</string>\n",
+ /* XmlNs */ "<string>XML</string>",
+ /* Html */ "<string>HTML</string>",
+ /* HtmlT */ "<string>HTML</string>",
+ /* HtmlR */ "<string>HTML</string>",
+ /* Uon */ "foo",
+ /* UonT */ "foo",
+ /* UonR */ "foo",
+ /* UrlEnc */ "_value=foo",
+ /* UrlEncT */ "_value=foo",
+ /* UrlEncR */ "_value=foo",
+ /* MsgPack */ "A3666F6F",
+ /* MsgPackT */ "A3666F6F",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>foo</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>foo</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>foo</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+ { /* 5 */
+ // In this case, "text/xml+rdf" should NOT match "text/xml".
+ new ComboInput<TestMediaTypePatternsPartial2>(
+ "TestMediaTypePatternsPartial2",
+ TestMediaTypePatternsPartial2.class,
+ new TestMediaTypePatternsPartial2(),
+ /* Json */ "'foo'",
+ /* JsonT */ "'foo'",
+ /* JsonR */ "'foo'",
+ /* Xml */ "<string>foo</string>",
+ /* XmlT */ "<string>foo</string>",
+ /* XmlR */ "<string>foo</string>\n",
+ /* XmlNs */ "<string>foo</string>",
+ /* Html */ "<string>foo</string>",
+ /* HtmlT */ "<string>foo</string>",
+ /* HtmlR */ "<string>foo</string>",
+ /* Uon */ "UON",
+ /* UonT */ "UON",
+ /* UonR */ "UON",
+ /* UrlEnc */ "_value=URLENCODING",
+ /* UrlEncT */ "_value=URLENCODING",
+ /* UrlEncR */ "_value=URLENCODING",
+ /* MsgPack */ "A74D53475041434B",
+ /* MsgPackT */ "A74D53475041434B",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>RDFXML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>RDFXML</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+ { /* 6 */
+ // In this case, "text/xml+*" should match both the XML and RDF serializers.
+ new ComboInput<TestMediaTypePatternsXmlPlus>(
+ "TestMediaTypePatternsXmlPlus",
+ TestMediaTypePatternsXmlPlus.class,
+ new TestMediaTypePatternsXmlPlus(),
+ /* Json */ "'foo'",
+ /* JsonT */ "'foo'",
+ /* JsonR */ "'foo'",
+ /* Xml */ "<string>XML</string>",
+ /* XmlT */ "<string>XML</string>",
+ /* XmlR */ "<string>XML</string>\n",
+ /* XmlNs */ "<string>XML</string>",
+ /* Html */ "<string>foo</string>",
+ /* HtmlT */ "<string>foo</string>",
+ /* HtmlR */ "<string>foo</string>",
+ /* Uon */ "foo",
+ /* UonT */ "foo",
+ /* UonR */ "foo",
+ /* UrlEnc */ "_value=foo",
+ /* UrlEncT */ "_value=foo",
+ /* UrlEncR */ "_value=foo",
+ /* MsgPack */ "A3666F6F",
+ /* MsgPackT */ "A3666F6F",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>XML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>XML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>XML</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+ { /* 7 */
+ // In this case, "text/*+xml" should match both the XML and RDF serializers.
+ new ComboInput<TestMediaTypePatternsXmlPlusReversed>(
+ "TestMediaTypePatternsXmlPlusReversed",
+ TestMediaTypePatternsXmlPlusReversed.class,
+ new TestMediaTypePatternsXmlPlusReversed(),
+ /* Json */ "'foo'",
+ /* JsonT */ "'foo'",
+ /* JsonR */ "'foo'",
+ /* Xml */ "<string>XML</string>",
+ /* XmlT */ "<string>XML</string>",
+ /* XmlR */ "<string>XML</string>\n",
+ /* XmlNs */ "<string>XML</string>",
+ /* Html */ "<string>foo</string>",
+ /* HtmlT */ "<string>foo</string>",
+ /* HtmlR */ "<string>foo</string>",
+ /* Uon */ "foo",
+ /* UonT */ "foo",
+ /* UonR */ "foo",
+ /* UrlEnc */ "_value=foo",
+ /* UrlEncT */ "_value=foo",
+ /* UrlEncR */ "_value=foo",
+ /* MsgPack */ "A3666F6F",
+ /* MsgPackT */ "A3666F6F",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>XML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>XML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>XML</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+ { /* 8 */
+ // In this case, "text/rdf+*" should match only the RDF serializer.
+ new ComboInput<TestMediaTypePatternsRdfPlus>(
+ "TestMediaTypePatternsRdfPlus",
+ TestMediaTypePatternsRdfPlus.class,
+ new TestMediaTypePatternsRdfPlus(),
+ /* Json */ "'foo'",
+ /* JsonT */ "'foo'",
+ /* JsonR */ "'foo'",
+ /* Xml */ "<string>foo</string>",
+ /* XmlT */ "<string>foo</string>",
+ /* XmlR */ "<string>foo</string>\n",
+ /* XmlNs */ "<string>foo</string>",
+ /* Html */ "<string>foo</string>",
+ /* HtmlT */ "<string>foo</string>",
+ /* HtmlR */ "<string>foo</string>",
+ /* Uon */ "foo",
+ /* UonT */ "foo",
+ /* UonR */ "foo",
+ /* UrlEnc */ "_value=foo",
+ /* UrlEncT */ "_value=foo",
+ /* UrlEncR */ "_value=foo",
+ /* MsgPack */ "A3666F6F",
+ /* MsgPackT */ "A3666F6F",
+ /* RdfXml */ "<rdf:RDF>\n<rdf:Description>\n<j:value>XML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlT */ "<rdf:RDF>\n<rdf:Description>\n<j:value>XML</j:value>\n</rdf:Description>\n</rdf:RDF>\n",
+ /* RdfXmlR */ "<rdf:RDF>\n <rdf:Description>\n <j:value>XML</j:value>\n </rdf:Description>\n</rdf:RDF>\n"
+ )
+ },
+// { /* 0 */
+// new ComboInput<byte[]>(
+// "ByteArray1d",
+// byte[].class,
+// new byte[] {1,2,3},
+// /* Json */ "xxx",
+// /* JsonT */ "xxx",
+// /* JsonR */ "xxx",
+// /* Xml */ "xxx",
+// /* XmlT */ "xxx",
+// /* XmlR */ "xxx",
+// /* XmlNs */ "xxx",
+// /* Html */ "xxx",
+// /* HtmlT */ "xxx",
+// /* HtmlR */ "xxx",
+// /* Uon */ "xxx",
+// /* UonT */ "xxx",
+// /* UonR */ "xxx",
+// /* UrlEnc */ "xxx",
+// /* UrlEncT */ "xxx",
+// /* UrlEncR */ "xxx",
+// /* MsgPack */ "xxx",
+// /* MsgPackT */ "xxx",
+// /* RdfXml */ "xxx",
+// /* RdfXmlT */ "xxx",
+// /* RdfXmlR */ "xxx"
+// )
+// },
+ });
+ }
+
+ public SwapsAnnotationComboTest(ComboInput<?> comboInput) {
+ super(comboInput);
+ }
+
+ @Override
+ protected Serializer applySettings(Serializer s) throws Exception {
+ return s.builder().pojoSwaps(ByteArrayBase64Swap.class).trimNullProperties(false).build();
+ }
+
+ @Swaps(
+ {
+ @Swap(value=SwapJson.class, mediaTypes={"application/json"}),
+ @Swap(value=SwapXml.class, mediaTypes={"text/xml"}),
+ @Swap(value=SwapHtml.class, mediaTypes={"text/html"}),
+ @Swap(value=SwapUon.class, mediaTypes={"text/uon"}),
+ @Swap(value=SwapUrlEncoding.class, mediaTypes={"application/x-www-form-urlencoded"}),
+ @Swap(value=SwapMsgPack.class, mediaTypes={"octal/msgpack"}),
+ @Swap(value=SwapRdfXml.class, mediaTypes={"text/xml+rdf"}),
+ }
+ )
+ public static class TestMediaTypeLiterals {}
+
+ @Swaps(
+ {
+ @Swap(value=SwapJson.class, mediaTypes={"*/json"}),
+ @Swap(value=SwapXml.class, mediaTypes={"*/xml"}),
+ @Swap(value=SwapHtml.class, mediaTypes={"*/html"}),
+ @Swap(value=SwapUon.class, mediaTypes={"*/uon"}),
+ @Swap(value=SwapUrlEncoding.class, mediaTypes={"*/x-www-form-urlencoded"}),
+ @Swap(value=SwapMsgPack.class, mediaTypes={"*/msgpack"}),
+ @Swap(value=SwapRdfXml.class, mediaTypes={"*/xml+rdf"}),
+ }
+ )
+ public static class TestMediaTypePatterns {}
+
+ @Swaps(
+ {
+ @Swap(value=SwapRdfXml.class, mediaTypes={"*/xml+rdf"}),
+ @Swap(value=SwapMsgPack.class, mediaTypes={"*/msgpack"}),
+ @Swap(value=SwapUrlEncoding.class, mediaTypes={"*/x-www-form-urlencoded"}),
+ @Swap(value=SwapUon.class, mediaTypes={"*/uon"}),
+ @Swap(value=SwapHtml.class, mediaTypes={"*/html"}),
+ @Swap(value=SwapXml.class, mediaTypes={"*/xml"}),
+ @Swap(value=SwapJson.class, mediaTypes={"*/json"}),
+ }
+ )
+ public static class TestMediaTypePatternsReversed {}
+
+ @Swaps(
+ {
+ @Swap(value=SwapJson.class, mediaTypes={"*/foo","*/json","*/bar"}),
+ @Swap(value=SwapXml.class, mediaTypes={"*/foo","*/xml","*/bar"}),
+ @Swap(value=SwapHtml.class, mediaTypes={"*/foo","*/html","*/bar"}),
+ @Swap(value=SwapUon.class, mediaTypes={"*/foo","*/uon","*/bar"}),
+ @Swap(value=SwapUrlEncoding.class, mediaTypes={"*/foo","*/x-www-form-urlencoded","*/bar"}),
+ @Swap(value=SwapMsgPack.class, mediaTypes={"*/foo","*/msgpack","*/bar"}),
+ @Swap(value=SwapRdfXml.class, mediaTypes={"*/foo","*/xml+rdf","*/bar"}),
+ }
+ )
+ public static class TestMediaTypePatternsMulti {}
+
+ @Swaps(
+ {
+ @Swap(value=SwapJson.class, mediaTypes={"*/foo","*/json","*/bar"}),
+ @Swap(value=SwapXml.class, mediaTypes={"*/foo","*/xml","*/bar"}),
+ @Swap(value=SwapHtml.class, mediaTypes={"*/foo","*/html","*/bar"}),
+ }
+ )
+ public static class TestMediaTypePatternsPartial1 {
+ public String toString() {
+ return "foo";
+ }
+ }
+
+ @Swaps(
+ {
+ @Swap(value=SwapUon.class, mediaTypes={"*/foo","*/uon","*/bar"}),
+ @Swap(value=SwapUrlEncoding.class, mediaTypes={"*/foo","*/x-www-form-urlencoded","*/bar"}),
+ @Swap(value=SwapMsgPack.class, mediaTypes={"*/foo","*/msgpack","*/bar"}),
+ @Swap(value=SwapRdfXml.class, mediaTypes={"*/foo","*/xml+rdf","*/bar"}),
+ }
+ )
+ public static class TestMediaTypePatternsPartial2 {
+ public String toString() {
+ return "foo";
+ }
+ }
+
+ @Swaps(
+ {
+ @Swap(value=SwapXml.class, mediaTypes={"text/xml+*"}),
+ }
+ )
+ public static class TestMediaTypePatternsXmlPlus {
+ public String toString() {
+ return "foo";
+ }
+ }
+
+ @Swaps(
+ {
+ @Swap(value=SwapXml.class, mediaTypes={"text/*+xml"}),
+ }
+ )
+ public static class TestMediaTypePatternsXmlPlusReversed {
+ public String toString() {
+ return "foo";
+ }
+ }
+
+ @Swaps(
+ {
+ @Swap(value=SwapXml.class, mediaTypes={"text/rdf+*"}),
+ }
+ )
+ public static class TestMediaTypePatternsRdfPlus {
+ public String toString() {
+ return "foo";
+ }
+ }
+
+ public static class SwapJson extends PojoSwap {
+ public Object swap(BeanSession session, Object o) throws Exception {
+ return "JSON";
+ }
+ }
+ public static class SwapXml extends PojoSwap {
+ public Object swap(BeanSession session, Object o) throws Exception {
+ return "XML";
+ }
+ }
+ public static class SwapHtml extends PojoSwap {
+ public Object swap(BeanSession session, Object o) throws Exception {
+ return "HTML";
+ }
+ }
+ public static class SwapUon extends PojoSwap {
+ public Object swap(BeanSession session, Object o) throws Exception {
+ return "UON";
+ }
+ }
+ public static class SwapUrlEncoding extends PojoSwap {
+ public Object swap(BeanSession session, Object o) throws Exception {
+ return "URLENCODING";
+ }
+ }
+ public static class SwapMsgPack extends PojoSwap {
+ public Object swap(BeanSession session, Object o) throws Exception {
+ return "MSGPACK";
+ }
+ }
+ public static class SwapRdfXml extends PojoSwap {
+ public Object swap(BeanSession session, Object o) throws Exception {
+ return "RDFXML";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
index 267d06f..04e779f 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
@@ -228,8 +228,8 @@ public class RdfParserSession 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);
if (! sType.canCreateNewInstance(outer)) {
@@ -341,8 +341,8 @@ public class RdfParserSession extends ReaderParserSession {
throw new ParseException("Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
}
- 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-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
index 0f66237..9c0e701 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -206,12 +206,13 @@ public final class RdfSerializerSession extends WriterSerializerSession {
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.
@@ -219,7 +220,7 @@ public final class RdfSerializerSession extends WriterSerializerSession {
sType = getClassMetaForObject(o);
}
} else {
- sType = eType.getSerializedClassMeta();
+ sType = eType.getSerializedClassMeta(this);
}
String typeName = getBeanTypeName(eType, aType, bpm);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index c550408..5464f52 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -210,7 +210,7 @@ public class BeanPropertyMeta {
return false;
if (typeMeta == null)
- typeMeta = (swap != null ? swap.getSwapClassMeta(beanContext) : rawTypeMeta == null ? beanContext.object() : rawTypeMeta.getSerializedClassMeta());
+ typeMeta = (swap != null ? beanContext.getClassMeta(swap.getSwapClass()) : rawTypeMeta == null ? beanContext.object() : rawTypeMeta);
if (typeMeta == null)
typeMeta = rawTypeMeta;
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index bad3d38..64d165c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -357,19 +357,19 @@ public class BeanSession extends Session {
if (tc == Class.class)
return (T)(ctx.classLoader.loadClass(value.toString()));
- if (type.getPojoSwap() != null) {
- PojoSwap f = type.getPojoSwap();
- Class<?> nc = f.getNormalClass(), fc = f.getSwapClass();
+ PojoSwap swap = type.getPojoSwap(this);
+ if (swap != null) {
+ Class<?> nc = swap.getNormalClass(), fc = swap.getSwapClass();
if (isParentClass(nc, tc) && isParentClass(fc, value.getClass()))
- return (T)f.unswap(this, value, type);
+ return (T)swap.unswap(this, value, type);
}
ClassMeta<?> vt = ctx.getClassMetaForObject(value);
- if (vt.getPojoSwap() != null) {
- PojoSwap f = vt.getPojoSwap();
- Class<?> nc = f.getNormalClass(), fc = f.getSwapClass();
+ swap = vt.getPojoSwap(this);
+ if (swap != null) {
+ Class<?> nc = swap.getNormalClass(), fc = swap.getSwapClass();
if (isParentClass(nc, vt.getInnerClass()) && isParentClass(fc, tc))
- return (T)f.swap(this, value);
+ return (T)swap.swap(this, value);
}
if (type.isPrimitive()) {
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
----------------------------------------------------------------------
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 0e1bd72..036c4ae 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
@@ -22,10 +22,12 @@ import java.lang.reflect.Proxy;
import java.net.*;
import java.net.URI;
import java.util.*;
+import java.util.Date;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import org.apache.juneau.annotation.*;
+import org.apache.juneau.http.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.remoteable.*;
@@ -93,12 +95,11 @@ public final class ClassMeta<T> implements Type {
private final ConcurrentHashMap<Class<?>,PojoSwap<?,?>>
childSwapMap, // Maps normal subclasses to PojoSwaps.
childUnswapMap; // Maps swap subclasses to PojoSwaps.
- private final PojoSwap<T,?> pojoSwap; // The object POJO swap associated with this bean (if it has one).
+ private final PojoSwap<T,?>[] pojoSwaps; // The object POJO swaps associated with this bean (if it has any).
private final BeanFilter beanFilter; // The bean filter associated with this bean (if it has one).
private final MetadataMap extMeta; // Extended metadata
private final BeanContext beanContext; // The bean context that created this object.
private final ClassMeta<?>
- serializedClassMeta, // The transformed class type (if class has swap associated with it).
elementType, // If ARRAY or COLLECTION, the element class type.
keyType, // If MAP, the key class type.
valueType; // If MAP, the value class type.
@@ -167,7 +168,7 @@ public final class ClassMeta<T> implements Type {
this.publicMethods = builder.publicMethods;
this.remoteableMethods = builder.remoteableMethods;
this.beanFilter = beanFilter;
- this.pojoSwap = builder.pojoSwap;
+ this.pojoSwaps = builder.pojoSwaps.isEmpty() ? null : builder.pojoSwaps.toArray(new PojoSwap[builder.pojoSwaps.size()]);
this.extMeta = new MetadataMap();
this.keyType = builder.keyType;
this.valueType = builder.valueType;
@@ -177,7 +178,6 @@ public final class ClassMeta<T> implements Type {
this.initException = builder.initException;
this.typePropertyName = builder.typePropertyName;
this.dictionaryName = builder.dictionaryName;
- this.serializedClassMeta = builder.serializedClassMeta;
this.invocationHandler = builder.invocationHandler;
this.beanRegistry = builder.beanRegistry;
this.isMemberClass = builder.isMemberClass;
@@ -231,7 +231,6 @@ public final class ClassMeta<T> implements Type {
this.remoteableMethods = mainType.remoteableMethods;
this.publicMethods = mainType.publicMethods;
this.beanContext = mainType.beanContext;
- this.serializedClassMeta = this;
this.elementType = elementType;
this.keyType = keyType;
this.valueType = valueType;
@@ -240,7 +239,7 @@ public final class ClassMeta<T> implements Type {
this.typePropertyName = mainType.typePropertyName;
this.dictionaryName = mainType.dictionaryName;
this.notABeanReason = mainType.notABeanReason;
- this.pojoSwap = mainType.pojoSwap;
+ this.pojoSwaps = mainType.pojoSwaps;
this.beanFilter = mainType.beanFilter;
this.extMeta = mainType.extMeta;
this.initException = mainType.initException;
@@ -278,7 +277,6 @@ public final class ClassMeta<T> implements Type {
this.remoteableMethods = null;
this.publicMethods = null;
this.beanContext = null;
- this.serializedClassMeta = this;
this.elementType = null;
this.keyType = null;
this.valueType = null;
@@ -287,7 +285,7 @@ public final class ClassMeta<T> implements Type {
this.typePropertyName = null;
this.dictionaryName = null;
this.notABeanReason = null;
- this.pojoSwap = null;
+ this.pojoSwaps = null;
this.beanFilter = null;
this.extMeta = new MetadataMap();
this.initException = null;
@@ -334,7 +332,7 @@ public final class ClassMeta<T> implements Type {
dictionaryName = null;
Throwable initException = null;
BeanMeta beanMeta = null;
- PojoSwap pojoSwap = null;
+ List<PojoSwap> pojoSwaps = new ArrayList<PojoSwap>();
InvocationHandler invocationHandler = null;
BeanRegistry beanRegistry = null;
PojoSwap<?,?>[] childPojoSwaps;
@@ -557,33 +555,36 @@ public final class ClassMeta<T> implements Type {
final Method fSwapMethod = swapMethod;
final Method fUnswapMethod = unswapMethod;
final Constructor<T> fSwapConstructor = swapConstructor;
- this.pojoSwap = new PojoSwap<T,Object>(c, swapMethod.getReturnType()) {
- @Override
- public Object swap(BeanSession session, Object o) throws SerializeException {
- try {
- return fSwapMethod.invoke(o, session);
- } catch (Exception e) {
- throw new SerializeException(e);
+ this.pojoSwaps.add(
+ new PojoSwap<T,Object>(c, swapMethod.getReturnType()) {
+ @Override
+ public Object swap(BeanSession session, Object o) throws SerializeException {
+ try {
+ return fSwapMethod.invoke(o, session);
+ } catch (Exception e) {
+ throw new SerializeException(e);
+ }
}
- }
- @Override
- public T unswap(BeanSession session, Object f, ClassMeta<?> hint) throws ParseException {
- try {
- if (fUnswapMethod != null)
- return (T)fUnswapMethod.invoke(null, session, f);
- if (fSwapConstructor != null)
- return fSwapConstructor.newInstance(f);
- return super.unswap(session, f, hint);
- } catch (Exception e) {
- throw new ParseException(e);
+ @Override
+ public T unswap(BeanSession session, Object f, ClassMeta<?> hint) throws ParseException {
+ try {
+ if (fUnswapMethod != null)
+ return (T)fUnswapMethod.invoke(null, session, f);
+ if (fSwapConstructor != null)
+ return fSwapConstructor.newInstance(f);
+ return super.unswap(session, f, hint);
+ } catch (Exception e) {
+ throw new ParseException(e);
+ }
}
}
- };
+ );
}
- if (this.pojoSwap == null)
- this.pojoSwap = findPojoSwap();
- if (this.pojoSwap == null)
- this.pojoSwap = pojoSwap;
+
+ if (pojoSwap != null)
+ this.pojoSwaps.add(pojoSwap);
+
+ findPojoSwaps(this.pojoSwaps);
try {
@@ -644,7 +645,7 @@ public final class ClassMeta<T> implements Type {
if (beanMeta != null)
dictionaryName = beanMeta.getDictionaryName();
- serializedClassMeta = (this.pojoSwap == null ? ClassMeta.this : findClassMeta(this.pojoSwap.getSwapClass()));
+ serializedClassMeta = (this.pojoSwaps.isEmpty() ? ClassMeta.this : findClassMeta(this.pojoSwaps.get(0).getSwapClass()));
if (serializedClassMeta == null)
serializedClassMeta = ClassMeta.this;
@@ -667,17 +668,23 @@ public final class ClassMeta<T> implements Type {
return null;
}
- private PojoSwap<T,?> findPojoSwap() {
- Pojo p = innerClass.getAnnotation(Pojo.class);
- if (p != null) {
- Class<?> c = p.swap();
- if (c != Null.class) {
- if (isParentClass(PojoSwap.class, c))
- return ClassUtils.newInstance(PojoSwap.class, c);
- throw new RuntimeException("TODO - Surrogate classes not yet supported.");
- }
- }
- return null;
+ private void findPojoSwaps(List<PojoSwap> l) {
+ Swap swap = innerClass.getAnnotation(Swap.class);
+ if (swap != null)
+ l.add(createPojoSwap(swap));
+ Swaps swaps = innerClass.getAnnotation(Swaps.class);
+ if (swaps != null)
+ for (Swap s : swaps.value())
+ l.add(createPojoSwap(s));
+ }
+
+ private PojoSwap<T,?> createPojoSwap(Swap s) {
+ Class<?> c = s.value();
+
+ if (! isParentClass(PojoSwap.class, c))
+ throw new FormattedRuntimeException("Invalid swap class ''{0}'' specified. Must extend from PojoSwap.", c);
+
+ return ClassUtils.newInstance(PojoSwap.class, c).forMediaTypes(MediaType.forStrings(s.mediaTypes())).withTemplate(s.template());
}
private ClassMeta<?> findClassMeta(Class<?> c) {
@@ -866,11 +873,15 @@ public final class ClassMeta<T> implements Type {
/**
* Returns the serialized (swapped) form of this class if there is an {@link PojoSwap} associated with it.
*
+ * @param session
+ * The bean session.
+ * <br>Required because the swap used may depend on the media type being serialized or parsed.
* @return The serialized class type, or this object if no swap is associated with the class.
*/
@BeanIgnore
- public ClassMeta<?> getSerializedClassMeta() {
- return serializedClassMeta;
+ public ClassMeta<?> getSerializedClassMeta(BeanSession session) {
+ PojoSwap<T,?> ps = getPojoSwap(session);
+ return (ps == null ? this : ps.getSwapClassMeta(session));
}
/**
@@ -1226,14 +1237,32 @@ public final class ClassMeta<T> implements Type {
}
/**
- * Returns the {@link PojoSwap} associated with this class.
+ * Returns the {@link PojoSwap} associated with this class that's the best match for the specified session.
*
+ * @param session
+ * The current bean session.
+ * <br>If multiple swaps are associated with a class, only the first one with a matching media type will
+ * be returned.
* @return
- * The {@link PojoSwap} associated with this class, or <jk>null</jk> if there is no POJO swap associated with
+ * The {@link PojoSwap} associated with this class, or <jk>null</jk> if there are no POJO swaps associated with
* this class.
*/
- public PojoSwap<T,?> getPojoSwap() {
- return pojoSwap;
+ public PojoSwap<T,?> getPojoSwap(BeanSession session) {
+ if (pojoSwaps != null) {
+ int matchQuant = 0, matchIndex = -1;
+
+ for (int i = 0; i < pojoSwaps.length; i++) {
+ int q = pojoSwaps[i].match(session);
+ if (q > matchQuant) {
+ matchQuant = q;
+ matchIndex = i;
+ }
+ }
+
+ if (matchIndex > -1)
+ return pojoSwaps[matchIndex];
+ }
+ return null;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Pojo.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Pojo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Pojo.java
deleted file mode 100644
index 0823e6d..0000000
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Pojo.java
+++ /dev/null
@@ -1,84 +0,0 @@
-// ***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
-// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
-// * with the License. You may obtain a copy of the License at *
-// * *
-// * http://www.apache.org/licenses/LICENSE-2.0 *
-// * *
-// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
-// * specific language governing permissions and limitations under the License. *
-// ***************************************************************************************************************************
-package org.apache.juneau.annotation;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-import java.lang.annotation.*;
-
-import org.apache.juneau.transform.*;
-
-/**
- * Used to tailor how POJOs get interpreted by the framework.
- */
-@Documented
-@Target(TYPE)
-@Retention(RUNTIME)
-@Inherited
-public @interface Pojo {
-
- /**
- * Associate a {@link PojoSwap} or {@link SurrogateSwap} with this class type.
- *
- * <p>
- * Supports the following class types:
- * <ul>
- * <li>Subclasses of {@link PojoSwap}.
- * <li>Any other class. Will get interpreted as a {@link SurrogateSwap}.
- * </ul>
- *
- * <h5 class='section'>Example:</h5>
- * <p>
- * In this case, a swap is being applied to a bean that will force it to be serialized as a <code>String</code>:
- * <p class='bcode'>
- * <jc>// Our bean class</jc>
- * <ja>@Pojo</ja>(swap=BSwap.<jk>class</jk>)
- * <jk>public class</jk> B {
- * <jk>public</jk> String <jf>f1</jf>;
- * }
- *
- * <jc>// Our POJO swap to force the bean to be serialized as a String</jc>
- * <jk>public class</jk> BSwap <jk>extends</jk> PojoSwap<B,String> {
- * <jk>public</jk> String swap(BeanSession s, B o) <jk>throws</jk> SerializeException {
- * <jk>return</jk> o.f1;
- * }
- * <jk>public</jk> B unswap(BeanSession s, String f) <jk>throws</jk> ParseException { {
- * B b1 = <jk>new</jk> B();
- * b1.<jf>f1</jf> = f;
- * <jk>return</jk> b1;
- * }
- * }
- *
- * <jk>public void</jk> test() <jk>throws</jk> Exception {
- * WriterSerializer s = JsonSerializer.<jsf>DEFAULT</jsf>;
- * B b = <jk>new</jk> B();
- * b.<jf>f1</jf> = <js>"bar"</js>;
- * String json = s.serialize(b);
- * <jsm>assertEquals</jsm>(<js>"\"bar\""</js>, json);
- *
- * ReaderParser p = JsonParser.<jsf>DEFAULT</jsf>;
- * b = p.parse(json, B.<jk>class</jk>);
- * <jsm>assertEquals</jsm>(<js>"bar"</js>, b.<jf>f1</jf>);
- * }
- * </p>
- *
- * <p>
- * Note that using this annotation is functionally equivalent to adding swaps to the serializers and parsers:
- * <p class='bcode'>
- * WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().pojoSwaps(BSwap.<jk>class</jk>).build();
- * ReaderParser p = <jk>new</jk> JsonParserBuilder().pojoSwaps(BSwap.<jk>class</jk>).build();
- * </p>
- */
- Class<?> swap() default Null.class;
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java
new file mode 100644
index 0000000..1daa3e9
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swap.java
@@ -0,0 +1,31 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+@Documented
+@Target({TYPE,ANNOTATION_TYPE})
+@Retention(RUNTIME)
+@Inherited
+public @interface Swap {
+
+ Class<?> value() default Null.class;
+
+ String template() default "";
+
+ String[] mediaTypes() default {};
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java
new file mode 100644
index 0000000..4795ce8
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Swaps.java
@@ -0,0 +1,27 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+@Documented
+@Target({TYPE,ANNOTATION_TYPE})
+@Retention(RUNTIME)
+@Inherited
+public @interface Swaps {
+
+ Swap[] value() default {};
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
----------------------------------------------------------------------
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 376843a..975cae4 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
@@ -83,8 +83,8 @@ public final class HtmlParserSession extends XmlParserSession {
if (eType == null)
eType = (ClassMeta<T>)object();
- PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap();
- ClassMeta<?> sType = eType.getSerializedClassMeta();
+ PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap(this);
+ ClassMeta<?> sType = transform == null ? eType : transform.getSwapClassMeta(this);
setCurrentClass(sType);
int event = r.getEventType();
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializerSession.java
index 27f020a..847b40d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializerSession.java
@@ -68,7 +68,7 @@ public class HtmlSchemaDocSerializerSession extends HtmlDocSerializerSession {
aType = push(attrName, eType, null);
- sType = eType.getSerializedClassMeta();
+ sType = eType.getSerializedClassMeta(this);
String type = null;
if (sType.isEnum() || sType.isCharSequence() || sType.isChar())
@@ -86,7 +86,7 @@ public class HtmlSchemaDocSerializerSession extends HtmlDocSerializerSession {
out.put("type", type);
out.put("class", eType.toString());
- PojoSwap t = eType.getPojoSwap();
+ PojoSwap t = eType.getPojoSwap(this);
if (t != null)
out.put("transform", t);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
----------------------------------------------------------------------
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 8cbbb83..3f1f1fd 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
@@ -263,15 +263,17 @@ public class HtmlSerializerSession extends XmlSerializerSession {
aType = ((Delegate)o).getClassMeta();
}
- sType = aType.getSerializedClassMeta();
+ sType = aType;
+
String typeName = null;
if (isAddBeanTypeProperties() && ! eType.equals(aType))
typeName = aType.getDictionaryName();
// 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.
@@ -564,10 +566,10 @@ public class HtmlSerializerSession extends XmlSerializerSession {
for (Object o : c) {
ClassMeta<?> cm = getClassMetaForObject(o);
- if (cm != null && cm.getPojoSwap() != null) {
- PojoSwap f = cm.getPojoSwap();
- o = f.swap(this, o);
- cm = cm.getSerializedClassMeta();
+ if (cm != null && cm.getPojoSwap(this) != null) {
+ PojoSwap swap = cm.getPojoSwap(this);
+ o = swap.swap(this, o);
+ cm = swap.getSwapClassMeta(this);
}
out.oTag(i+1, "tr");
@@ -705,11 +707,13 @@ public class HtmlSerializerSession extends XmlSerializerSession {
if (o1 == null)
return null;
ClassMeta<?> cm = getClassMetaForObject(o1);
- if (cm.getPojoSwap() != null) {
- PojoSwap f = cm.getPojoSwap();
- o1 = f.swap(this, o1);
- cm = cm.getSerializedClassMeta();
+
+ PojoSwap swap = cm.getPojoSwap(this);
+ if (swap != null) {
+ o1 = swap.swap(this, o1);
+ cm = swap.getSwapClassMeta(this);
}
+
if (cm == null || ! cm.isMapOrBean())
return null;
if (cm.getInnerClass().isAnnotationPresent(HtmlLink.class))
@@ -767,10 +771,11 @@ public class HtmlSerializerSession extends XmlSerializerSession {
if (o == null)
continue;
cm = getClassMetaForObject(o);
- if (cm != null && cm.getPojoSwap() != null) {
- PojoSwap f = cm.getPojoSwap();
- o = f.swap(this, o);
- cm = cm.getSerializedClassMeta();
+
+ PojoSwap ps = cm == null ? null : cm.getPojoSwap(this);
+ if (ps != null) {
+ o = ps.swap(this, o);
+ cm = ps.getSwapClassMeta(this);
}
if (prevC.contains(cm))
continue;
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
index 4ea7bec..5b5c64f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
@@ -219,7 +219,8 @@ public final class Accept {
for (int i = 0; i < mediaTypes.length; i++) {
MediaType mt = mediaTypes[i];
- int matchQuant2 = mt.match(mr.getMediaType());
+ int matchQuant2 = mr.getMediaType().match(mt, false);
+
if (matchQuant2 > matchQuant) {
matchIndex = i;
matchQuant = matchQuant2;
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/495c648d/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java
index 05a4f3e..5bcc4ed 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java
@@ -95,7 +95,7 @@ public class ContentType extends MediaType {
for (int i = 0; i < mediaTypes.length; i++) {
MediaType mt = mediaTypes[i];
- int matchQuant2 = mt.match(this);
+ int matchQuant2 = mt.match(this, true);
if (matchQuant2 > matchQuant) {
matchQuant = matchQuant2;
matchIndex = i;