http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/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 a897d1a..ac4a096 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 @@ -101,7 +101,6 @@ public final class JsonParser extends ReaderParser { ClassMeta<?> sType = eType.getSerializedClassMeta(); session.setCurrentClass(sType); String wrapperAttr = sType.getExtendedMeta(JsonClassMeta.class).getWrapperAttr(); - BeanRegistry breg = pMeta == null ? session.getBeanRegistry() : pMeta.getBeanRegistry(); Object o = null; @@ -124,7 +123,7 @@ public final class JsonParser extends ReaderParser { if (c == '{') { ObjectMap m2 = new ObjectMap(session); parseIntoMap2(session, r, m2, string(), object(), pMeta); - o = breg.cast(m2); + o = session.cast(m2, pMeta, eType); } else if (c == '[') { o = parseIntoCollection2(session, r, new ObjectList(session), object(), pMeta); } else if (c == '\'' || c == '"') { @@ -155,7 +154,7 @@ public final class JsonParser extends ReaderParser { if (c == '{') { ObjectMap m = new ObjectMap(session); parseIntoMap2(session, r, m, string(), object(), pMeta); - o = breg.cast(m); + o = session.cast(m, pMeta, eType); } else { Collection l = (sType.canCreateNewInstance(outer) ? (Collection)sType.newInstance() : new ObjectList(session)); o = parseIntoCollection2(session, r, l, sType.getElementType(), pMeta); @@ -171,7 +170,7 @@ public final class JsonParser extends ReaderParser { if (c == '{') { ObjectMap m = new ObjectMap(session); parseIntoMap2(session, r, m, string(), object(), pMeta); - o = breg.cast(m); + o = session.cast(m, pMeta, eType); } else { ArrayList l = (ArrayList)parseIntoCollection2(session, r, new ArrayList(), sType.getElementType(), pMeta); o = session.toArray(sType, l); @@ -180,7 +179,7 @@ public final class JsonParser extends ReaderParser { Map m = new ObjectMap(session); parseIntoMap2(session, r, m, sType.getKeyType(), sType.getValueType(), pMeta); if (m.containsKey(session.getBeanTypePropertyName())) - o = breg.cast((ObjectMap)m); + 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()); } else if (sType.canCreateNewInstanceFromString(outer) && ! session.isStrict()) { @@ -222,7 +221,7 @@ public final class JsonParser extends ReaderParser { // Need to weed out octal and hexadecimal formats: 0123,-0123,0x123,-0x123. // Don't weed out 0 or -0. boolean isNegative = false; - char c = (s.length() == 0 ? 'x' : s.charAt(0)); + char c = s.charAt(0); if (c == '-') { isNegative = true; c = (s.length() == 1 ? 'x' : s.charAt(1)); @@ -505,13 +504,8 @@ public final class JsonParser extends ReaderParser { BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr); session.setCurrentProperty(pMeta); if (pMeta == null) { - if (m.getMeta().isSubTyped()) { - Object value = parseAnything(session, object(), r.unread(), m.getBean(false), null); - m.put(currAttr, value); - } else { - onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol); - parseAnything(session, object(), r.unread(), m.getBean(false), null); // Read content anyway to ignore it - } + onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol); + parseAnything(session, object(), r.unread(), m.getBean(false), null); // Read content anyway to ignore it } else { ClassMeta<?> cm = pMeta.getClassMeta(); Object value = parseAnything(session, cm, r.unread(), m.getBean(false), pMeta);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java index 07121d3..3a89b68 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java @@ -113,7 +113,6 @@ public class JsonSerializer extends WriterSerializer { /** Constructor */ public Readable() { setUseWhitespace(true); - setUseIndentation(true); } } @@ -132,7 +131,6 @@ public class JsonSerializer extends WriterSerializer { /** Constructor */ public SimpleReadable() { setUseWhitespace(true); - setUseIndentation(true); } } @@ -162,7 +160,6 @@ public class JsonSerializer extends WriterSerializer { if (eType == null) eType = object(); - boolean addTypeProperty; // Add "_type" attribute to element? ClassMeta<?> aType; // The actual type ClassMeta<?> sType; // The serialized type @@ -176,7 +173,7 @@ public class JsonSerializer extends WriterSerializer { } sType = aType.getSerializedClassMeta(); - addTypeProperty = (session.isAddBeanTypeProperties() && ! eType.equals(aType)); + String typeName = session.getBeanTypeName(eType, aType, pMeta); // Swap if necessary PojoSwap swap = aType.getPojoSwap(); @@ -201,12 +198,12 @@ public class JsonSerializer extends WriterSerializer { else if (sType.isNumber() || sType.isBoolean()) out.append(o); else if (sType.isBean()) - serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty); + serializeBeanMap(session, out, session.toBeanMap(o), typeName); else if (sType.isUri() || (pMeta != null && pMeta.isUri())) out.q().appendUri(o).q(); else if (sType.isMap()) { if (o instanceof BeanMap) - serializeBeanMap(session, out, (BeanMap)o, addTypeProperty); + serializeBeanMap(session, out, (BeanMap)o, typeName); else serializeMap(session, out, (Map)o, eType); } @@ -260,12 +257,12 @@ public class JsonSerializer extends WriterSerializer { return out; } - private SerializerWriter serializeBeanMap(JsonSerializerSession session, JsonWriter out, BeanMap<?> m, boolean addTypeProperty) throws Exception { + private SerializerWriter serializeBeanMap(JsonSerializerSession session, JsonWriter out, BeanMap<?> m, String typeName) throws Exception { int depth = session.getIndent(); out.append('{'); boolean addComma = false; - for (BeanPropertyValue p : m.getValues(session.isTrimNulls(), addTypeProperty ? session.createBeanTypeNameProperty(m) : null)) { + for (BeanPropertyValue p : m.getValues(session.isTrimNulls(), typeName != null ? session.createBeanTypeNameProperty(m, typeName) : null)) { BeanPropertyMeta pMeta = p.getMeta(); ClassMeta<?> cMeta = p.getClassMeta(); String key = p.getName(); @@ -373,32 +370,6 @@ public class JsonSerializer extends WriterSerializer { } /** - * <b>Configuration property:</b> Use whitespace. - * <p> - * <ul> - * <li><b>Name:</b> <js>"JsonSerializer.useWhitespace"</js> - * <li><b>Data type:</b> <code>Boolean</code> - * <li><b>Default:</b> <jk>false</jk> - * <li><b>Session-overridable:</b> <jk>true</jk> - * </ul> - * <p> - * If <jk>true</jk>, whitespace is added to the output to improve readability. - * <p> - * <h5 class='section'>Notes:</h5> - * <ul> - * <li>This is equivalent to calling <code>setProperty(<jsf>JSON_useWhitespace</jsf>, value)</code>. - * </ul> - * - * @param value The new value for this property. - * @return This object (for method chaining). - * @throws LockedException If {@link #lock()} was called on this class. - * @see JsonSerializerContext#JSON_useWhitespace - */ - public JsonSerializer setUseWhitespace(boolean value) throws LockedException { - return setProperty(JSON_useWhitespace, value); - } - - /** * <b>Configuration property:</b> Prefix solidus <js>'/'</js> characters with escapes. * <p> * <ul> @@ -452,8 +423,8 @@ public class JsonSerializer extends WriterSerializer { } @Override /* Serializer */ - public JsonSerializer setUseIndentation(boolean value) throws LockedException { - super.setUseIndentation(value); + public JsonSerializer setUseWhitespace(boolean value) throws LockedException { + super.setUseWhitespace(value); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java index eec89c8..6cdceb3 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java @@ -49,20 +49,6 @@ public final class JsonSerializerContext extends SerializerContext { public static final String JSON_simpleMode = "JsonSerializer.simpleMode"; /** - * <b>Configuration property:</b> Use whitespace. - * <p> - * <ul> - * <li><b>Name:</b> <js>"JsonSerializer.useWhitespace"</js> - * <li><b>Data type:</b> <code>Boolean</code> - * <li><b>Default:</b> <jk>false</jk> - * <li><b>Session-overridable:</b> <jk>true</jk> - * </ul> - * <p> - * If <jk>true</jk>, whitespace is added to the output to improve readability. - */ - public static final String JSON_useWhitespace = "JsonSerializer.useWhitespace"; - - /** * <b>Configuration property:</b> Prefix solidus <js>'/'</js> characters with escapes. * <p> * <ul> @@ -82,7 +68,6 @@ public final class JsonSerializerContext extends SerializerContext { final boolean simpleMode, - useWhitespace, escapeSolidus; /** @@ -95,7 +80,6 @@ public final class JsonSerializerContext extends SerializerContext { public JsonSerializerContext(ContextFactory cf) { super(cf); simpleMode = cf.getProperty(JSON_simpleMode, boolean.class, false); - useWhitespace = cf.getProperty(JSON_useWhitespace, boolean.class, false); escapeSolidus = cf.getProperty(JSON_escapeSolidus, boolean.class, false); } @@ -104,7 +88,6 @@ public final class JsonSerializerContext extends SerializerContext { return super.asMap() .append("JsonSerializerContext", new ObjectMap() .append("simpleMode", simpleMode) - .append("useWhitespace", useWhitespace) .append("escapeSolidus", escapeSolidus) ); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java index ae0fb4a..1d99bf7 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java @@ -18,7 +18,6 @@ import java.lang.reflect.*; import java.util.*; import org.apache.juneau.*; -import org.apache.juneau.MediaType; import org.apache.juneau.serializer.*; /** @@ -28,7 +27,7 @@ import org.apache.juneau.serializer.*; */ public final class JsonSerializerSession extends SerializerSession { - private final boolean simpleMode, useWhitespace, escapeSolidus; + private final boolean simpleMode, escapeSolidus; /** * Create a new session using properties specified in the context. @@ -49,11 +48,9 @@ public final class JsonSerializerSession extends SerializerSession { super(ctx, op, output, javaMethod, locale, timeZone, mediaType); if (op == null || op.isEmpty()) { simpleMode = ctx.simpleMode; - useWhitespace = ctx.useWhitespace; escapeSolidus = ctx.escapeSolidus; } else { simpleMode = op.getBoolean(JSON_simpleMode, ctx.simpleMode); - useWhitespace = op.getBoolean(JSON_useWhitespace, ctx.useWhitespace); escapeSolidus = op.getBoolean(JSON_escapeSolidus, ctx.escapeSolidus); } } @@ -68,15 +65,6 @@ public final class JsonSerializerSession extends SerializerSession { } /** - * Returns the {@link JsonSerializerContext#JSON_useWhitespace} setting value for this session. - * - * @return The {@link JsonSerializerContext#JSON_useWhitespace} setting value for this session. - */ - public final boolean isUseWhitespace() { - return useWhitespace; - } - - /** * Returns the {@link JsonSerializerContext#JSON_escapeSolidus} setting value for this session. * * @return The {@link JsonSerializerContext#JSON_escapeSolidus} setting value for this session. @@ -90,6 +78,6 @@ public final class JsonSerializerSession extends SerializerSession { Object output = getOutput(); if (output instanceof JsonWriter) return (JsonWriter)output; - return new JsonWriter(super.getWriter(), isUseIndentation(), isUseWhitespace(), isEscapeSolidus(), getQuoteChar(), isSimpleMode(), isTrimStrings(), getRelativeUriBase(), getAbsolutePathUriBase()); + return new JsonWriter(super.getWriter(), isUseWhitespace(), isEscapeSolidus(), getQuoteChar(), isSimpleMode(), isTrimStrings(), getRelativeUriBase(), getAbsolutePathUriBase()); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java index 4b3af99..093a4f0 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java @@ -55,8 +55,7 @@ public final class JsonWriter extends SerializerWriter { /** * Constructor. * @param out The writer being wrapped. - * @param useIndentation If <jk>true</jk>, tabs will be used in output. - * @param useWhitespace If <jk>true</jk>, whitespace will be used in output. + * @param useWhitespace If <jk>true</jk>, tabs and spaces will be used in output. * @param escapeSolidus If <jk>true</jk>, forward slashes should be escaped in the output. * @param quoteChar The quote character to use (i.e. <js>'\''</js> or <js>'"'</js>) * @param laxMode If <jk>true</jk>, JSON attributes will only be quoted when necessary. @@ -64,8 +63,8 @@ public final class JsonWriter extends SerializerWriter { * @param relativeUriBase The base (e.g. <js>https://localhost:9443/contextPath"</js>) for relative URIs (e.g. <js>"my/path"</js>). * @param absolutePathUriBase The base (e.g. <js>https://localhost:9443"</js>) for relative URIs with absolute paths (e.g. <js>"/contextPath/my/path"</js>). */ - protected JsonWriter(Writer out, boolean useIndentation, boolean useWhitespace, boolean escapeSolidus, char quoteChar, boolean laxMode, boolean trimStrings, String relativeUriBase, String absolutePathUriBase) { - super(out, useIndentation, useWhitespace, trimStrings, quoteChar, relativeUriBase, absolutePathUriBase); + protected JsonWriter(Writer out, boolean useWhitespace, boolean escapeSolidus, char quoteChar, boolean laxMode, boolean trimStrings, String relativeUriBase, String absolutePathUriBase) { + super(out, useWhitespace, trimStrings, quoteChar, relativeUriBase, absolutePathUriBase); this.laxMode = laxMode; this.escapeSolidus = escapeSolidus; this.ec = escapeSolidus ? encodedChars2 : encodedChars; @@ -90,8 +89,6 @@ public final class JsonWriter extends SerializerWriter { */ if (s == null) return this; -// if (trimStrings) -// s = s.trim(); boolean doConvert = false; for (int i = 0; i < s.length() && ! doConvert; i++) { char c = s.charAt(i); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/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 0b15adc..08b80e4 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 @@ -53,7 +53,6 @@ public final class MsgPackParser extends InputStreamParser { PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap(); ClassMeta<?> sType = eType.getSerializedClassMeta(); session.setCurrentClass(sType); - BeanRegistry breg = (pMeta == null ? session.getBeanRegistry() : pMeta.getBeanRegistry()); Object o = null; DataType dt = is.readDataType(); @@ -83,7 +82,7 @@ public final class MsgPackParser extends InputStreamParser { ObjectMap om = new ObjectMap(session); for (int i = 0; i < length; i++) om.put(parseAnything(session, string(), is, outer, pMeta), parseAnything(session, object(), is, om, pMeta)); - o = breg.cast(om); + o = session.cast(om, pMeta, eType); } if (sType.isObject()) { @@ -135,7 +134,7 @@ public final 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)); - o = breg.cast(m); + o = session.cast(m, pMeta, eType); } else if (dt == ARRAY) { Collection l = (sType.canCreateNewInstance(outer) ? (Collection)sType.newInstance() : new ObjectList(session)); for (int i = 0; i < length; i++) @@ -149,7 +148,7 @@ public final 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)); - o = breg.cast(m); + o = session.cast(m, pMeta, eType); } else if (dt == ARRAY) { Collection l = (sType.isCollection() && sType.canCreateNewInstance(outer) ? (Collection)sType.newInstance() : new ObjectList(session)); for (int i = 0; i < length; i++) @@ -163,7 +162,7 @@ public final class MsgPackParser extends InputStreamParser { 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())) - o = breg.cast(m); + o = session.cast(m, pMeta, eType); else throw new ParseException(session, "Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason()); } else { @@ -204,277 +203,277 @@ public final class MsgPackParser extends InputStreamParser { //-------------------------------------------------------------------------------- @Override /* Parser */ - public Parser setTrimStrings(boolean value) throws LockedException { + public MsgPackParser setTrimStrings(boolean value) throws LockedException { super.setTrimStrings(value); return this; } @Override /* Parser */ - public Parser setStrict(boolean value) throws LockedException { + public MsgPackParser setStrict(boolean value) throws LockedException { super.setStrict(value); return this; } @Override /* Parser */ - public Parser setInputStreamCharset(String value) throws LockedException { + public MsgPackParser setInputStreamCharset(String value) throws LockedException { super.setInputStreamCharset(value); return this; } @Override /* Parser */ - public Parser setFileCharset(String value) throws LockedException { + public MsgPackParser setFileCharset(String value) throws LockedException { super.setFileCharset(value); return this; } @Override /* CoreApi */ - public Parser setBeansRequireDefaultConstructor(boolean value) throws LockedException { + public MsgPackParser setBeansRequireDefaultConstructor(boolean value) throws LockedException { super.setBeansRequireDefaultConstructor(value); return this; } @Override /* CoreApi */ - public Parser setBeansRequireSerializable(boolean value) throws LockedException { + public MsgPackParser setBeansRequireSerializable(boolean value) throws LockedException { super.setBeansRequireSerializable(value); return this; } @Override /* CoreApi */ - public Parser setBeansRequireSettersForGetters(boolean value) throws LockedException { + public MsgPackParser setBeansRequireSettersForGetters(boolean value) throws LockedException { super.setBeansRequireSettersForGetters(value); return this; } @Override /* CoreApi */ - public Parser setBeansRequireSomeProperties(boolean value) throws LockedException { + public MsgPackParser setBeansRequireSomeProperties(boolean value) throws LockedException { super.setBeansRequireSomeProperties(value); return this; } @Override /* CoreApi */ - public Parser setBeanMapPutReturnsOldValue(boolean value) throws LockedException { + public MsgPackParser setBeanMapPutReturnsOldValue(boolean value) throws LockedException { super.setBeanMapPutReturnsOldValue(value); return this; } @Override /* CoreApi */ - public Parser setBeanConstructorVisibility(Visibility value) throws LockedException { + public MsgPackParser setBeanConstructorVisibility(Visibility value) throws LockedException { super.setBeanConstructorVisibility(value); return this; } @Override /* CoreApi */ - public Parser setBeanClassVisibility(Visibility value) throws LockedException { + public MsgPackParser setBeanClassVisibility(Visibility value) throws LockedException { super.setBeanClassVisibility(value); return this; } @Override /* CoreApi */ - public Parser setBeanFieldVisibility(Visibility value) throws LockedException { + public MsgPackParser setBeanFieldVisibility(Visibility value) throws LockedException { super.setBeanFieldVisibility(value); return this; } @Override /* CoreApi */ - public Parser setMethodVisibility(Visibility value) throws LockedException { + public MsgPackParser setMethodVisibility(Visibility value) throws LockedException { super.setMethodVisibility(value); return this; } @Override /* CoreApi */ - public Parser setUseJavaBeanIntrospector(boolean value) throws LockedException { + public MsgPackParser setUseJavaBeanIntrospector(boolean value) throws LockedException { super.setUseJavaBeanIntrospector(value); return this; } @Override /* CoreApi */ - public Parser setUseInterfaceProxies(boolean value) throws LockedException { + public MsgPackParser setUseInterfaceProxies(boolean value) throws LockedException { super.setUseInterfaceProxies(value); return this; } @Override /* CoreApi */ - public Parser setIgnoreUnknownBeanProperties(boolean value) throws LockedException { + public MsgPackParser setIgnoreUnknownBeanProperties(boolean value) throws LockedException { super.setIgnoreUnknownBeanProperties(value); return this; } @Override /* CoreApi */ - public Parser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException { + public MsgPackParser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException { super.setIgnoreUnknownNullBeanProperties(value); return this; } @Override /* CoreApi */ - public Parser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException { + public MsgPackParser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException { super.setIgnorePropertiesWithoutSetters(value); return this; } @Override /* CoreApi */ - public Parser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException { + public MsgPackParser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException { super.setIgnoreInvocationExceptionsOnGetters(value); return this; } @Override /* CoreApi */ - public Parser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException { + public MsgPackParser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException { super.setIgnoreInvocationExceptionsOnSetters(value); return this; } @Override /* CoreApi */ - public Parser setSortProperties(boolean value) throws LockedException { + public MsgPackParser setSortProperties(boolean value) throws LockedException { super.setSortProperties(value); return this; } @Override /* CoreApi */ - public Parser setNotBeanPackages(String...values) throws LockedException { + public MsgPackParser setNotBeanPackages(String...values) throws LockedException { super.setNotBeanPackages(values); return this; } @Override /* CoreApi */ - public Parser setNotBeanPackages(Collection<String> values) throws LockedException { + public MsgPackParser setNotBeanPackages(Collection<String> values) throws LockedException { super.setNotBeanPackages(values); return this; } @Override /* CoreApi */ - public Parser addNotBeanPackages(String...values) throws LockedException { + public MsgPackParser addNotBeanPackages(String...values) throws LockedException { super.addNotBeanPackages(values); return this; } @Override /* CoreApi */ - public Parser addNotBeanPackages(Collection<String> values) throws LockedException { + public MsgPackParser addNotBeanPackages(Collection<String> values) throws LockedException { super.addNotBeanPackages(values); return this; } @Override /* CoreApi */ - public Parser removeNotBeanPackages(String...values) throws LockedException { + public MsgPackParser removeNotBeanPackages(String...values) throws LockedException { super.removeNotBeanPackages(values); return this; } @Override /* CoreApi */ - public Parser removeNotBeanPackages(Collection<String> values) throws LockedException { + public MsgPackParser removeNotBeanPackages(Collection<String> values) throws LockedException { super.removeNotBeanPackages(values); return this; } @Override /* CoreApi */ - public Parser setNotBeanClasses(Class<?>...values) throws LockedException { + public MsgPackParser setNotBeanClasses(Class<?>...values) throws LockedException { super.setNotBeanClasses(values); return this; } @Override /* CoreApi */ - public Parser setNotBeanClasses(Collection<Class<?>> values) throws LockedException { + public MsgPackParser setNotBeanClasses(Collection<Class<?>> values) throws LockedException { super.setNotBeanClasses(values); return this; } @Override /* CoreApi */ - public Parser addNotBeanClasses(Class<?>...values) throws LockedException { + public MsgPackParser addNotBeanClasses(Class<?>...values) throws LockedException { super.addNotBeanClasses(values); return this; } @Override /* CoreApi */ - public Parser addNotBeanClasses(Collection<Class<?>> values) throws LockedException { + public MsgPackParser addNotBeanClasses(Collection<Class<?>> values) throws LockedException { super.addNotBeanClasses(values); return this; } @Override /* CoreApi */ - public Parser removeNotBeanClasses(Class<?>...values) throws LockedException { + public MsgPackParser removeNotBeanClasses(Class<?>...values) throws LockedException { super.removeNotBeanClasses(values); return this; } @Override /* CoreApi */ - public Parser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException { + public MsgPackParser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException { super.removeNotBeanClasses(values); return this; } @Override /* CoreApi */ - public Parser setBeanFilters(Class<?>...values) throws LockedException { + public MsgPackParser setBeanFilters(Class<?>...values) throws LockedException { super.setBeanFilters(values); return this; } @Override /* CoreApi */ - public Parser setBeanFilters(Collection<Class<?>> values) throws LockedException { + public MsgPackParser setBeanFilters(Collection<Class<?>> values) throws LockedException { super.setBeanFilters(values); return this; } @Override /* CoreApi */ - public Parser addBeanFilters(Class<?>...values) throws LockedException { + public MsgPackParser addBeanFilters(Class<?>...values) throws LockedException { super.addBeanFilters(values); return this; } @Override /* CoreApi */ - public Parser addBeanFilters(Collection<Class<?>> values) throws LockedException { + public MsgPackParser addBeanFilters(Collection<Class<?>> values) throws LockedException { super.addBeanFilters(values); return this; } @Override /* CoreApi */ - public Parser removeBeanFilters(Class<?>...values) throws LockedException { + public MsgPackParser removeBeanFilters(Class<?>...values) throws LockedException { super.removeBeanFilters(values); return this; } @Override /* CoreApi */ - public Parser removeBeanFilters(Collection<Class<?>> values) throws LockedException { + public MsgPackParser removeBeanFilters(Collection<Class<?>> values) throws LockedException { super.removeBeanFilters(values); return this; } @Override /* CoreApi */ - public Parser setPojoSwaps(Class<?>...values) throws LockedException { + public MsgPackParser setPojoSwaps(Class<?>...values) throws LockedException { super.setPojoSwaps(values); return this; } @Override /* CoreApi */ - public Parser setPojoSwaps(Collection<Class<?>> values) throws LockedException { + public MsgPackParser setPojoSwaps(Collection<Class<?>> values) throws LockedException { super.setPojoSwaps(values); return this; } @Override /* CoreApi */ - public Parser addPojoSwaps(Class<?>...values) throws LockedException { + public MsgPackParser addPojoSwaps(Class<?>...values) throws LockedException { super.addPojoSwaps(values); return this; } @Override /* CoreApi */ - public Parser addPojoSwaps(Collection<Class<?>> values) throws LockedException { + public MsgPackParser addPojoSwaps(Collection<Class<?>> values) throws LockedException { super.addPojoSwaps(values); return this; } @Override /* CoreApi */ - public Parser removePojoSwaps(Class<?>...values) throws LockedException { + public MsgPackParser removePojoSwaps(Class<?>...values) throws LockedException { super.removePojoSwaps(values); return this; } @Override /* CoreApi */ - public Parser removePojoSwaps(Collection<Class<?>> values) throws LockedException { + public MsgPackParser removePojoSwaps(Collection<Class<?>> values) throws LockedException { super.removePojoSwaps(values); return this; } @Override /* CoreApi */ - public Parser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException { + public MsgPackParser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException { super.setImplClasses(values); return this; } @@ -486,109 +485,109 @@ public final class MsgPackParser extends InputStreamParser { } @Override /* CoreApi */ - public Parser setBeanDictionary(Class<?>...values) throws LockedException { + public MsgPackParser setBeanDictionary(Class<?>...values) throws LockedException { super.setBeanDictionary(values); return this; } @Override /* CoreApi */ - public Parser setBeanDictionary(Collection<Class<?>> values) throws LockedException { + public MsgPackParser setBeanDictionary(Collection<Class<?>> values) throws LockedException { super.setBeanDictionary(values); return this; } @Override /* CoreApi */ - public Parser addToBeanDictionary(Class<?>...values) throws LockedException { + public MsgPackParser addToBeanDictionary(Class<?>...values) throws LockedException { super.addToBeanDictionary(values); return this; } @Override /* CoreApi */ - public Parser addToBeanDictionary(Collection<Class<?>> values) throws LockedException { + public MsgPackParser addToBeanDictionary(Collection<Class<?>> values) throws LockedException { super.addToBeanDictionary(values); return this; } @Override /* CoreApi */ - public Parser removeFromBeanDictionary(Class<?>...values) throws LockedException { + public MsgPackParser removeFromBeanDictionary(Class<?>...values) throws LockedException { super.removeFromBeanDictionary(values); return this; } @Override /* CoreApi */ - public Parser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException { + public MsgPackParser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException { super.removeFromBeanDictionary(values); return this; } @Override /* CoreApi */ - public Parser setBeanTypePropertyName(String value) throws LockedException { + public MsgPackParser setBeanTypePropertyName(String value) throws LockedException { super.setBeanTypePropertyName(value); return this; } @Override /* CoreApi */ - public Parser setDefaultParser(Class<?> value) throws LockedException { + public MsgPackParser setDefaultParser(Class<?> value) throws LockedException { super.setDefaultParser(value); return this; } @Override /* CoreApi */ - public Parser setLocale(Locale value) throws LockedException { + public MsgPackParser setLocale(Locale value) throws LockedException { super.setLocale(value); return this; } @Override /* CoreApi */ - public Parser setTimeZone(TimeZone value) throws LockedException { + public MsgPackParser setTimeZone(TimeZone value) throws LockedException { super.setTimeZone(value); return this; } @Override /* CoreApi */ - public Parser setMediaType(MediaType value) throws LockedException { + public MsgPackParser setMediaType(MediaType value) throws LockedException { super.setMediaType(value); return this; } @Override /* CoreApi */ - public Parser setDebug(boolean value) throws LockedException { + public MsgPackParser setDebug(boolean value) throws LockedException { super.setDebug(value); return this; } @Override /* CoreApi */ - public Parser setProperty(String name, Object value) throws LockedException { + public MsgPackParser setProperty(String name, Object value) throws LockedException { super.setProperty(name, value); return this; } @Override /* CoreApi */ - public Parser setProperties(ObjectMap properties) throws LockedException { + public MsgPackParser setProperties(ObjectMap properties) throws LockedException { super.setProperties(properties); return this; } @Override /* CoreApi */ - public Parser addToProperty(String name, Object value) throws LockedException { + public MsgPackParser addToProperty(String name, Object value) throws LockedException { super.addToProperty(name, value); return this; } @Override /* CoreApi */ - public Parser putToProperty(String name, Object key, Object value) throws LockedException { + public MsgPackParser putToProperty(String name, Object key, Object value) throws LockedException { super.putToProperty(name, key, value); return this; } @Override /* CoreApi */ - public Parser putToProperty(String name, Object value) throws LockedException { + public MsgPackParser putToProperty(String name, Object value) throws LockedException { super.putToProperty(name, value); return this; } @Override /* CoreApi */ - public Parser removeFromProperty(String name, Object value) throws LockedException { + public MsgPackParser removeFromProperty(String name, Object value) throws LockedException { super.removeFromProperty(name, value); return this; } @@ -599,7 +598,7 @@ public final class MsgPackParser extends InputStreamParser { //-------------------------------------------------------------------------------- @Override /* CoreApi */ - public Parser setClassLoader(ClassLoader classLoader) throws LockedException { + public MsgPackParser setClassLoader(ClassLoader classLoader) throws LockedException { super.setClassLoader(classLoader); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java index 4ce103d..cd842d6 100644 --- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java @@ -57,7 +57,6 @@ public class MsgPackSerializer extends OutputStreamSerializer { if (eType == null) eType = object(); - boolean addTypeProperty; // Add "_type" attribute to element? ClassMeta<?> aType; // The actual type ClassMeta<?> sType; // The serialized type @@ -71,7 +70,7 @@ public class MsgPackSerializer extends OutputStreamSerializer { } sType = aType.getSerializedClassMeta(); - addTypeProperty = (session.isAddBeanTypeProperties() && ! eType.equals(aType)); + String typeName = session.getBeanTypeName(eType, aType, pMeta); // Swap if necessary PojoSwap swap = aType.getPojoSwap(); @@ -92,12 +91,12 @@ public class MsgPackSerializer extends OutputStreamSerializer { else if (sType.isNumber()) out.appendNumber((Number)o); else if (sType.isBean()) - serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty); + serializeBeanMap(session, out, session.toBeanMap(o), typeName); else if (sType.isUri() || (pMeta != null && pMeta.isUri())) out.appendString(session.resolveUri(o.toString())); else if (sType.isMap()) { if (o instanceof BeanMap) - serializeBeanMap(session, out, (BeanMap)o, addTypeProperty); + serializeBeanMap(session, out, (BeanMap)o, typeName); else serializeMap(session, out, (Map)o, eType); } @@ -138,9 +137,9 @@ public class MsgPackSerializer extends OutputStreamSerializer { } } - private void serializeBeanMap(MsgPackSerializerSession session, MsgPackOutputStream out, final BeanMap<?> m, boolean addTypeProperty) throws Exception { + private void serializeBeanMap(MsgPackSerializerSession session, MsgPackOutputStream out, final BeanMap<?> m, String typeName) throws Exception { - List<BeanPropertyValue> values = m.getValues(session.isTrimNulls(), addTypeProperty ? session.createBeanTypeNameProperty(m) : null); + List<BeanPropertyValue> values = m.getValues(session.isTrimNulls(), typeName != null ? session.createBeanTypeNameProperty(m, typeName) : null); int size = values.size(); for (BeanPropertyValue p : values) @@ -234,8 +233,8 @@ public class MsgPackSerializer extends OutputStreamSerializer { } @Override /* Serializer */ - public MsgPackSerializer setUseIndentation(boolean value) throws LockedException { - super.setUseIndentation(value); + public MsgPackSerializer setUseWhitespace(boolean value) throws LockedException { + super.setUseWhitespace(value); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java index 6f2247b..3d9fa30 100644 --- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java +++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java @@ -78,7 +78,7 @@ public final class ParserGroup extends Lockable { */ public ParserGroup append(Parser p) { checkLock(); - synchronized(parsers) { + synchronized(this) { cache.clear(); parsers.add(0, p); } @@ -110,7 +110,7 @@ public final class ParserGroup extends Lockable { append(p.newInstance()); } catch (NoClassDefFoundError e) { // Ignore if dependent library not found (e.g. Jena). - System.err.println(e); + System.err.println(e); // NOT DEBUG } return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/parser/ParserReader.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserReader.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserReader.java index 07f21fe..de3187a 100644 --- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserReader.java +++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserReader.java @@ -109,6 +109,20 @@ public class ParserReader extends Reader { } /** + * Same as {@link #read()} but skips over any whitespace characters. + * + * @return The first non-whitespace character, or -1 if the end of stream reached. + * @throws IOException + */ + public final int readSkipWs() throws IOException { + while (true) { + int c = read(); + if (c == -1 || ! Character.isWhitespace(c)) + return c; + } + } + + /** * Same as {@link #read()} but detects and combines extended unicode characters (i.e. characters * above 0x10000). * @@ -205,7 +219,7 @@ public class ParserReader extends Reader { /** * Peeks the next character in the stream. * <p> - * This is equivalent to doing a {@code read()} followed by an {@code unread()}. + * This is equivalent to doing a {@code read()} followed by an {@code unread()}. * * @return The peeked character, or (char)-1 if the end of the stream has been reached. * @throws IOException If a problem occurred trying to read from the reader. @@ -218,6 +232,25 @@ public class ParserReader extends Reader { } /** + * Same as {@link #peek()} but skips over any whitespace characters. + * <p> + * This is equivalent to doing a {@code read()} followed by an {@code unread()}. + * + * @return The peeked character, or (char)-1 if the end of the stream has been reached. + * @throws IOException If a problem occurred trying to read from the reader. + */ + public final int peekSkipWs() throws IOException { + while(true) { + int c = read(); + boolean isWs = Character.isWhitespace(c); + if (c != -1 && ! isWs) + unread(); + if (! isWs) + return c; + } + } + + /** * Read the specified number of characters off the stream. * * @param num The number of characters to read. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/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 e471056..8a4a87b 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 @@ -20,6 +20,7 @@ import java.nio.charset.*; import java.util.*; import org.apache.juneau.*; +import org.apache.juneau.internal.*; /** * Session object that lives for the duration of a single use of {@link Parser}. @@ -103,6 +104,8 @@ public class ParserSession extends BeanSession { return (InputStream)input; if (input instanceof byte[]) return new ByteArrayInputStream((byte[])input); + if (input instanceof String) + return new ByteArrayInputStream(StringUtils.fromHex((String)input)); if (input instanceof File) try { inputStream = new FileInputStream((File)input); @@ -269,6 +272,77 @@ public class ParserSession extends BeanSession { } /** + * Converts the specified <code>ObjectMap</code> into a bean identified by the <js>"_type"</js> + * property in the map. + * + * @param m The map to convert to a bean. + * @param pMeta The current bean property being parsed. + * @param eType The current expected type being parsed. + * @return The converted bean, or the same map if the <js>"_type"</js> entry wasn't found + * or didn't resolve to a bean. + */ + public final Object cast(ObjectMap m, BeanPropertyMeta pMeta, ClassMeta<?> eType) { + + String btpn = getBeanTypePropertyName(); + + Object o = m.get(btpn); + if (o == null) + return m; + String typeName = o.toString(); + + ClassMeta<?> cm = getClassMeta(typeName, pMeta, eType); + + if (cm != null) { + BeanMap<?> bm = m.getBeanSession().newBeanMap(cm.getInnerClass()); + + // Iterate through all the entries in the map and set the individual field values. + for (Map.Entry<String,Object> e : m.entrySet()) { + String k = e.getKey(); + Object v = e.getValue(); + if (! k.equals(btpn)) { + // Attempt to recursively cast child maps. + if (v instanceof ObjectMap) + v = cast((ObjectMap)v, pMeta, eType); + bm.put(k, v); + } + } + return bm.getBean(); + } + + return m; + } + + /** + * Give the specified dictionary name, resolve it to a class. + * + * @param typeName The dictionary name to resolve. + * @param pMeta The bean property we're currently parsing. + * @param eType The expected type we're currently parsing. + * @return The resolved class, or <jk>null</jk> if the type name could not be resolved. + */ + public final ClassMeta<?> getClassMeta(String typeName, BeanPropertyMeta pMeta, ClassMeta<?> eType) { + BeanRegistry br = null; + + // Resolve via @BeanProperty(beanDictionary={}) + if (pMeta != null) { + br = pMeta.getBeanRegistry(); + if (br != null && br.hasName(typeName)) + return br.getClassMeta(typeName); + } + + // Resolve via @Bean(beanDictionary={}) on the expected type where the + // expected type is an interface with subclasses. + if (eType != null) { + br = eType.getBeanRegistry(); + if (br != null && br.hasName(typeName)) + return br.getClassMeta(typeName); + } + + // Last resort, resolve using the session registry. + return getBeanRegistry().getClassMeta(typeName); + } + + /** * Perform cleanup on this context object if necessary. */ @Override http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java index 0c8f215..0901c14 100644 --- a/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java @@ -15,6 +15,7 @@ package org.apache.juneau.serializer; import java.io.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.internal.*; /** * Subclass of {@link Serializer} for byte-based serializers. @@ -50,7 +51,7 @@ public abstract class OutputStreamSerializer extends Serializer { * Convenience method for serializing an object to a <code><jk>byte</jk></code>. * * @param o The object to serialize. - * @return The output serialized to a string. + * @return The output serialized to a byte array. * @throws SerializeException If a problem occurred trying to convert the output. */ @Override @@ -59,4 +60,17 @@ public abstract class OutputStreamSerializer extends Serializer { serialize(createSession(baos), o); return baos.toByteArray(); } + + /** + * Convenience method for serializing an object to a hex-encoded String. + * + * @param o The object to serialize. + * @return The output serialized to a hex-encoded string. + * @throws SerializeException If a problem occurred trying to convert the output. + */ + public final String serializeToHex(Object o) throws SerializeException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + serialize(createSession(baos), o); + return StringUtils.toHex(baos.toByteArray()); + } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java index ac43ecb..313ff47 100644 --- a/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java @@ -413,30 +413,29 @@ public abstract class Serializer extends CoreApi { } /** - * <b>Configuration property:</b> Use indentation. + * <b>Configuration property:</b> Use whitespace. * <p> * <ul> - * <li><b>Name:</b> <js>"Serializer.useIndentation"</js> + * <li><b>Name:</b> <js>"Serializer.useWhitepace"</js> * <li><b>Data type:</b> <code>Boolean</code> * <li><b>Default:</b> <jk>false</jk> * <li><b>Session-overridable:</b> <jk>true</jk> * </ul> * <p> - * If <jk>true</jk>, newlines and indentation is added to the output to improve readability. + * If <jk>true</jk>, newlines and indentation and spaces are added to the output to improve readability. * <p> * <h5 class='section'>Notes:</h5> * <ul> - * <li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_useIndentation</jsf>, value)</code>. - * <li>Checking for recursion can cause a small performance penalty. + * <li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_useWhitespace</jsf>, value)</code>. * </ul> * * @param value The new value for this property. * @return This object (for method chaining). * @throws LockedException If {@link #lock()} was called on this class. - * @see SerializerContext#SERIALIZER_useIndentation + * @see SerializerContext#SERIALIZER_useWhitespace */ - public Serializer setUseIndentation(boolean value) throws LockedException { - return setProperty(SERIALIZER_useIndentation, value); + public Serializer setUseWhitespace(boolean value) throws LockedException { + return setProperty(SERIALIZER_useWhitespace, value); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java index 7abdd45..38fdfef 100644 --- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java +++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java @@ -98,18 +98,18 @@ public class SerializerContext extends BeanContext { public static final String SERIALIZER_ignoreRecursions = "Serializer.ignoreRecursions"; /** - * <b>Configuration property:</b> Use indentation. + * <b>Configuration property:</b> Use whitespace. * <p> * <ul> - * <li><b>Name:</b> <js>"Serializer.useIndentation"</js> + * <li><b>Name:</b> <js>"Serializer.useWhitespace"</js> * <li><b>Data type:</b> <code>Boolean</code> * <li><b>Default:</b> <jk>false</jk> * <li><b>Session-overridable:</b> <jk>true</jk> * </ul> * <p> - * If <jk>true</jk>, newlines and indentation is added to the output to improve readability. + * If <jk>true</jk>, whitespace is added to the output to improve readability. */ - public static final String SERIALIZER_useIndentation = "Serializer.useIndentation"; + public static final String SERIALIZER_useWhitespace = "Serializer.useWhitespace"; /** * <b>Configuration property:</b> Add <js>"_type"</js> properties when needed. @@ -318,7 +318,7 @@ public class SerializerContext extends BeanContext { final boolean detectRecursions, ignoreRecursions, - useIndentation, + useWhitespace, addBeanTypeProperties, trimNulls, trimEmptyCollections, @@ -340,8 +340,8 @@ public class SerializerContext extends BeanContext { initialDepth = cf.getProperty(SERIALIZER_initialDepth, int.class, 0); detectRecursions = cf.getProperty(SERIALIZER_detectRecursions, boolean.class, false); ignoreRecursions = cf.getProperty(SERIALIZER_ignoreRecursions, boolean.class, false); - useIndentation = cf.getProperty(SERIALIZER_useIndentation, boolean.class, false); - addBeanTypeProperties = cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, false); + useWhitespace = cf.getProperty(SERIALIZER_useWhitespace, boolean.class, false); + addBeanTypeProperties = cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true); trimNulls = cf.getProperty(SERIALIZER_trimNullProperties, boolean.class, true); trimEmptyCollections = cf.getProperty(SERIALIZER_trimEmptyCollections, boolean.class, false); trimEmptyMaps = cf.getProperty(SERIALIZER_trimEmptyMaps, boolean.class, false); @@ -379,7 +379,7 @@ public class SerializerContext extends BeanContext { .append("initialDepth", initialDepth) .append("detectRecursions", detectRecursions) .append("ignoreRecursions", ignoreRecursions) - .append("useIndentation", useIndentation) + .append("useWhitespace", useWhitespace) .append("addBeanTypeProperties", addBeanTypeProperties) .append("trimNulls", trimNulls) .append("trimEmptyCollections", trimEmptyCollections) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java index 63f0400..d2d6847 100644 --- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java +++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java @@ -51,7 +51,7 @@ import org.apache.juneau.*; * g.append(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>); * * <jc>// Change settings for all serializers in the group and lock it.</jc> - * g.setProperty(SerializerContext.<jsf>SERIALIZER_useIndentation</jsf>, <jk>true</jk>) + * g.setProperty(SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, <jk>true</jk>) * .addPojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>) * .lock(); * @@ -79,7 +79,7 @@ public final class SerializerGroup extends Lockable { */ public SerializerGroup append(Serializer s) { checkLock(); - synchronized(serializers) { + synchronized(this) { cache.clear(); serializers.add(0, s); } @@ -111,7 +111,7 @@ public final class SerializerGroup extends Lockable { append(s.newInstance()); } catch (NoClassDefFoundError e) { // Ignore if dependent library not found (e.g. Jena). - System.err.println(e); + System.err.println(e); // NOT DEBUG } return this; } @@ -303,17 +303,17 @@ public final class SerializerGroup extends Lockable { } /** - * Calls {@link Serializer#setUseIndentation(boolean)} on all serializers in this group. + * Calls {@link Serializer#setUseWhitespace(boolean)} on all serializers in this group. * * @param value The new value for this property. * @return This object (for method chaining). * @throws LockedException If {@link #lock()} was called on this class. - * @see SerializerContext#SERIALIZER_useIndentation + * @see SerializerContext#SERIALIZER_useWhitespace */ - public SerializerGroup setUseIndentation(boolean value) throws LockedException { + public SerializerGroup setUseWhitespace(boolean value) throws LockedException { checkLock(); for (Serializer s : serializers) - s.setUseIndentation(value); + s.setUseWhitespace(value); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java index 1ad5ee5..7d499e6 100644 --- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java @@ -20,7 +20,6 @@ import java.lang.reflect.*; import java.util.*; import org.apache.juneau.*; -import org.apache.juneau.MediaType; import org.apache.juneau.internal.*; import org.apache.juneau.transform.*; @@ -43,7 +42,7 @@ public class SerializerSession extends BeanSession { private final boolean detectRecursions, ignoreRecursions, - useIndentation, + useWhitespace, addBeanTypeProperties, trimNulls, trimEmptyCollections, @@ -103,7 +102,7 @@ public class SerializerSession extends BeanSession { initialDepth = ctx.initialDepth; detectRecursions = ctx.detectRecursions; ignoreRecursions = ctx.ignoreRecursions; - useIndentation = ctx.useIndentation; + useWhitespace = ctx.useWhitespace; addBeanTypeProperties = ctx.addBeanTypeProperties; trimNulls = ctx.trimNulls; trimEmptyCollections = ctx.trimEmptyCollections; @@ -119,7 +118,7 @@ public class SerializerSession extends BeanSession { initialDepth = op.getInt(SERIALIZER_initialDepth, ctx.initialDepth); detectRecursions = op.getBoolean(SERIALIZER_detectRecursions, ctx.detectRecursions); ignoreRecursions = op.getBoolean(SERIALIZER_ignoreRecursions, ctx.ignoreRecursions); - useIndentation = op.getBoolean(SERIALIZER_useIndentation, ctx.useIndentation); + useWhitespace = op.getBoolean(SERIALIZER_useWhitespace, ctx.useWhitespace); addBeanTypeProperties = op.getBoolean(SERIALIZER_addBeanTypeProperties, ctx.addBeanTypeProperties); trimNulls = op.getBoolean(SERIALIZER_trimNullProperties, ctx.trimNulls); trimEmptyCollections = op.getBoolean(SERIALIZER_trimEmptyCollections, ctx.trimEmptyCollections); @@ -273,12 +272,12 @@ public class SerializerSession extends BeanSession { } /** - * Returns the {@link SerializerContext#SERIALIZER_useIndentation} setting value for this session. + * Returns the {@link SerializerContext#SERIALIZER_useWhitespace} setting value for this session. * - * @return The {@link SerializerContext#SERIALIZER_useIndentation} setting value for this session. + * @return The {@link SerializerContext#SERIALIZER_useWhitespace} setting value for this session. */ - public final boolean isUseIndentation() { - return useIndentation; + public final boolean isUseWhitespace() { + return useWhitespace; } /** @@ -682,16 +681,63 @@ public class SerializerSession extends BeanSession { /** * Create a "_type" property that contains the dictionary name of the bean. * - * @param m - * The bean map to create a class property on. - * @return - * A new bean property value. + * @param m The bean map to create a class property on. + * @param typeName The type name of the bean. + * @return A new bean property value. */ - public BeanPropertyValue createBeanTypeNameProperty(BeanMap<?> m) { + public BeanPropertyValue createBeanTypeNameProperty(BeanMap<?> m, String typeName) { BeanMeta<?> bm = m.getMeta(); - String name = bm.getClassMeta().getDictionaryName(); - if (name == null) + return new BeanPropertyValue(bm.getTypeProperty(), typeName, null); + } + + /** + * Resolves the dictionary name for the actual type. + * + * @param eType The expected type of the bean property. + * @param aType The actual type of the bean property. + * @param pMeta The current bean property being serialized. + * @return The bean dictionary name, or <jk>null</jk> if a name could not be found. + */ + public String getBeanTypeName(ClassMeta<?> eType, ClassMeta<?> aType, BeanPropertyMeta pMeta) { + if (eType == aType) return null; - return new BeanPropertyValue(bm.getTypeProperty(), name, null); + + if (! addBeanTypeProperties) + return null; + + String eTypeTn = eType.getDictionaryName(); + + // First see if it's defined on the actual type. + String tn = aType.getDictionaryName(); + if (tn != null && ! tn.equals(eTypeTn)) { + return tn; + } + + // Then see if it's defined on the expected type. + // The expected type might be an interface with mappings for implementation classes. + BeanRegistry br = eType.getBeanRegistry(); + if (br != null) { + tn = br.getTypeName(aType); + if (tn != null && ! tn.equals(eTypeTn)) + return tn; + } + + // Then look on the bean property. + br = pMeta == null ? null : pMeta.getBeanRegistry(); + if (br != null) { + tn = br.getTypeName(aType); + if (tn != null && ! tn.equals(eTypeTn)) + return tn; + } + + // Finally look in the session. + br = getBeanRegistry(); + if (br != null) { + tn = br.getTypeName(aType); + if (tn != null && ! tn.equals(eTypeTn)) + return tn; + } + + return null; } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerWriter.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerWriter.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerWriter.java index 00f8b8b..1e6272b 100644 --- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerWriter.java +++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerWriter.java @@ -33,9 +33,6 @@ public class SerializerWriter extends Writer { /** The underlying writer. */ protected final Writer out; - /** Use-indentation flag. */ - protected final boolean useIndentation; - /** Use-whitespace flag. */ protected final boolean useWhitespace; @@ -53,16 +50,14 @@ public class SerializerWriter extends Writer { /** * @param out The writer being wrapped. - * @param useIndentation If <jk>true</jk>, calling {@link #cr(int)} will create an indentation. - * @param useWhitespace If <jk>true</jk>, calling {@link #s()} will write a space character. + * @param useWhitespace If <jk>true</jk>, calling {@link #cr(int)} will create an indentation and calling {@link #s()} will write a space character. * @param trimStrings If <jk>true</jk>, strings should be trimmed before they're serialized. * @param quoteChar The character to write when {@link #q()} is called. * @param relativeUriBase The base (e.g. <js>https://localhost:9443/contextPath"</js>) for relative URIs (e.g. <js>"my/path"</js>). * @param absolutePathUriBase The base (e.g. <js>https://localhost:9443"</js>) for relative URIs with absolute paths (e.g. <js>"/contextPath/my/path"</js>). */ - public SerializerWriter(Writer out, boolean useIndentation, boolean useWhitespace, boolean trimStrings, char quoteChar, String relativeUriBase, String absolutePathUriBase) { + public SerializerWriter(Writer out, boolean useWhitespace, boolean trimStrings, char quoteChar, String relativeUriBase, String absolutePathUriBase) { this.out = out; - this.useIndentation = useIndentation; this.useWhitespace = useWhitespace; this.trimStrings = trimStrings; this.quoteChar = quoteChar; @@ -73,21 +68,21 @@ public class SerializerWriter extends Writer { /** * Performs a carriage return. * <p> - * Adds a newline and the specified number of tabs (if the {@code useIndentation} setting is enabled) to the output. + * Adds a newline and the specified number of tabs (if the {@code useWhitespace} setting is enabled) to the output. * * @param depth The indentation. * @throws IOException If a problem occurred trying to write to the writer. * @return This object (for method chaining). */ public SerializerWriter cr(int depth) throws IOException { - if (useIndentation) + if (useWhitespace) return nl().i(depth); return this; } /** - * Writes an indent (if the {@code useIndentation} setting is enabled), followed by text, - * followed by a newline (if the {@code useIndentation} setting is enabled). + * Writes an indent (if the {@code useWhitespace} setting is enabled), followed by text, + * followed by a newline (if the {@code useWhitespace} setting is enabled). * * @param indent The number of tabs to indent. * @param text The text to write. @@ -99,7 +94,7 @@ public class SerializerWriter extends Writer { } /** - * Writes the specified text followed by a newline (if the {@code useIndentation} setting is enabled). + * Writes the specified text followed by a newline (if the {@code useWhitespace} setting is enabled). * * @param text The text to write. * @throws IOException If a problem occurred trying to write to the writer. @@ -110,7 +105,7 @@ public class SerializerWriter extends Writer { } /** - * Writes an indent (if the {@code useIndentation} setting is enabled), followed by text. + * Writes an indent (if the {@code useWhitespace} setting is enabled), followed by text. * * @param indent The number of tabs to indent. * @param text The text to write. @@ -122,7 +117,7 @@ public class SerializerWriter extends Writer { } /** - * Writes an indent (if the {@code useIndentation} setting is enabled), followed by text. + * Writes an indent (if the {@code useWhitespace} setting is enabled), followed by text. * * @param indent The number of tabs to indent. * @param c The character to write. @@ -134,8 +129,8 @@ public class SerializerWriter extends Writer { } /** - * Writes an indent (if the {@code useIndentation} setting is enabled), followed by text, - * optionally followed by a newline (if the {@code useIndentation} setting is enabled). + * Writes an indent (if the {@code useWhitespace} setting is enabled), followed by text, + * optionally followed by a newline (if the {@code useWhitespace} setting is enabled). * * @param indent The number of tabs to indent. * @param newline If <jk>true</jk>, then a newline is written. @@ -222,40 +217,40 @@ public class SerializerWriter extends Writer { } /** - * Writes an indent to the writer if the {@code useIndentation} setting is enabled. + * Writes an indent to the writer if the {@code useWhitespace} setting is enabled. * * @param indent The number of tabs to indent. * @throws IOException If a problem occurred trying to write to the writer. * @return This object (for method chaining). */ public SerializerWriter i(int indent) throws IOException { - if (useIndentation) + if (useWhitespace) for (int i = 0; i < indent; i++) out.write('\t'); return this; } /** - * Writes a newline to the writer if the {@code useIndentation} setting is enabled. + * Writes a newline to the writer if the {@code useWhitespace} setting is enabled. * * @throws IOException If a problem occurred trying to write to the writer. * @return This object (for method chaining). */ public SerializerWriter nl() throws IOException { - if (useIndentation) + if (useWhitespace) out.write('\n'); return this; } /** - * Writes a newline to the writer if the {@code useIndentation} setting is enabled and the boolean flag is true. + * Writes a newline to the writer if the {@code useWhitespace} setting is enabled and the boolean flag is true. * * @param b The boolean flag. * @return This object (for method chaining). * @throws IOException If a problem occurred trying to write to the writer. */ public SerializerWriter nlIf(boolean b) throws IOException { - if (b && useIndentation) + if (b && useWhitespace) out.write('\n'); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java index 27aa39c..8a38a88 100644 --- a/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java @@ -99,7 +99,7 @@ public abstract class WriterSerializer extends Serializer { * @return This object (for method chaining). */ public final WriterSerializer println(Object o) { - System.out.println(toString(o)); + System.out.println(toString(o)); // NOT DEBUG return this; } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java index a194286..76c8dc0 100644 --- a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java @@ -32,10 +32,10 @@ public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder { * @param annotations The {@link Bean @Bean} annotations found on the class and all parent classes in child-to-parent order. * @throws Exception Thrown from property namer constructor. */ - public AnnotationBeanFilterBuilder(Class<?> annotatedClass, List<Bean> annotations) throws Exception { + public AnnotationBeanFilterBuilder(Class<?> annotatedClass, Map<Class<?>,Bean> annotations) throws Exception { super(annotatedClass); - ListIterator<Bean> li = annotations.listIterator(annotations.size()); + ListIterator<Bean> li = new ArrayList<Bean>(annotations.values()).listIterator(annotations.size()); while (li.hasPrevious()) { Bean b = li.previous(); @@ -60,19 +60,8 @@ public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder { if (b.stopClass() != Object.class) setStopClass(b.stopClass()); - if (b.subTypes().length > 0) { - setSubTypeProperty(b.subTypeProperty()); - - for (Class<?> bst : b.subTypes()) { - Bean b2 = bst.getAnnotation(Bean.class); - String name = null; - if (! b2.typeName().isEmpty()) - name = b2.typeName(); - else - name = bst.getSimpleName(); - addSubType(name, bst); - } - } + if (b.beanDictionary().length > 0) + addToBeanDictionary(b.beanDictionary()); } } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java index b4fc90e..3817910 100644 --- a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java +++ b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java @@ -12,8 +12,6 @@ // *************************************************************************************************************************** package org.apache.juneau.transform; -import java.util.*; - import org.apache.juneau.*; import org.apache.juneau.annotation.*; import org.apache.juneau.internal.*; @@ -31,12 +29,11 @@ public class BeanFilter { private final Class<?> beanClass; private final String[] properties, excludeProperties; - private final Map<Class<?>, String> subTypes; - private final String subTypeAttr; private final PropertyNamer propertyNamer; private final Class<?> interfaceClass, stopClass; private final boolean sortProperties; private final String typeName; + private final Class<?>[] beanDictionary; /** * Constructor. @@ -50,8 +47,7 @@ public class BeanFilter { this.stopClass = builder.stopClass; this.sortProperties = builder.sortProperties; this.propertyNamer = builder.propertyNamer; - this.subTypeAttr = builder.subTypeProperty; - this.subTypes = builder.subTypes == null ? null : Collections.unmodifiableMap(builder.subTypes); + this.beanDictionary = builder.beanDictionary == null ? null : builder.beanDictionary.toArray(new Class<?>[builder.beanDictionary.size()]); } /** @@ -80,6 +76,15 @@ public class BeanFilter { } /** + * Returns the bean dictionary defined on this bean. + * + * @return The bean dictionary defined on this bean, or <jk>null</jk> if no bean dictionary is defined. + */ + public Class<?>[] getBeanDictionary() { + return beanDictionary; + } + + /** * Returns <jk>true</jk> if the properties defined on this bean class should be ordered alphabetically. * <p> * This method is only used when the {@link #getProperties()} method returns <jk>null</jk>. @@ -110,24 +115,6 @@ public class BeanFilter { } /** - * Returns the name of the sub type property associated with the bean class. - * - * @return The sub type property name, or <jk>null</jk> if bean has no subtypes defined. - */ - public String getSubTypeProperty() { - return subTypeAttr; - } - - /** - * Returns the subtypes associated with the bean class. - * - * @return The set of sub types associated with this bean class, or <jk>null</jk> if bean has no subtypes defined. - */ - public Map<Class<?>, String> getSubTypes() { - return subTypes; - } - - /** * Returns the interface class associated with this class. * * @return The interface class associated with this class, or <jk>null</jk> if no interface class is associated. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java index 6c2928f..b56ce30 100644 --- a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java @@ -51,8 +51,7 @@ public abstract class BeanFilterBuilder { Class<?> interfaceClass, stopClass; boolean sortProperties; PropertyNamer propertyNamer; - String subTypeProperty; - Map<Class<?>,String> subTypes; + List<Class<?>> beanDictionary; /** * Constructor. @@ -205,87 +204,16 @@ public abstract class BeanFilterBuilder { } /** - * Defines a virtual property on a superclass that identifies bean subtype classes. - * <p> - * In the following example, the abstract class has two subclasses that are differentiated - * by a property called <code>subType</code> - * - * <p class='bcode'> - * <jc>// Abstract superclass</jc> - * <jk>public abstract class</jk> A { - * <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>; - * } - * - * <jc>// Subclass 1</jc> - * <jk>public class</jk> A1 <jk>extends</jk> A { - * <jk>public</jk> String <jf>f1</jf>; - * } - * - * <jc>// Subclass 2</jc> - * <jk>public class</jk> A2 <jk>extends</jk> A { - * <jk>public</jk> String <jf>f2</jf>; - * } - * - * <jc>// Filter for defining subtypes</jc> - * <jk>public class</jk> AFilter <jk>extends</jk> BeanFilterBuilder { - * <jk>public</jk> AFilter() { - * super(A.<jk>class</jk>); - * setSubTypeProperty(<js>"subType"</js>); - * addSubType("A1", A1.<jk>class</jk>); - * addSubType("A2", A2.<jk>class</jk>); - * } - * } - * </p> - * <p> - * The following shows what happens when serializing a subclassed object to JSON: - * <p class='bcode'> - * JsonSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(AFilter.<jk>class</jk>); - * A1 a1 = <jk>new</jk> A1(); - * a1.<jf>f1</jf> = <js>"f1"</js>; - * String r = s.serialize(a1); - * <jsm>assertEquals</jsm>(<js>"{subType:'A1',f1:'f1',f0:'f0'}"</js>, r); - * </p> - * <p> - * The following shows what happens when parsing back into the original object. - * <p class='bcode'> - * JsonParser p = <jk>new</jk> JsonParser().addBeanFilters(AFilter.<jk>class</jk>); - * A a = p.parse(r, A.<jk>class</jk>); - * <jsm>assertTrue</jsm>(a <jk>instanceof</jk> A1); - * </p> - * - * @param subTypeProperty The name of the subtype property for this bean. - * Default is <js>"_subtype"</js>. - * @return This object (for method chaining). - */ - public BeanFilterBuilder setSubTypeProperty(String subTypeProperty) { - this.subTypeProperty = subTypeProperty; - return this; - } - - /** - * Specifies the subtype mappings for this bean class. - * See {@link #setSubTypeProperty(String)}. - * - * @param subTypes The mappings of subtype classes to subtype names. - * @return This object (for method chaining). - */ - public BeanFilterBuilder setSubTypes(Map<Class<?>,String> subTypes) { - this.subTypes = subTypes; - return this; - } - - /** - * Adds an entry to the subtype mappings for this bean class. - * See {@link #setSubTypeProperty(String)}. + * Adds a class to this bean's bean dictionary. * - * @param name The subtype name. - * @param c The subtype class. + * @param c The class to add to this bean dictionary. * @return This object (for method chaining). */ - public BeanFilterBuilder addSubType(String name, Class<?> c) { - if (subTypes == null) - subTypes = new LinkedHashMap<Class<?>,String>(); - subTypes.put(c, name); + public BeanFilterBuilder addToBeanDictionary(Class<?>...c) { + if (beanDictionary == null) + beanDictionary = new ArrayList<Class<?>>(Arrays.asList(c)); + else for (Class<?> cc : c) + beanDictionary.add(cc); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/transform/package.html ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/package.html b/juneau-core/src/main/java/org/apache/juneau/transform/package.html index 9a9b2a6..f9722e3 100644 --- a/juneau-core/src/main/java/org/apache/juneau/transform/package.html +++ b/juneau-core/src/main/java/org/apache/juneau/transform/package.html @@ -210,81 +210,6 @@ } </p> - <h6 class='topic'>Define bean subtypes</h6> - <p> - Juneau allows you to losslessly serialize and parse abstract class fields back into the original - concrete objects by defining a subtype attribute and a list of subtypes/ids. - </p> - <p> - For example, let's define the following parent class with two subclasses: - </p> - <p class='bcode'> - <jc>// Abstract parent class</jc> - <jk>public abstract class</jk> MyClass { - <jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>; - } - - <jc>// Subclass 1</jc> - <jk>public class</jk> MyClassBar <jk>extends</jk> MyClass { - <jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>; - } - - <jc>// Subclass 2</jc> - <jk>public class</jk> MyClassBaz <jk>extends</jk> MyClass { - <jk>public</jk> String <jf>baz</jf>=<js>"baz"</js>; - } - </p> - <p> - Normally, when parsing a serialized <code>MyClass</code> object, the parser does not know what subtype to create. - This can be fixed by defining the following bean filter: - </p> - <p class='bcode'> - <jc>// Define bean filter with our own property namer.</jc> - <jk>public class</jk> MyBeanFilter <jk>extends</jk> BeanFilter<MyClass> { - <jk>public</jk> MyBeanFilter() { - setSubTypeProperty(<js>"subType"</js>); - addSubType(MyClassBar.<jk>class</jk>, <js>"BAR"</js>); - addSubType(MyClassBaz.<jk>class</jk>, <js>"BAZ"</js>); - } - } - </p> - <p> - When serialized, the serialized bean will include a <code>"subType"</code> attribute that identifies the subclass, and - allows it to be parsed back into the original subclass. - </p> - <p class='bcode'> - <jc>// Serialize to JSON</jc> - WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(MyBeanFilter.<jk>class</jk>); - MyClass c = <jk>new</jk> MyClassBar(); - String json = s.serialize(p); <jc>// Prints "{subType:'BAR',foo:'foo',bar:'bar'}"</jc> - - <jc>// Parse back into bean</jc> - ReaderParser p = <jk>new</jk> JsonParser().addBeanFilters(MyBeanFilter.<jk>class</jk>); - c = p.parse(json, MyClass.<jk>class</jk>); <jc>// c is an instance of MyClassBar</jc> - </p> - <p> - It should be noted that the sub type attribute is always rendered first in the JSON object so - that the bean object can be instantiated before the real properties are set on it during parsing. - Beans with subtypes are thus 'lazy-instantiated' when the sub type attribute is set. - If the sub type attribute is not listed first, the parser will still be able to parse the input, - but with reduced efficiency since it must cache the incoming data until the bean can be instantiated. - </p> - <p> - Note that this bean filter is equivalent to specifying the following annotation on the bean class: - </p> - <p class='bcode'> - <ja>@Bean</ja>( - subTypeProperty=<js>"subType"</js>, - subTypes={ - <ja>@BeanSubType</ja>(type=MyClassBar.<jk>class</jk>, id=<js>"BAR"</js>), - <ja>@BeanSubType</ja>(type=MyClassBaz.<jk>class</jk>, id=<js>"BAZ"</js>) - } - ) - <jk>public abstract class</jk> MyClass { - ... - } - </p> - <h6 class='topic'>Limiting bean properties to parent bean classes</h6> <p> Occassionally, you may want to limit bean properties to some parent interface.
