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/04/03 14:36:19 UTC
incubator-juneau git commit: Add support for overriding _type
property name at class level.
Repository: incubator-juneau
Updated Branches:
refs/heads/master ce5b9e810 -> 4d73a6368
Add support for overriding _type property name at class level.
Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/4d73a636
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/4d73a636
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/4d73a636
Branch: refs/heads/master
Commit: 4d73a63680fbb6f624ca2d5f4fb078435cbf774e
Parents: ce5b9e8
Author: JamesBognar <ja...@apache.org>
Authored: Mon Apr 3 10:36:20 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Mon Apr 3 10:36:20 2017 -0400
----------------------------------------------------------------------
.../java/org/apache/juneau/jena/RdfParser.java | 2 +-
.../java/org/apache/juneau/BeanMapTest.java | 28 ++++-----
.../main/java/org/apache/juneau/BeanMap.java | 4 +-
.../main/java/org/apache/juneau/BeanMeta.java | 12 +++-
.../java/org/apache/juneau/BeanSession.java | 9 ++-
.../main/java/org/apache/juneau/ClassMeta.java | 22 ++++++-
.../main/java/org/apache/juneau/ObjectMap.java | 50 ++++-----------
.../java/org/apache/juneau/annotation/Bean.java | 32 +++++++++-
.../java/org/apache/juneau/html/HtmlParser.java | 10 +--
.../org/apache/juneau/html/HtmlSerializer.java | 6 +-
.../java/org/apache/juneau/json/JsonParser.java | 4 +-
.../apache/juneau/msgpack/MsgPackParser.java | 4 +-
.../java/org/apache/juneau/parser/Parser.java | 2 +-
.../org/apache/juneau/parser/ParserSession.java | 2 +-
.../java/org/apache/juneau/uon/UonParser.java | 10 +--
.../juneau/urlencoding/UrlEncodingParser.java | 6 +-
.../java/org/apache/juneau/xml/XmlParser.java | 6 +-
.../apache/juneau/xml/XmlSchemaSerializer.java | 4 +-
.../org/apache/juneau/xml/XmlSerializer.java | 4 +-
juneau-core/src/main/javadoc/overview.html | 66 ++++++++++----------
20 files changed, 160 insertions(+), 123 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index c3138dc..d3e7abe 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -374,7 +374,7 @@ public class RdfParser extends ReaderParser {
Resource r = n.asResource();
Map m = new ObjectMap(session);
parseIntoMap(session, r, m, sType.getKeyType(), sType.getValueType(), pMeta);
- if (m.containsKey(session.getBeanTypePropertyName()))
+ if (m.containsKey(session.getBeanTypePropertyName(eType)))
o = session.cast((ObjectMap)m, pMeta, eType);
else
throw new ParseException(session, "Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
index a254525..5dd13b0 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
@@ -1144,7 +1144,7 @@ public class BeanMapTest {
m.put("f1", 1);
m.put("f2", "2");
- R2 t = (R2)m.cast();
+ R2 t = (R2)m.cast(Object.class);
assertEquals(1, t.f1);
t = (R2)m.cast(R1.class);
@@ -1160,7 +1160,7 @@ public class BeanMapTest {
m.put("f1", 1);
m.put("f2", "2");
- m = (ObjectMap)m.cast();
+ m = (ObjectMap)m.cast(Object.class);
assertEquals(1, t.f1);
assertEquals(2, t.f2);
@@ -1193,7 +1193,7 @@ public class BeanMapTest {
m.put("_type", "S");
m.put("f1", new ObjectMap(session).append("_type", "R1").append("f1", 1));
- S t = (S)m.cast();
+ S t = (S)m.cast(Object.class);
assertEquals(1, t.f1.f1);
t = m.cast(S.class);
@@ -1206,7 +1206,7 @@ public class BeanMapTest {
m = new ObjectMap(session);
m.put("f1", new ObjectMap(session).append("_type", R1.class.getName()).append("f1", 1));
- m = (ObjectMap)m.cast();
+ m = (ObjectMap)m.cast(Object.class);
assertEquals(1, t.f1.f1);
t = m.cast(S.class);
@@ -1232,7 +1232,7 @@ public class BeanMapTest {
m.put("_type", "TreeMap");
m.put("1", "ONE");
- m2 = (Map)m.cast();
+ m2 = (Map)m.cast(Object.class);
assertTrue(m2 instanceof TreeMap);
assertEquals("ONE", m2.get("1"));
@@ -1269,7 +1269,7 @@ public class BeanMapTest {
m = new ObjectMap();
m.put("1", "ONE");
- m2 = (ObjectMap)m.cast();
+ m2 = (ObjectMap)m.cast(Object.class);
assertTrue(m2 instanceof ObjectMap);
assertEquals("ONE", m2.get("1"));
@@ -1311,7 +1311,7 @@ public class BeanMapTest {
m.put("_type", "LinkedList");
m.put("items", new ObjectList().append("1").append("2"));
- List l = (List)m.cast();
+ List l = (List)m.cast(Object.class);
assertTrue(l instanceof LinkedList);
assertEquals("1", l.get(0));
@@ -1364,7 +1364,7 @@ public class BeanMapTest {
m.put("_type", "LinkedListOfInts");
m.put("items", new ObjectList().append("1").append("2"));
- List l = (List)m.cast();
+ List l = (List)m.cast(Object.class);
assertTrue(l instanceof LinkedList);
assertEquals(1, l.get(0));
@@ -1426,7 +1426,7 @@ public class BeanMapTest {
m.put("_type", "LinkedListOfR1");
m.put("items", new ObjectList(session).append("{f1:1}"));
- List l = (List)m.cast();
+ List l = (List)m.cast(Object.class);
assertTrue(l instanceof LinkedList);
assertTrue(l.get(0) instanceof R1);
assertEquals(1, ((R1)l.get(0)).f1);
@@ -1507,7 +1507,7 @@ public class BeanMapTest {
m.put("_type", "LinkedListOfCalendar");
m.put("items", new ObjectList().append("2001-07-04T15:30:45Z"));
- List l = (List)m.cast();
+ List l = (List)m.cast(Object.class);
assertTrue(l instanceof LinkedList);
assertEquals(2001, ((Calendar)l.get(0)).get(Calendar.YEAR));
@@ -1569,7 +1569,7 @@ public class BeanMapTest {
m.put("_type", "StringArray");
m.put("items", new ObjectList().append("1").append("2"));
- String[] l = (String[])m.cast();
+ String[] l = (String[])m.cast(Object.class);
assertEquals("1", l[0]);
l = m.cast(String[].class);
@@ -1615,7 +1615,7 @@ public class BeanMapTest {
m.put("_type", "IntArray");
m.put("items", new ObjectList().append("1").append("2"));
- int[] l = (int[])m.cast();
+ int[] l = (int[])m.cast(Object.class);
assertEquals(1, l[0]);
l = m.cast(int[].class);
@@ -1660,7 +1660,7 @@ public class BeanMapTest {
m.put("_type", "String2dArray");
m.put("items", new ObjectList().append(new ObjectList().append("1")).append(new ObjectList().append("2")));
- String[][] l = (String[][])m.cast();
+ String[][] l = (String[][])m.cast(Object.class);
assertEquals("1", l[0][0]);
assertEquals("2", l[1][0]);
@@ -1692,7 +1692,7 @@ public class BeanMapTest {
m.put("_type", "Int2dArray");
m.put("items", new ObjectList().append(new ObjectList().append("1")).append(new ObjectList().append("2")));
- int[][] l = (int[][])m.cast();
+ int[][] l = (int[][])m.cast(Object.class);
assertEquals(1, l[0][0]);
assertEquals(2, l[1][0]);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
index ed57429..6318255 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
@@ -65,6 +65,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
protected BeanMeta<T> meta;
private final BeanSession session;
+ private final String beanTypePropertyName;
/**
* Instance of this class are instantiated through the BeanContext class.
@@ -79,6 +80,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
this.meta = meta;
if (meta.constructorArgs.length > 0)
propertyCache = new TreeMap<String,Object>();
+ this.beanTypePropertyName = session.getBeanTypePropertyName(meta.classMeta);
}
/**
@@ -203,7 +205,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
if (meta.ctx.ignoreUnknownBeanProperties)
return null;
- if (property.equals(session.getBeanTypePropertyName()))
+ if (property.equals(beanTypePropertyName))
return null;
throw new BeanRuntimeException(meta.c, "Bean property ''{0}'' not found.", property);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
index e327a75..e1edb43 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
@@ -87,6 +87,7 @@ public class BeanMeta<T> {
private final MetadataMap extMeta; // Extended metadata
// Other fields
+ final String typePropertyName; // "_type" property actual name.
private final BeanPropertyMeta typeProperty; // "_type" mock bean property.
private final String dictionaryName; // The @Bean.typeName() annotation defined on this bean class.
final String notABeanReason; // Readable string explaining why this class wasn't a bean.
@@ -118,7 +119,8 @@ public class BeanMeta<T> {
this.constructorArgs = b.constructorArgs;
this.extMeta = b.extMeta;
this.beanRegistry = b.beanRegistry;
- this.typeProperty = new BeanPropertyMeta.Builder(this, ctx.getBeanTypePropertyName(), ctx.string(), beanRegistry).build();
+ this.typePropertyName = b.typePropertyName;
+ this.typeProperty = new BeanPropertyMeta.Builder(this, typePropertyName, ctx.string(), beanRegistry).build();
}
private static final class Builder<T> {
@@ -135,7 +137,7 @@ public class BeanMeta<T> {
MetadataMap extMeta = new MetadataMap();
PropertyNamer propertyNamer;
BeanRegistry beanRegistry;
- String dictionaryName;
+ String dictionaryName, typePropertyName;
private Builder(ClassMeta<T> classMeta, BeanContext ctx, BeanFilter beanFilter, String[] pNames) {
this.classMeta = classMeta;
@@ -165,6 +167,12 @@ public class BeanMeta<T> {
}
this.beanRegistry = new BeanRegistry(ctx, null, bdClasses.toArray(new Class<?>[bdClasses.size()]));
+ for (Bean b : ReflectionUtils.findAnnotationsParentFirst(Bean.class, classMeta.innerClass))
+ if (! b.typePropertyName().isEmpty())
+ typePropertyName = b.typePropertyName();
+ if (typePropertyName == null)
+ typePropertyName = ctx.getBeanTypePropertyName();
+
// If @Bean.interfaceClass is specified on the parent class, then we want
// to use the properties defined on that class, not the subclass.
Class<?> c2 = (beanFilter != null && beanFilter.getInterfaceClass() != null ? beanFilter.getInterfaceClass() : c);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
index 0f9e79b..ad1cee6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
@@ -554,7 +554,7 @@ public class BeanSession extends Session {
if (type.isBean() && value instanceof Map) {
if (value instanceof ObjectMap) {
ObjectMap m2 = (ObjectMap)value;
- String typeName = m2.getString(getBeanTypePropertyName());
+ String typeName = m2.getString(getBeanTypePropertyName(type));
if (typeName != null) {
ClassMeta cm = type.getBeanRegistry().getClassMeta(typeName);
if (cm != null && ClassUtils.isParentClass(type.innerClass, cm.innerClass))
@@ -873,10 +873,13 @@ public class BeanSession extends Session {
/**
* Returns the type property name as defined by {@link BeanContext#BEAN_beanTypePropertyName}.
*
+ * @param cm The class meta of the type we're trying to resolve the type name for.
+ * Can be <jk>null</jk>.
* @return The type property name. Never <jk>null</jk>.
*/
- public final String getBeanTypePropertyName() {
- return ctx.beanTypePropertyName;
+ public final String getBeanTypePropertyName(ClassMeta cm) {
+ String s = cm == null ? null : cm.getBeanTypePropertyName();
+ return s == null ? ctx.beanTypePropertyName : s;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
index 397e4e0..9614408 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
@@ -100,6 +100,7 @@ public final class ClassMeta<T> implements Type {
valueType; // If MAP, the value class type.
private final BeanMeta<T> beanMeta; // The bean meta for this bean class (if it's a bean).
private final String
+ typePropertyName, // The property name of the _type property for this class and subclasses.
notABeanReason, // If this isn't a bean, the reason why.
dictionaryName, // The dictionary name of this class if it has one.
resolvedDictionaryName; // The name if this is an array type (e.g. "X^^").
@@ -171,6 +172,7 @@ public final class ClassMeta<T> implements Type {
this.notABeanReason = builder.notABeanReason;
this.beanMeta = builder.beanMeta;
this.initException = builder.initException;
+ this.typePropertyName = builder.typePropertyName;
this.dictionaryName = builder.dictionaryName;
this.resolvedDictionaryName = builder.resolvedDictionaryName;
this.serializedClassMeta = builder.serializedClassMeta;
@@ -221,6 +223,7 @@ public final class ClassMeta<T> implements Type {
this.valueType = valueType;
this.invocationHandler = mainType.invocationHandler;
this.beanMeta = mainType.beanMeta;
+ this.typePropertyName = mainType.typePropertyName;
this.dictionaryName = mainType.dictionaryName;
this.resolvedDictionaryName = mainType.resolvedDictionaryName;
this.notABeanReason = mainType.notABeanReason;
@@ -269,6 +272,7 @@ public final class ClassMeta<T> implements Type {
this.valueType = null;
this.invocationHandler = null;
this.beanMeta = null;
+ this.typePropertyName = null;
this.dictionaryName = null;
this.resolvedDictionaryName = null;
this.notABeanReason = null;
@@ -314,6 +318,7 @@ public final class ClassMeta<T> implements Type {
elementType = null,
serializedClassMeta = null;
String
+ typePropertyName = null,
notABeanReason = null,
dictionaryName = null,
resolvedDictionaryName = null;
@@ -622,7 +627,11 @@ public final class ClassMeta<T> implements Type {
try {
newMeta = new BeanMeta(ClassMeta.this, beanContext, beanFilter, null);
notABeanReason = newMeta.notABeanReason;
- beanRegistry = newMeta.beanRegistry; // Always get the bean registry even if it's not a bean.
+
+ // Always get these even if it's not a bean:
+ beanRegistry = newMeta.beanRegistry;
+ typePropertyName = newMeta.typePropertyName;
+
} catch (RuntimeException e) {
notABeanReason = e.getMessage();
throw e;
@@ -698,6 +707,17 @@ public final class ClassMeta<T> implements Type {
/**
+ * Returns the type property name associated with this class and subclasses.
+ * <p>
+ * If <jk>null</jk>, <js>"_type"</js> should be assumed.
+ *
+ * @return The type property name associated with this bean class, or <jk>null</jk> if there is no explicit type property name defined or this isn't a bean.
+ */
+ public String getBeanTypePropertyName() {
+ return typePropertyName;
+ }
+
+ /**
* Returns the bean dictionary name associated with this class.
* <p>
* The lexical name is defined by {@link Bean#typeName()}.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
index c146b25..0bb3491 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
@@ -1069,39 +1069,8 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
}
/**
- * Converts this map into the class type specified by the <js>"_type"</js> entry value.
- * <p>
- * TODO - Needs better description.
- *
- * @return This object map cast as another object.
- */
- public Object cast() {
- return cast(session.getBeanRegistry());
- }
-
- /**
- * Same as {@link #cast()}, but first do a lookup for the name in the specified dictionary.
- *
- * @param beanRegistry
- * The class lexicon to resolve the name. Can be <jk>null</jk>.
- * @return The new Java object of type specified by the <js>"_type"</js> entry value, or this
- * same object if entry does not exist.
- */
- public Object cast(BeanRegistry beanRegistry) {
- String c = (String)get(session.getBeanTypePropertyName());
- if (c == null || beanRegistry == null)
- return this;
- ClassMeta<?> cm = beanRegistry.getClassMeta(c);
- if (cm == null)
- return this;
- return cast2(cm);
- }
-
- /**
* Converts this map into an object of the specified type.
* <p>
- * The rules are the same as those specified in {@link #cast()}.
- * <p>
* If this map contains a <js>"_type"</js> entry, it must be the same as or a subclass
* of the <code>type</code>.
*
@@ -1113,9 +1082,12 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
*/
@SuppressWarnings("unchecked")
public <T> T cast(Class<T> type) {
- ClassMeta<?> c1 = session.getBeanRegistry().getClassMeta((String)get(session.getBeanTypePropertyName()));
ClassMeta<?> c2 = session.getClassMeta(type);
- ClassMeta<?> c = narrowClassMeta(c1, c2);
+ String typePropertyName = session.getBeanTypePropertyName(c2);
+ ClassMeta<?> c1 = session.getBeanRegistry().getClassMeta((String)get(typePropertyName));
+ ClassMeta<?> c = c1 == null ? c2 : narrowClassMeta(c1, c2);
+ if (c.isObject())
+ return (T)this;
return (T)cast2(c);
}
@@ -1130,7 +1102,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
*/
@SuppressWarnings({"unchecked"})
public <T> T cast(ClassMeta<T> cm) {
- ClassMeta<?> c1 = session.getBeanRegistry().getClassMeta((String)get(session.getBeanTypePropertyName()));
+ ClassMeta<?> c1 = session.getBeanRegistry().getClassMeta((String)get(session.getBeanTypePropertyName(cm)));
ClassMeta<?> c = narrowClassMeta(c1, cm);
return (T)cast2(c);
}
@@ -1162,7 +1134,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
* Otherwise, returns c2.
*/
private static ClassMeta<?> getNarrowedClassMeta(ClassMeta<?> c1, ClassMeta<?> c2) {
- if (isParentClass(c2.getInnerClass(), c1.getInnerClass()))
+ if (c2 == null || isParentClass(c2.getInnerClass(), c1.getInnerClass()))
return c1;
return c2;
}
@@ -1182,11 +1154,11 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
for (Map.Entry<String,Object> e : entrySet()) {
Object k = e.getKey();
Object v = e.getValue();
- if (! k.equals(session.getBeanTypePropertyName())) {
+ if (! k.equals(session.getBeanTypePropertyName(cm))) {
// Attempt to recursively cast child maps.
if (v instanceof ObjectMap)
- v = ((ObjectMap)v).cast(session.getBeanRegistry());
+ v = ((ObjectMap)v).cast(vType);
k = (kType.isString() ? k : session.convertToType(k, kType));
v = (vType.isObject() ? v : session.convertToType(v, vType));
@@ -1203,11 +1175,11 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
for (Map.Entry<String,Object> e : entrySet()) {
String k = e.getKey();
Object v = e.getValue();
- if (! k.equals(session.getBeanTypePropertyName())) {
+ if (! k.equals(session.getBeanTypePropertyName(cm))) {
// Attempt to recursively cast child maps.
if (v instanceof ObjectMap)
- v = ((ObjectMap)v).cast(session.getBeanRegistry());
+ v = ((ObjectMap)v).cast(bm.getProperty(k).getMeta().getClassMeta());
bm.put(k, v);
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java b/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java
index d4abba2..5b7bf93 100644
--- a/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java
+++ b/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java
@@ -84,13 +84,43 @@ public @interface Bean {
* {
* x: [
* {_type:<js>'bar'</js>},
- * {_type>:<js>'baz'</js>}
+ * {_type:<js>'baz'</js>}
* ]
* }
* </p>
*/
String typeName() default "";
+
+ /**
+ * The property name to use for representing the type name.
+ * <p>
+ * This can be used to override the name used for the <js>"_type"</js> property designated above.
+ * Typically, you'll define this on an interface class so that it can apply to all subclasses.
+ * <p class='bcode'>
+ * <ja>@Bean</ja>(typePropertyName=<js>"mytype"</js>, beanDictionary={MyClass1.<jk>class</jk>,MyClass2.<jk>class</jk>})
+ * <jk>public interface</jk> MyInterface {...}
+ *
+ * <ja>@Bean</ja>(typeName=<js>"C1"</js>)
+ * <jk>public class</jk> MyClass1 <jk>implements</jk> MyInterface {...}
+ *
+ * <ja>@Bean</ja>(typeName=<js>"C2"</js>)
+ * <jk>public class</jk> MyClass2 <jk>implements</jk> MyInterface {...}
+ *
+ * MyInterface[] x = <jk>new</jk> MyInterface[]{ <jk>new</jk> MyClass1(), <jk>new</jk> MyClass2() };
+ *
+ * <jc>// Produces "[{mytype:'C1',...},{mytype:'C2',...}]"</jc>
+ * String json = JsonSerializer.<jsf>DEFAULT_LAX</jsf>.serialize(x);
+ * </p>
+ * <p>
+ * This is similar in concept to the {@link BeanContext#BEAN_beanTypePropertyName} setting except this annotation
+ * applies only to the annotated class and subclasses whereas the bean context property applies globally on
+ * serializers and parsers.
+ * <p>
+ * The default value if not specified is <js>"_type"</js> unless overridden by the {@link BeanContext#BEAN_beanTypePropertyName} setting.
+ */
+ String typePropertyName() default "";
+
/**
* The set and order of names of properties associated with a bean class.
* <p>
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
index 9e53303..5e65356 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
@@ -183,7 +183,7 @@ public class HtmlParser extends XmlParser {
} else if (tag == TABLE) {
- String typeName = getAttribute(r, session.getBeanTypePropertyName(), "object");
+ String typeName = getAttribute(r, session.getBeanTypePropertyName(eType), "object");
ClassMeta cm = session.getClassMeta(typeName, pMeta, eType);
if (cm != null) {
@@ -225,7 +225,7 @@ public class HtmlParser extends XmlParser {
}
} else if (tag == UL) {
- String typeName = getAttribute(r, session.getBeanTypePropertyName(), "array");
+ String typeName = getAttribute(r, session.getBeanTypePropertyName(eType), "array");
ClassMeta cm = session.getClassMeta(typeName, pMeta, eType);
if (cm != null)
sType = eType = cm;
@@ -377,7 +377,7 @@ public class HtmlParser extends XmlParser {
break;
ClassMeta elementType = null;
- String beanType = getAttribute(r, session.getBeanTypePropertyName(), null);
+ String beanType = getAttribute(r, session.getBeanTypePropertyName(type), null);
if (beanType != null)
elementType = session.getClassMeta(beanType, pMeta, null);
if (elementType == null)
@@ -409,7 +409,7 @@ public class HtmlParser extends XmlParser {
}
l.add(m == null ? null : (E)m.getBean());
} else {
- String c = getAttributes(r).get(session.getBeanTypePropertyName());
+ String c = getAttributes(r).get(session.getBeanTypePropertyName(type));
Map m = (Map)(elementType.isMap() && elementType.canCreateNewInstance(l) ? elementType.newInstance(l) : new ObjectMap(session));
for (int i = 0; i < keys.size(); i++) {
tag = nextTag(r, TD, NULL);
@@ -428,7 +428,7 @@ public class HtmlParser extends XmlParser {
}
if (m != null && c != null) {
ObjectMap m2 = (m instanceof ObjectMap ? (ObjectMap)m : new ObjectMap(m).setBeanSession(session));
- m2.put(session.getBeanTypePropertyName(), c);
+ m2.put(session.getBeanTypePropertyName(type), c);
l.add((E)session.cast(m2, pMeta, elementType));
} else {
l.add((E)m);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index a4d8c7d..28b31c0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -362,7 +362,7 @@ public class HtmlSerializer extends XmlSerializer {
out.oTag(i, "table");
if (typeName != null && ppMeta != null && ppMeta.getClassMeta() != aType)
- out.attr(session.getBeanTypePropertyName(), typeName);
+ out.attr(session.getBeanTypePropertyName(sType), typeName);
out.appendln(">");
if (session.isAddKeyValueTableHeaders() && ! (aType.getExtendedMeta(HtmlClassMeta.class).isNoTableHeaders() || (ppMeta != null && ppMeta.getExtendedMeta(HtmlBeanPropertyMeta.class).isNoTableHeaders()))) {
@@ -406,7 +406,7 @@ public class HtmlSerializer extends XmlSerializer {
String typeName = m.getMeta().getDictionaryName();
if (typeName != null && eType != m.getClassMeta())
- out.attr(session.getBeanTypePropertyName(), typeName);
+ out.attr(session.getBeanTypePropertyName(m.getClassMeta()), typeName);
out.append('>').nl();
if (session.isAddKeyValueTableHeaders() && ! (m.getClassMeta().getExtendedMeta(HtmlClassMeta.class).isNoTableHeaders() || (ppMeta != null && ppMeta.getExtendedMeta(HtmlBeanPropertyMeta.class).isNoTableHeaders()))) {
@@ -474,7 +474,7 @@ public class HtmlSerializer extends XmlSerializer {
c = session.sort(c);
HtmlBeanPropertyMeta hbpMeta = (ppMeta == null ? null : ppMeta.getExtendedMeta(HtmlBeanPropertyMeta.class));
- String btpn = session.getBeanTypePropertyName();
+ String btpn = session.getBeanTypePropertyName(eType);
// Look at the objects to see how we're going to handle them. Check the first object to see how we're going to handle this.
// If it's a map or bean, then we'll create a table.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
index 5a09de5..bd79451 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
@@ -215,7 +215,7 @@ public class JsonParser extends ReaderParser {
} else if (c == '{') {
Map m = new ObjectMap(session);
parseIntoMap2(session, r, m, sType.getKeyType(), sType.getValueType(), pMeta);
- if (m.containsKey(session.getBeanTypePropertyName()))
+ if (m.containsKey(session.getBeanTypePropertyName(eType)))
o = session.cast((ObjectMap)m, pMeta, eType);
else
throw new ParseException(session, "Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
@@ -493,7 +493,7 @@ public class JsonParser extends ReaderParser {
if (session.isCommentOrWhitespace(c)) {
skipCommentsAndSpace(session, r.unread());
} else {
- if (! currAttr.equals(session.getBeanTypePropertyName())) {
+ if (! currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
session.setCurrentProperty(pMeta);
if (pMeta == null) {
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
index fc18351..8895f33 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
@@ -127,7 +127,7 @@ public class MsgPackParser extends InputStreamParser {
String pName = parseAnything(session, string(), is, m.getBean(false), null);
BeanPropertyMeta bpm = m.getPropertyMeta(pName);
if (bpm == null) {
- if (pName.equals(session.getBeanTypePropertyName()))
+ if (pName.equals(session.getBeanTypePropertyName(eType)))
parseAnything(session, session.string(), is, null, null);
else
onUnknownProperty(session, pName, m, 0, is.getPosition());
@@ -178,7 +178,7 @@ public class MsgPackParser extends InputStreamParser {
ObjectMap m = new ObjectMap(session);
for (int i = 0; i < length; i++)
m.put(parseAnything(session, string(), is, outer, pMeta), parseAnything(session, object(), is, m, pMeta));
- if (m.containsKey(session.getBeanTypePropertyName()))
+ if (m.containsKey(session.getBeanTypePropertyName(eType)))
o = session.cast(m, pMeta, eType);
else
throw new ParseException(session, "Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
index 389e224..25b3840 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
@@ -611,7 +611,7 @@ public abstract class Parser extends CoreObject {
* @param <T> The class type of the bean map that doesn't have the expected property.
*/
protected <T> void onUnknownProperty(ParserSession session, String propertyName, BeanMap<T> beanMap, int line, int col) throws ParseException {
- if (propertyName.equals("type") || propertyName.equals(session.getBeanTypePropertyName()))
+ if (propertyName.equals(session.getBeanTypePropertyName(beanMap.getClassMeta())))
return;
if (! session.isIgnoreUnknownBeanProperties())
throw new ParseException(session, "Unknown property ''{0}'' encountered while trying to parse into class ''{1}''", propertyName, beanMap.getClassMeta());
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
index c84e6e2..ea20042 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -283,7 +283,7 @@ public class ParserSession extends BeanSession {
*/
public final Object cast(ObjectMap m, BeanPropertyMeta pMeta, ClassMeta<?> eType) {
- String btpn = getBeanTypePropertyName();
+ String btpn = getBeanTypePropertyName(eType);
Object o = m.get(btpn);
if (o == null)
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
index 52ff871..b53f5b7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
@@ -169,7 +169,7 @@ public class UonParser extends ReaderParser {
ObjectMap m = new ObjectMap(session);
parseIntoMap(session, r, m, string(), object(), pMeta);
// Handle case where it's a collection, but serialized as a map with a _type or _value key.
- if (m.containsKey(session.getBeanTypePropertyName()))
+ if (m.containsKey(session.getBeanTypePropertyName(sType)))
o = session.cast(m, pMeta, eType);
// Handle case where it's a collection, but only a single value was specified.
else {
@@ -196,7 +196,7 @@ public class UonParser extends ReaderParser {
ObjectMap m = new ObjectMap(session);
parseIntoMap(session, r, m, string(), object(), pMeta);
// Handle case where it's an array, but serialized as a map with a _type or _value key.
- if (m.containsKey(session.getBeanTypePropertyName()))
+ if (m.containsKey(session.getBeanTypePropertyName(sType)))
o = session.cast(m, pMeta, eType);
// Handle case where it's an array, but only a single value was specified.
else {
@@ -212,7 +212,7 @@ public class UonParser extends ReaderParser {
// It could be a non-bean with _type attribute.
ObjectMap m = new ObjectMap(session);
parseIntoMap(session, r, m, string(), object(), pMeta);
- if (m.containsKey(session.getBeanTypePropertyName()))
+ if (m.containsKey(session.getBeanTypePropertyName(sType)))
o = session.cast(m, pMeta, eType);
else
throw new ParseException(session, "Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
@@ -454,7 +454,7 @@ public class UonParser extends ReaderParser {
}
} else if (state == S3) {
if (c == -1 || c == ',' || c == ')' || c == AMP) {
- if (! currAttr.equals(session.getBeanTypePropertyName())) {
+ if (! currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
if (pMeta == null) {
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
@@ -467,7 +467,7 @@ public class UonParser extends ReaderParser {
return m;
state = S1;
} else {
- if (! currAttr.equals(session.getBeanTypePropertyName())) {
+ if (! currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
if (pMeta == null) {
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index 5fd9647..6ecf88d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -119,7 +119,7 @@ public class UrlEncodingParser extends UonParser {
// It could be a non-bean with _type attribute.
ObjectMap m = new ObjectMap(session);
parseIntoMap(session, r, m, session.getClassMeta(Map.class, String.class, Object.class), outer);
- if (m.containsKey(session.getBeanTypePropertyName()))
+ if (m.containsKey(session.getBeanTypePropertyName(eType)))
o = session.cast(m, null, eType);
else if (m.containsKey("_value")) {
o = session.convertToType(m.get("_value"), sType);
@@ -265,7 +265,7 @@ public class UrlEncodingParser extends UonParser {
}
} else if (state == S3) {
if (c == -1 || c == '\u0001') {
- if (! currAttr.equals(session.getBeanTypePropertyName())) {
+ if (! currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
if (pMeta == null) {
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
@@ -283,7 +283,7 @@ public class UrlEncodingParser extends UonParser {
return m;
state = S1;
} else {
- if (! currAttr.equals(session.getBeanTypePropertyName())) {
+ if (! currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
if (pMeta == null) {
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
index d0e592f..7830163 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -94,7 +94,7 @@ public class XmlParser extends ReaderParser {
session.setCurrentClass(sType);
String wrapperAttr = (isRoot && session.isPreserveRootElement()) ? r.getName().getLocalPart() : null;
- String typeAttr = r.getAttributeValue(null, session.getBeanTypePropertyName());
+ String typeAttr = r.getAttributeValue(null, session.getBeanTypePropertyName(eType));
int jsonType = getJsonType(typeAttr);
String elementName = session.getElementName(r);
if (jsonType == 0) {
@@ -195,7 +195,7 @@ public class XmlParser extends ReaderParser {
for (int i = 0; i < r.getAttributeCount(); i++) {
String a = r.getAttributeLocalName(i);
// TODO - Need better handling of namespaces here.
- if (! (a.equals(session.getBeanTypePropertyName()))) {
+ if (! (a.equals(session.getBeanTypePropertyName(null)))) {
K key = session.trim(convertAttrToType(session, m, a, keyType));
V value = session.trim(convertAttrToType(session, m, r.getAttributeValue(i), valueType));
setName(valueType, value, key);
@@ -429,7 +429,7 @@ public class XmlParser extends ReaderParser {
for (int i = 0; i < r.getAttributeCount(); i++) {
String key = session.getAttributeName(r, i);
String val = r.getAttributeValue(i);
- if (! key.equals(session.getBeanTypePropertyName()))
+ if (! key.equals(session.getBeanTypePropertyName(null)))
m.put(key, val);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
index 740ff3a..68031de 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
@@ -346,7 +346,7 @@ public class XmlSchemaSerializer extends XmlSerializer {
w.cTag().nl();
if (! (cm.isMapOrBean() || cm.isCollectionOrArray() || (cm.isAbstract() && ! cm.isNumber()) || cm.isObject())) {
- w.oTag(i+1, "attribute").attr("name", session.getBeanTypePropertyName()).attr("type", "string").ceTag().nl();
+ w.oTag(i+1, "attribute").attr("name", session.getBeanTypePropertyName(cm)).attr("type", "string").ceTag().nl();
} else {
@@ -494,7 +494,7 @@ public class XmlSchemaSerializer extends XmlSerializer {
}
w.oTag(i+1, "attribute")
- .attr("name", session.getBeanTypePropertyName())
+ .attr("name", session.getBeanTypePropertyName(null))
.attr("type", "string")
.ceTag().nl();
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index da39582..3db721c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -498,9 +498,9 @@ public class XmlSerializer extends WriterSerializer {
}
if (! isExpectedType) {
if (resolvedDictionaryName != null)
- out.attr(dns, session.getBeanTypePropertyName(), resolvedDictionaryName);
+ out.attr(dns, session.getBeanTypePropertyName(eType), resolvedDictionaryName);
else if (type != null && type != STRING)
- out.attr(dns, session.getBeanTypePropertyName(), type);
+ out.attr(dns, session.getBeanTypePropertyName(eType), type);
}
if (o == null) {
if ((sType.isBoolean() || sType.isNumber()) && ! sType.isNullable())
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4d73a636/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index 3b23b5c..171b7c3 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -5704,51 +5704,53 @@
WriterSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf>.builder().ws().pojoSwaps(BSwap.<jk>class</jk>).build();
</p>
<li>Also introduced the following builder classes and related architecture changes to make the built objects unmodifiable:
- <ul>
- <li>{@link org.apache.juneau.serializer.SerializerGroupBuilder}
- <li>{@link org.apache.juneau.parser.ParserGroupBuilder}
- <li>{@link org.apache.juneau.encoders.EncoderGroupBuilder}
- </ul>
+ <ul>
+ <li>{@link org.apache.juneau.serializer.SerializerGroupBuilder}
+ <li>{@link org.apache.juneau.parser.ParserGroupBuilder}
+ <li>{@link org.apache.juneau.encoders.EncoderGroupBuilder}
+ </ul>
<li>Revamped the config file API to use a build: {@link org.apache.juneau.ini.ConfigFileBuilder}.
<li>Removed the <code><del>Lockable</del></code> interface.
<li>New <code>addBeanTypeProperties</code> setting added to serializers to override the
{@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_addBeanTypeProperties} setting
for individual serializers in a serializer group:
- <ul>
- <li>{@link org.apache.juneau.html.HtmlSerializerContext#HTML_addBeanTypeProperties}
- <li>{@link org.apache.juneau.json.JsonSerializerContext#JSON_addBeanTypeProperties}
- <li>{@link org.apache.juneau.msgpack.MsgPackSerializerContext#MSGPACK_addBeanTypeProperties}
- <li>{@link org.apache.juneau.uon.UonSerializerContext#UON_addBeanTypeProperties}
- <li>{@link org.apache.juneau.xml.XmlSerializerContext#XML_addBeanTypeProperties}
- <li>{@link org.apache.juneau.jena.RdfSerializerContext#RDF_addBeanTypeProperties}
- </ul>
+ <ul>
+ <li>{@link org.apache.juneau.html.HtmlSerializerContext#HTML_addBeanTypeProperties}
+ <li>{@link org.apache.juneau.json.JsonSerializerContext#JSON_addBeanTypeProperties}
+ <li>{@link org.apache.juneau.msgpack.MsgPackSerializerContext#MSGPACK_addBeanTypeProperties}
+ <li>{@link org.apache.juneau.uon.UonSerializerContext#UON_addBeanTypeProperties}
+ <li>{@link org.apache.juneau.xml.XmlSerializerContext#XML_addBeanTypeProperties}
+ <li>{@link org.apache.juneau.jena.RdfSerializerContext#RDF_addBeanTypeProperties}
+ </ul>
<li>UON notation serializers and parsers moved into the new <code>org.apache.juneau.uon</code> package.
<li>New {@link org.apache.juneau.xml.annotation.XmlFormat#VOID} format to identify HTML void elements.
<li>Tweaks to HTML5 support.
- <ul>
- <li>Fixed handling of empty non-void elements in HTML serializer.
- <li>Added <code>style()</code> override methods to all elements.
- </ul>
+ <ul>
+ <li>Fixed handling of empty non-void elements in HTML serializer.
+ <li>Added <code>style()</code> override methods to all elements.
+ </ul>
<li>Improvements to Swagger support.
- <ul>
- <li>New {@link org.apache.juneau.dto.swagger.SwaggerBuilder} class.
- <li>Fluent-style setters added to the Swagger beans.
- <li>Added Swagger examples <a href="#DTOs.Swagger">here</a> and in the <a class='doclink' href='org/apache/juneau/dto/swagger/package-summary.html#TOC'>org.apache.juneau.dto.swagger</a> javadocs.
- </ul>
+ <ul>
+ <li>New {@link org.apache.juneau.dto.swagger.SwaggerBuilder} class.
+ <li>Fluent-style setters added to the Swagger beans.
+ <li>Added Swagger examples <a href="#DTOs.Swagger">here</a> and in the <a class='doclink' href='org/apache/juneau/dto/swagger/package-summary.html#TOC'>org.apache.juneau.dto.swagger</a> javadocs.
+ </ul>
<li>Improvements to {@link org.apache.juneau.svl.VarResolver}.
- <ul>
- <li>New {@link org.apache.juneau.svl.vars.IfVar $IF} variable for if-else block logic.
- <li>New {@link org.apache.juneau.svl.vars.SwitchVar $SWITCH} variable for switch block logic.
- <li>Whitespace wasn't being ignored in some cases.
- </ul>
+ <ul>
+ <li>New {@link org.apache.juneau.svl.vars.IfVar $IF} variable for if-else block logic.
+ <li>New {@link org.apache.juneau.svl.vars.SwitchVar $SWITCH} variable for switch block logic.
+ <li>Whitespace wasn't being ignored in some cases.
+ </ul>
<li>{@link org.apache.juneau.html.HtmlParser} can now parse full body contents generated by {@link org.apache.juneau.html.HtmlDocSerializer}.
<li>Parse-args supported added to {@link org.apache.juneau.msgpack.MsgPackParser} to allow it to be used in remoteable proxies.
<li>Added some convenience classes for constructing collections using a fluent interface:
- <ul>
- <li>{@link org.apache.juneau.utils.AList}
- <li>{@link org.apache.juneau.utils.ASet}
- <li>{@link org.apache.juneau.utils.AMap}
- </ul>
+ <ul>
+ <li>{@link org.apache.juneau.utils.AList}
+ <li>{@link org.apache.juneau.utils.ASet}
+ <li>{@link org.apache.juneau.utils.AMap}
+ </ul>
+ <li>New {@link org.apache.juneau.annotation.Bean#typePropertyName @Bean.typePropertyName()} annotation allows you to
+ specify the name of the <js>"_type"</js> property at the class level.
</ul>
<h6 class='topic'>org.apache.juneau.rest</h6>