This is an automated email from the ASF dual-hosted git repository. jamesbognar pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push: new 08da940 Serializer API cleanup. 08da940 is described below commit 08da9407fde7952955867f5288663371a81647af Author: JamesBognar <jamesbog...@apache.org> AuthorDate: Sun Jul 8 19:06:31 2018 -0400 Serializer API cleanup. --- .../java/org/apache/juneau/xml/XmlContentTest.java | 18 +- .../apache/juneau/jena/RdfSerializerSession.java | 4 +- .../apache/juneau/html/HtmlSerializerSession.java | 2 +- .../juneau/httppart/OpenApiPartSerializer.java | 2 +- .../apache/juneau/json/JsonSerializerSession.java | 2 +- .../juneau/msgpack/MsgPackSerializerSession.java | 2 +- .../org/apache/juneau/serializer/Serializer.java | 248 +++++++++----- .../juneau/serializer/SerializerSession.java | 359 +++++++++++---------- .../apache/juneau/uon/UonSerializerSession.java | 2 +- .../urlencoding/UrlEncodingSerializerSession.java | 2 +- .../apache/juneau/xml/XmlSerializerSession.java | 6 +- .../juneau/yaml/proto/YamlSerializerSession.java | 2 +- 12 files changed, 375 insertions(+), 274 deletions(-) diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java index a6b44ad..f3085d6 100755 --- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java @@ -12,14 +12,12 @@ // *************************************************************************************************************************** package org.apache.juneau.xml; -import static org.apache.juneau.serializer.Serializer.*; import static org.apache.juneau.testutils.TestUtils.*; import static org.apache.juneau.xml.annotation.XmlFormat.*; import static org.junit.Assert.*; import java.io.*; -import org.apache.juneau.*; import org.apache.juneau.annotation.*; import org.apache.juneau.serializer.*; import org.apache.juneau.xml.annotation.*; @@ -33,8 +31,8 @@ public class XmlContentTest { @Test public void testContentFormat() throws Exception { A t = A.newInstance(), t2; - XmlSerializer s1 = XmlSerializer.DEFAULT_SQ, - s2 = XmlSerializer.create().sq().ws().enableNamespaces(false).build(); + XmlSerializer s1 = XmlSerializer.DEFAULT_SQ.builder().trimNullProperties(false).build(), + s2 = XmlSerializer.create().sq().ws().enableNamespaces(false).trimNullProperties(false).build(); XmlParser p = XmlParser.DEFAULT; WriterSerializerSession session; String r; @@ -46,7 +44,7 @@ public class XmlContentTest { t.f2 = null; sw = new StringWriter(); - session = s1.createSession(new SerializerSessionArgs(new ObjectMap("{"+SERIALIZER_trimNullProperties+":false}"), null, null, null, null, null)); + session = s1.createSession(new SerializerSessionArgs(null, null, null, null, null, null)); session.serialize(t, sw); r = sw.toString(); assertEquals("<A f1='f1'>_x0000_</A>", r); @@ -54,7 +52,7 @@ public class XmlContentTest { assertEqualObjects(t, t2); sw = new StringWriter(); - session = s2.createSession(new SerializerSessionArgs(new ObjectMap("{"+SERIALIZER_trimNullProperties+":false}"), null, null, null, null, null)); + session = s2.createSession(new SerializerSessionArgs(null, null, null, null, null, null)); session.serialize(t, sw); r = sw.toString(); assertEquals("<A f1='f1'>_x0000_</A>\n", r); @@ -141,8 +139,8 @@ public class XmlContentTest { @Test public void testXmlMixed() throws Exception { B t = B.newInstance(), t2; - XmlSerializer s1 = XmlSerializer.DEFAULT_SQ, - s2 = XmlSerializer.create().sq().ws().enableNamespaces(false).build(); + XmlSerializer s1 = XmlSerializer.DEFAULT_SQ.builder().trimNullProperties(false).build(), + s2 = XmlSerializer.create().sq().ws().enableNamespaces(false).trimNullProperties(false).build(); XmlParser p = XmlParser.DEFAULT; WriterSerializerSession session; String r; @@ -154,7 +152,7 @@ public class XmlContentTest { t.f2 = null; sw = new StringWriter(); - session = s1.createSession(new SerializerSessionArgs(new ObjectMap("{"+SERIALIZER_trimNullProperties+":false}"), null, null, null, null, null)); + session = s1.createSession(new SerializerSessionArgs(null, null, null, null, null, null)); session.serialize(t, sw); r = sw.toString(); assertEquals("<A f1='f1'>_x0000_</A>", r); @@ -162,7 +160,7 @@ public class XmlContentTest { assertEqualObjects(t, t2); sw = new StringWriter(); - session = s2.createSession(new SerializerSessionArgs(new ObjectMap("{"+SERIALIZER_trimNullProperties+":false}"), null, null, null, null, null)); + session = s2.createSession(new SerializerSessionArgs(null, null, null, null, null, null)); session.serialize(t, sw); r = sw.toString(); assertEquals("<A f1='f1'>_x0000_</A>\n", r); diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java index a467264..1e56039 100644 --- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java +++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java @@ -233,7 +233,7 @@ public final class RdfSerializerSession extends WriterSerializerSession { if (o == null || sType.isChar() && ((Character)o).charValue() == 0) { if (bpm != null) { - if (! isTrimNulls()) { + if (! isTrimNullProperties()) { n = m.createResource(RDF_NIL); } } else { @@ -347,7 +347,7 @@ public final class RdfSerializerSession extends WriterSerializerSession { } private void serializeBeanMap(BeanMap<?> m, Resource r, String typeName) throws Exception { - List<BeanPropertyValue> l = m.getValues(isTrimNulls(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null); + List<BeanPropertyValue> l = m.getValues(isTrimNullProperties(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null); Collections.reverse(l); for (BeanPropertyValue bpv : l) { diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java index 5c2da02..9ab93d9 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java @@ -496,7 +496,7 @@ public class HtmlSerializerSession extends XmlSerializerSession { out.ie(i+1).eTag("tr").nl(i+1); } - for (BeanPropertyValue p : m.getValues(isTrimNulls())) { + for (BeanPropertyValue p : m.getValues(isTrimNullProperties())) { BeanPropertyMeta pMeta = p.getMeta(); ClassMeta<?> cMeta = p.getClassMeta(); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java index f7a8993..718ed11 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java @@ -268,7 +268,7 @@ public class OpenApiPartSerializer extends UonPartSerializer { s = DEFAULT_SCHEMA; ObjectMap m = new ObjectMap(); if (type.isBean()) { - for (BeanPropertyValue p : bs.toBeanMap(o).getValues(isTrimNulls())) { + for (BeanPropertyValue p : bs.toBeanMap(o).getValues(isTrimNullProperties())) { if (p.getMeta().canRead()) { Throwable t = p.getThrown(); if (t == null) diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java index c86d276..8f675c5 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java @@ -213,7 +213,7 @@ public class JsonSerializerSession extends WriterSerializerSession { out.append('{'); boolean addComma = false; - for (BeanPropertyValue p : m.getValues(isTrimNulls(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null)) { + for (BeanPropertyValue p : m.getValues(isTrimNullProperties(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null)) { BeanPropertyMeta pMeta = p.getMeta(); if (pMeta.canRead()) { ClassMeta<?> cMeta = p.getClassMeta(); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java index c8b022b..7196421 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java @@ -185,7 +185,7 @@ public final class MsgPackSerializerSession extends OutputStreamSerializerSessio private void serializeBeanMap(MsgPackOutputStream out, final BeanMap<?> m, String typeName) throws Exception { - List<BeanPropertyValue> values = m.getValues(isTrimNulls(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null); + List<BeanPropertyValue> values = m.getValues(isTrimNullProperties(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null); int size = values.size(); for (BeanPropertyValue p : values) diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java index 34a4d7c..9396588 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java @@ -843,22 +843,22 @@ public abstract class Serializer extends BeanContext { // Instance //------------------------------------------------------------------------------------------------------------------- - final int initialDepth, maxDepth; - final boolean + private final int initialDepth, maxDepth; + private final boolean detectRecursions, ignoreRecursions, addBeanTypes, - trimNulls, + trimNullProperties, trimEmptyCollections, trimEmptyMaps, trimStrings, sortCollections, sortMaps, addRootType; - final UriContext uriContext; - final UriResolution uriResolution; - final UriRelativity uriRelativity; - final Class<? extends SerializerListener> listener; + private final UriContext uriContext; + private final UriResolution uriResolution; + private final UriRelativity uriRelativity; + private final Class<? extends SerializerListener> listener; private final MediaTypeRange[] accept; private final MediaType[] accepts; @@ -899,7 +899,7 @@ public abstract class Serializer extends BeanContext { detectRecursions = getBooleanProperty(SERIALIZER_detectRecursions, false); ignoreRecursions = getBooleanProperty(SERIALIZER_ignoreRecursions, false); addBeanTypes = getBooleanProperty(SERIALIZER_addBeanTypes, false); - trimNulls = getBooleanProperty(SERIALIZER_trimNullProperties, true); + trimNullProperties = getBooleanProperty(SERIALIZER_trimNullProperties, true); trimEmptyCollections = getBooleanProperty(SERIALIZER_trimEmptyCollections, false); trimEmptyMaps = getBooleanProperty(SERIALIZER_trimEmptyMaps, false); trimStrings = getBooleanProperty(SERIALIZER_trimStrings, false); @@ -1025,167 +1025,241 @@ public abstract class Serializer extends BeanContext { //-------------------------------------------------------------------------------- /** - * Returns the {@link Serializer#SERIALIZER_maxDepth} setting value for this session. + * Returns the media types handled based on the value of the <code>accept</code> parameter passed into the constructor. * - * @return The {@link Serializer#SERIALIZER_maxDepth} setting value for this session. + * <p> + * Note that the order of these ranges are from high to low q-value. + * + * @return The list of media types. Never <jk>null</jk>. */ - public final int getMaxDepth() { - return maxDepth; + public final MediaTypeRange[] getMediaTypeRanges() { + return accept; } /** - * Returns the {@link Serializer#SERIALIZER_initialDepth} setting value for this session. + * Returns the first entry in the <code>accept</code> parameter passed into the constructor. * - * @return The {@link Serializer#SERIALIZER_initialDepth} setting value for this session. + * <p> + * This signifies the 'primary' media type for this serializer. + * + * @return The media type. Never <jk>null</jk>. */ - public final int getInitialDepth() { - return initialDepth; + public final MediaType getPrimaryMediaType() { + return accepts[0]; } /** - * Returns the {@link Serializer#SERIALIZER_detectRecursions} setting value for this session. + * Returns the media types handled based on the value of the <code>accept</code> parameter passed into the constructor. * - * @return The {@link Serializer#SERIALIZER_detectRecursions} setting value for this session. + * <p> + * The order of the media types are the same as those in the <code>accept</code> parameter. + * + * @return The list of media types. Never <jk>null</jk>. */ - public final boolean isDetectRecursions() { - return detectRecursions; + public final MediaType[] getAcceptMediaTypes() { + return accepts; } /** - * Returns the {@link Serializer#SERIALIZER_ignoreRecursions} setting value for this session. + * Optional method that returns the response <code>Content-Type</code> for this serializer if it is different from + * the matched media type. * - * @return The {@link Serializer#SERIALIZER_ignoreRecursions} setting value for this session. + * <p> + * This method is specified to override the content type for this serializer. + * For example, the {@link org.apache.juneau.json.JsonSerializer.Simple} class returns that it handles media type + * <js>"text/json+simple"</js>, but returns <js>"text/json"</js> as the actual content type. + * This allows clients to request specific 'flavors' of content using specialized <code>Accept</code> header values. + * + * <p> + * This method is typically meaningless if the serializer is being used stand-alone (i.e. outside of a REST server + * or client). + * + * @return The response content type. If <jk>null</jk>, then the matched media type is used. */ - public final boolean isIgnoreRecursions() { - return ignoreRecursions; + public final MediaType getResponseContentType() { + return produces; } + //----------------------------------------------------------------------------------------------------------------- + // Properties + //----------------------------------------------------------------------------------------------------------------- + /** - * Returns the {@link Serializer#SERIALIZER_addBeanTypes} setting value for this session. + * Configuration property: Initial depth. * - * @return The {@link Serializer#SERIALIZER_addBeanTypes} setting value for this session. + * @see #SERIALIZER_initialDepth + * @return + * The initial indentation level at the root. */ - public boolean isAddBeanTypes() { - return addBeanTypes; + protected final int getInitialDepth() { + return initialDepth; } /** - * Returns the {@link Serializer#SERIALIZER_addRootType} setting value for this session. + * Configuration property: Max serialization depth. * - * @return The {@link Serializer#SERIALIZER_addRootType} setting value for this session. + * @see #SERIALIZER_maxDepth + * @return + * The depth at which serialization is aborted if depth is reached in the POJO tree. + * <br>If this depth is exceeded, an exception is thrown. */ - public boolean isAddRootType() { - return addRootType; + protected final int getMaxDepth() { + return maxDepth; + } + + /** + * Configuration property: Automatically detect POJO recursions. + * @see #SERIALIZER_detectRecursions + * @return + * <jk>true</jk> if recursions should be checked for during serialization. + */ + protected final boolean isDetectRecursions() { + return detectRecursions; + } + + /** + * Configuration property: Ignore recursion errors. + * + * @see #SERIALIZER_ignoreRecursions + * @return + * <jk>true</jk> if when we encounter the same object when serializing a tree, we set the value to <jk>null</jk>. + * <br>Otherwise, a {@link SerializeException} is thrown with the message <js>"Recursion occurred, stack=..."</js>. + */ + protected final boolean isIgnoreRecursions() { + return ignoreRecursions; + } + + /** + * Configuration property: Add <js>"_type"</js> properties when needed. + * + * @see #SERIALIZER_addBeanTypes + * @return + * <jk>true</jk> if <js>"_type"</js> properties added to beans if their type cannot be inferred + * through reflection. + */ + protected final boolean isAddBeanTypes() { + return addBeanTypes; } /** - * Returns the {@link Serializer#SERIALIZER_trimNullProperties} setting value for this session. + * Configuration property: Trim null bean property values. * - * @return The {@link Serializer#SERIALIZER_trimNullProperties} setting value for this session. + * @see #SERIALIZER_trimNullProperties + * @return + * <jk>true</jk> if null bean values are not serialized to the output. */ - public final boolean isTrimNulls() { - return trimNulls; + protected final boolean isTrimNullProperties() { + return trimNullProperties; } /** - * Returns the {@link Serializer#SERIALIZER_trimEmptyCollections} setting value for this session. + * Configuration property: Trim empty lists and arrays. * - * @return The {@link Serializer#SERIALIZER_trimEmptyCollections} setting value for this session. + * @see #SERIALIZER_trimEmptyCollections + * @return + * <jk>true</jk> if empty lists and arrays are not serialized to the output. */ - public final boolean isTrimEmptyCollections() { + protected final boolean isTrimEmptyCollections() { return trimEmptyCollections; } /** - * Returns the {@link Serializer#SERIALIZER_trimEmptyMaps} setting value for this session. + * Configuration property: Trim empty maps. * - * @return The {@link Serializer#SERIALIZER_trimEmptyMaps} setting value for this session. + * @see #SERIALIZER_trimEmptyMaps + * @return + * <jk>true</jk> if empty map values are not serialized to the output. */ - public final boolean isTrimEmptyMaps() { + protected final boolean isTrimEmptyMaps() { return trimEmptyMaps; } /** - * Returns the {@link Serializer#SERIALIZER_trimStrings} setting value for this session. + * Configuration property: Trim strings. * - * @return The {@link Serializer#SERIALIZER_trimStrings} setting value for this session. + * @see #SERIALIZER_trimStrings + * @return + * <jk>true</jk> if string values will be trimmed of whitespace using {@link String#trim()} before being serialized. */ - public boolean isTrimStrings() { + protected final boolean isTrimStrings() { return trimStrings; } /** - * Returns the {@link Serializer#SERIALIZER_sortCollections} setting value for this session. + * Configuration property: Sort arrays and collections alphabetically. * - * @return The {@link Serializer#SERIALIZER_sortCollections} setting value for this session. + * @see #SERIALIZER_sortCollections + * @return + * <jk>true</jk> if arrays and collections are copied and sorted before serialization. */ - public final boolean isSortCollections() { + protected final boolean isSortCollections() { return sortCollections; } /** - * Returns the {@link Serializer#SERIALIZER_sortMaps} setting value for this session. + * Configuration property: Sort maps alphabetically. * - * @return The {@link Serializer#SERIALIZER_sortMaps} setting value for this session. + * @see #SERIALIZER_sortMaps + * @return + * <jk>true</jk> if maps are copied and sorted before serialization. */ - public final boolean isSortMaps() { + protected final boolean isSortMaps() { return sortMaps; } /** - * Returns the media types handled based on the value of the <code>accept</code> parameter passed into the constructor. - * - * <p> - * Note that the order of these ranges are from high to low q-value. + * Configuration property: Add type attribute to root nodes. * - * @return The list of media types. Never <jk>null</jk>. + * @see #SERIALIZER_addRootType + * @return + * <jk>true</jk> if type property should be added to root node. */ - public final MediaTypeRange[] getMediaTypeRanges() { - return accept; + protected final boolean isAddRootType() { + return addRootType; } /** - * Returns the first entry in the <code>accept</code> parameter passed into the constructor. - * - * <p> - * This signifies the 'primary' media type for this serializer. + * Configuration property: URI context bean. * - * @return The media type. Never <jk>null</jk>. + * @see #SERIALIZER_uriContext + * @return + * Bean used for resolution of URIs to absolute or root-relative form. */ - public final MediaType getPrimaryMediaType() { - return accepts[0]; + protected final UriContext getUriContext() { + return uriContext; } /** - * Returns the media types handled based on the value of the <code>accept</code> parameter passed into the constructor. - * - * <p> - * The order of the media types are the same as those in the <code>accept</code> parameter. + * Configuration property: URI resolution. * - * @return The list of media types. Never <jk>null</jk>. + * @see #SERIALIZER_uriResolution + * @return + * Defines the resolution level for URIs when serializing URIs. */ - public final MediaType[] getAcceptMediaTypes() { - return accepts; + protected final UriResolution getUriResolution() { + return uriResolution; } /** - * Optional method that returns the response <code>Content-Type</code> for this serializer if it is different from - * the matched media type. - * - * <p> - * This method is specified to override the content type for this serializer. - * For example, the {@link org.apache.juneau.json.JsonSerializer.Simple} class returns that it handles media type - * <js>"text/json+simple"</js>, but returns <js>"text/json"</js> as the actual content type. - * This allows clients to request specific 'flavors' of content using specialized <code>Accept</code> header values. + * Configuration property: URI relativity. * - * <p> - * This method is typically meaningless if the serializer is being used stand-alone (i.e. outside of a REST server - * or client). + * @see #SERIALIZER_uriRelativity + * @return + * Defines what relative URIs are relative to when serializing any of the following: + */ + protected final UriRelativity getUriRelativity() { + return uriRelativity; + } + + /** + * Configuration property: Serializer listener. * - * @return The response content type. If <jk>null</jk>, then the matched media type is used. + * @see #SERIALIZER_listener + * @return + * Class used to listen for errors and warnings that occur during serialization. */ - public final MediaType getResponseContentType() { - return produces; + protected final Class<? extends SerializerListener> getListener() { + return listener; } @Override /* Context */ @@ -1197,7 +1271,7 @@ public abstract class Serializer extends BeanContext { .append("detectRecursions", detectRecursions) .append("ignoreRecursions", ignoreRecursions) .append("addBeanTypes", addBeanTypes) - .append("trimNulls", trimNulls) + .append("trimNullProperties", trimNullProperties) .append("trimEmptyCollections", trimEmptyCollections) .append("trimEmptyMaps", trimEmptyMaps) .append("trimStrings", trimStrings) diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java index 510cea1..76ea460 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java @@ -49,18 +49,7 @@ import org.apache.juneau.transform.*; */ public abstract class SerializerSession extends BeanSession { - private final int maxDepth, initialDepth; - private final boolean - detectRecursions, - ignoreRecursions, - addBeanTypes, - trimNulls, - trimEmptyCollections, - trimEmptyMaps, - trimStrings, - sortCollections, - sortMaps, - addRootType; + private final Serializer ctx; private final UriResolver uriResolver; private final Map<Object,Object> set; // Contains the current objects in the current branch of the model. @@ -92,33 +81,22 @@ public abstract class SerializerSession extends BeanSession { */ protected SerializerSession(Serializer ctx, SerializerSessionArgs args) { super(ctx, args); + this.ctx = ctx; this.javaMethod = args.javaMethod; UriResolution uriResolution; UriRelativity uriRelativity; Class<?> listenerClass; - maxDepth = getProperty(SERIALIZER_maxDepth, int.class, ctx.maxDepth); - initialDepth = getProperty(SERIALIZER_initialDepth, int.class, ctx.initialDepth); - detectRecursions = getProperty(SERIALIZER_detectRecursions, boolean.class, ctx.detectRecursions); - ignoreRecursions = getProperty(SERIALIZER_ignoreRecursions, boolean.class, ctx.ignoreRecursions); - addBeanTypes = getProperty(SERIALIZER_addBeanTypes, boolean.class, ctx.addBeanTypes); - trimNulls = getProperty(SERIALIZER_trimNullProperties, boolean.class, ctx.trimNulls); - trimEmptyCollections = getProperty(SERIALIZER_trimEmptyCollections, boolean.class, ctx.trimEmptyCollections); - trimEmptyMaps = getProperty(SERIALIZER_trimEmptyMaps, boolean.class, ctx.trimEmptyMaps); - trimStrings = getProperty(SERIALIZER_trimStrings, boolean.class, ctx.trimStrings); - sortCollections = getProperty(SERIALIZER_sortCollections, boolean.class, ctx.sortMaps); - sortMaps = getProperty(SERIALIZER_sortMaps, boolean.class, ctx.sortMaps); - addRootType = getProperty(SERIALIZER_addRootType, boolean.class, ctx.addRootType); - uriResolution = getInstanceProperty(SERIALIZER_uriResolution, UriResolution.class, ctx.uriResolution); - uriRelativity = getInstanceProperty(SERIALIZER_uriRelativity, UriRelativity.class, ctx.uriRelativity); - listenerClass = getProperty(SERIALIZER_listener, Class.class, ctx.listener); - - uriResolver = new UriResolver(uriResolution, uriRelativity, args.uriContext == null ? ctx.uriContext : args.uriContext); + uriResolution = getInstanceProperty(SERIALIZER_uriResolution, UriResolution.class, ctx.getUriResolution()); + uriRelativity = getInstanceProperty(SERIALIZER_uriRelativity, UriRelativity.class, ctx.getUriRelativity()); + listenerClass = getProperty(SERIALIZER_listener, Class.class, ctx.getListener()); + + uriResolver = new UriResolver(uriResolution, uriRelativity, args.uriContext == null ? ctx.getUriContext() : args.uriContext); listener = newInstance(SerializerListener.class, listenerClass); - this.indent = initialDepth; - if (detectRecursions || isDebug()) { + this.indent = getInitialDepth(); + if (isDetectRecursions() || isDebug()) { set = new IdentityHashMap<>(); } else { set = Collections.emptyMap(); @@ -142,18 +120,6 @@ public abstract class SerializerSession extends BeanSession { public ObjectMap asMap() { return super.asMap() .append("SerializerSession", new ObjectMap() - .append("maxDepth", maxDepth) - .append("initialDepth", initialDepth) - .append("detectRecursions", detectRecursions) - .append("ignoreRecursions", ignoreRecursions) - .append("addBeanTypes", addBeanTypes) - .append("trimNulls", trimNulls) - .append("trimEmptyCollections", trimEmptyCollections) - .append("trimEmptyMaps", trimEmptyMaps) - .append("trimStrings", trimStrings) - .append("sortCollections", sortCollections) - .append("sortMaps", sortMaps) - .append("addRootType", addRootType) .append("uriResolver", uriResolver) ); } @@ -300,114 +266,6 @@ public abstract class SerializerSession extends BeanSession { } /** - * Returns the {@link Serializer#SERIALIZER_maxDepth} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_maxDepth} setting value for this session. - */ - protected final int getMaxDepth() { - return maxDepth; - } - - /** - * Returns the {@link Serializer#SERIALIZER_initialDepth} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_initialDepth} setting value for this session. - */ - protected final int getInitialDepth() { - return initialDepth; - } - - /** - * Returns the {@link Serializer#SERIALIZER_detectRecursions} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_detectRecursions} setting value for this session. - */ - protected final boolean isDetectRecursions() { - return detectRecursions; - } - - /** - * Returns the {@link Serializer#SERIALIZER_ignoreRecursions} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_ignoreRecursions} setting value for this session. - */ - protected final boolean isIgnoreRecursions() { - return ignoreRecursions; - } - - /** - * Returns the {@link Serializer#SERIALIZER_addBeanTypes} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_addBeanTypes} setting value for this session. - */ - protected boolean isAddBeanTypes() { - return addBeanTypes; - } - - /** - * Returns the {@link Serializer#SERIALIZER_addRootType} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_addRootType} setting value for this session. - */ - protected boolean isAddRootType() { - return addRootType; - } - - /** - * Returns the {@link Serializer#SERIALIZER_trimNullProperties} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_trimNullProperties} setting value for this session. - */ - protected final boolean isTrimNulls() { - return trimNulls; - } - - /** - * Returns the {@link Serializer#SERIALIZER_trimEmptyCollections} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_trimEmptyCollections} setting value for this session. - */ - protected final boolean isTrimEmptyCollections() { - return trimEmptyCollections; - } - - /** - * Returns the {@link Serializer#SERIALIZER_trimEmptyMaps} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_trimEmptyMaps} setting value for this session. - */ - protected final boolean isTrimEmptyMaps() { - return trimEmptyMaps; - } - - /** - * Returns the {@link Serializer#SERIALIZER_trimStrings} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_trimStrings} setting value for this session. - */ - protected boolean isTrimStrings() { - return trimStrings; - } - - /** - * Returns the {@link Serializer#SERIALIZER_sortCollections} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_sortCollections} setting value for this session. - */ - protected final boolean isSortCollections() { - return sortCollections; - } - - /** - * Returns the {@link Serializer#SERIALIZER_sortMaps} setting value for this session. - * - * @return The {@link Serializer#SERIALIZER_sortMaps} setting value for this session. - */ - protected final boolean isSortMaps() { - return sortMaps; - } - - /** * Push the specified object onto the stack. * * @param attrName The attribute name. @@ -427,8 +285,8 @@ public abstract class SerializerSession extends BeanSession { ClassMeta<?> cm = (eType != null && c == eType.getInnerClass()) ? eType : getClassMeta(c); if (cm.isCharSequence() || cm.isNumber() || cm.isBoolean()) return cm; - if (detectRecursions || isDebug()) { - if (stack.size() > maxDepth) + if (isDetectRecursions() || isDebug()) { + if (stack.size() > getMaxDepth()) return null; if (willRecurse(attrName, o, cm)) return null; @@ -452,11 +310,11 @@ public abstract class SerializerSession extends BeanSession { * @throws SerializeException If recursion occurred. */ protected final boolean willRecurse(String attrName, Object o, ClassMeta<?> cm) throws SerializeException { - if (! (detectRecursions || isDebug())) + if (! (isDetectRecursions() || isDebug())) return false; if (! set.containsKey(o)) return false; - if (ignoreRecursions && ! isDebug()) + if (isIgnoreRecursions() && ! isDebug()) return true; stack.add(new StackElement(stack.size(), attrName, o, cm)); @@ -468,7 +326,7 @@ public abstract class SerializerSession extends BeanSession { */ protected final void pop() { indent--; - if ((detectRecursions || isDebug()) && ! isBottom) { + if ((isDetectRecursions() || isDebug()) && ! isBottom) { Object o = stack.removeLast().o; Object o2 = set.remove(o); if (o2 == null) @@ -515,7 +373,7 @@ public abstract class SerializerSession extends BeanSession { if (o == null) return null; String s = o.toString(); - if (trimStrings) + if (isTrimStrings()) s = s.trim(); return s; } @@ -555,7 +413,7 @@ public abstract class SerializerSession extends BeanSession { */ protected final boolean canIgnoreValue(ClassMeta<?> cm, String attrName, Object value) throws SerializeException { - if (trimNulls && value == null) + if (isTrimNullProperties() && value == null) return true; if (value == null) @@ -564,7 +422,7 @@ public abstract class SerializerSession extends BeanSession { if (cm == null) cm = object(); - if (trimEmptyCollections) { + if (isTrimEmptyCollections()) { if (cm.isArray() || (cm.isObject() && value.getClass().isArray())) { if (((Object[])value).length == 0) return true; @@ -575,14 +433,14 @@ public abstract class SerializerSession extends BeanSession { } } - if (trimEmptyMaps) { + if (isTrimEmptyMaps()) { if (cm.isMap() || (cm.isObject() && isParentClass(Map.class, value.getClass()))) { if (((Map<?,?>)value).isEmpty()) return true; } } - if (trimNulls && willRecurse(attrName, value, cm)) + if (isTrimNullProperties() && willRecurse(attrName, value, cm)) return true; return false; @@ -595,7 +453,7 @@ public abstract class SerializerSession extends BeanSession { * @return A new sorted {@link TreeMap}. */ protected final <K,V> Map<K,V> sort(Map<K,V> m) { - if (sortMaps && m != null && (! m.isEmpty()) && m.keySet().iterator().next() instanceof Comparable<?>) + if (isSortMaps() && m != null && (! m.isEmpty()) && m.keySet().iterator().next() instanceof Comparable<?>) return new TreeMap<>(m); return m; } @@ -607,7 +465,7 @@ public abstract class SerializerSession extends BeanSession { * @return A new sorted {@link TreeSet}. */ protected final <E> Collection<E> sort(Collection<E> c) { - if (sortCollections && c != null && (! c.isEmpty()) && c.iterator().next() instanceof Comparable<?>) + if (isSortCollections() && c != null && (! c.isEmpty()) && c.iterator().next() instanceof Comparable<?>) return new TreeSet<>(c); return c; } @@ -729,7 +587,7 @@ public abstract class SerializerSession extends BeanSession { if (o.getClass().isEnum()) return getClassMetaForObject(o).toString(o); String s = o.toString(); - if (trimStrings) + if (isTrimStrings()) s = s.trim(); return s; } @@ -865,7 +723,7 @@ public abstract class SerializerSession extends BeanSession { * @return The expected type. */ protected final ClassMeta<?> getExpectedRootType(Object o) { - return addRootType ? object() : getClassMetaForObject(o); + return isAddRootType() ? object() : getClassMetaForObject(o); } /** @@ -906,4 +764,175 @@ public abstract class SerializerSession extends BeanSession { public <T extends SerializerListener> T getListener(Class<T> c) { return (T)listener; } + + //----------------------------------------------------------------------------------------------------------------- + // Properties + //----------------------------------------------------------------------------------------------------------------- + + /** + * Configuration property: Initial depth. + * + * @see #SERIALIZER_initialDepth + * @return + * The initial indentation level at the root. + */ + protected final int getInitialDepth() { + return ctx.getInitialDepth(); + } + + /** + * Configuration property: Max serialization depth. + * + * @see #SERIALIZER_maxDepth + * @return + * The depth at which serialization is aborted if depth is reached in the POJO tree. + * <br>If this depth is exceeded, an exception is thrown. + */ + protected final int getMaxDepth() { + return ctx.getMaxDepth(); + } + + /** + * Configuration property: Automatically detect POJO recursions. + * @see #SERIALIZER_detectRecursions + * @return + * <jk>true</jk> if recursions should be checked for during serialization. + */ + protected final boolean isDetectRecursions() { + return ctx.isDetectRecursions(); + } + + /** + * Configuration property: Ignore recursion errors. + * + * @see #SERIALIZER_ignoreRecursions + * @return + * <jk>true</jk> if when we encounter the same object when serializing a tree, we set the value to <jk>null</jk>. + * <br>Otherwise, a {@link SerializeException} is thrown with the message <js>"Recursion occurred, stack=..."</js>. + */ + protected final boolean isIgnoreRecursions() { + return ctx.isIgnoreRecursions(); + } + + /** + * Configuration property: Add <js>"_type"</js> properties when needed. + * + * @see #SERIALIZER_addBeanTypes + * @return + * <jk>true</jk> if <js>"_type"</js> properties added to beans if their type cannot be inferred + * through reflection. + */ + protected boolean isAddBeanTypes() { + return ctx.isAddBeanTypes(); + } + + /** + * Configuration property: Trim null bean property values. + * + * @see #SERIALIZER_trimNullProperties + * @return + * <jk>true</jk> if null bean values are not serialized to the output. + */ + protected final boolean isTrimNullProperties() { + return ctx.isTrimNullProperties(); + } + + /** + * Configuration property: Trim empty lists and arrays. + * + * @see #SERIALIZER_trimEmptyCollections + * @return + * <jk>true</jk> if empty lists and arrays are not serialized to the output. + */ + protected final boolean isTrimEmptyCollections() { + return ctx.isTrimEmptyCollections(); + } + + /** + * Configuration property: Trim empty maps. + * + * @see #SERIALIZER_trimEmptyMaps + * @return + * <jk>true</jk> if empty map values are not serialized to the output. + */ + protected final boolean isTrimEmptyMaps() { + return ctx.isTrimEmptyMaps(); + } + + /** + * Configuration property: Trim strings. + * + * @see #SERIALIZER_trimStrings + * @return + * <jk>true</jk> if string values will be trimmed of whitespace using {@link String#trim()} before being serialized. + */ + protected boolean isTrimStrings() { + return ctx.isTrimStrings(); + } + + /** + * Configuration property: Sort arrays and collections alphabetically. + * + * @see #SERIALIZER_sortCollections + * @return + * <jk>true</jk> if arrays and collections are copied and sorted before serialization. + */ + protected final boolean isSortCollections() { + return ctx.isSortCollections(); + } + + /** + * Configuration property: Sort maps alphabetically. + * + * @see #SERIALIZER_sortMaps + * @return + * <jk>true</jk> if maps are copied and sorted before serialization. + */ + protected final boolean isSortMaps() { + return ctx.isSortMaps(); + } + + /** + * Configuration property: Add type attribute to root nodes. + * + * @see #SERIALIZER_addRootType + * @return + * <jk>true</jk> if type property should be added to root node. + */ + protected final boolean isAddRootType() { + return ctx.isAddRootType(); + } + + /** + * Configuration property: URI context bean. + * + * @see #SERIALIZER_uriContext + * @return + * Bean used for resolution of URIs to absolute or root-relative form. + */ + protected final UriContext getUriContext() { + return getUriContext(); + } + + /** + * Configuration property: URI resolution. + * + * @see #SERIALIZER_uriResolution + * @return + * Defines the resolution level for URIs when serializing URIs. + */ + protected final UriResolution getUriResolution() { + return ctx.getUriResolution(); + } + + /** + * Configuration property: URI relativity. + * + * @see #SERIALIZER_uriRelativity + * @return + * Defines what relative URIs are relative to when serializing any of the following: + */ + protected final UriRelativity getUriRelativity() { + return ctx.getUriRelativity(); + } } diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java index 8341181..30c191a 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java @@ -219,7 +219,7 @@ public class UonSerializerSession extends WriterSerializerSession { boolean addComma = false; - for (BeanPropertyValue p : m.getValues(isTrimNulls(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null)) { + for (BeanPropertyValue p : m.getValues(isTrimNullProperties(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null)) { BeanPropertyMeta pMeta = p.getMeta(); if (pMeta.canRead()) { ClassMeta<?> cMeta = p.getClassMeta(); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java index 40757ce..98e8427 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java @@ -221,7 +221,7 @@ public class UrlEncodingSerializerSession extends UonSerializerSession { private SerializerWriter serializeBeanMap(UonWriter out, BeanMap<?> m, String typeName) throws Exception { boolean addAmp = false; - for (BeanPropertyValue p : m.getValues(isTrimNulls(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null)) { + for (BeanPropertyValue p : m.getValues(isTrimNullProperties(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null)) { BeanPropertyMeta pMeta = p.getMeta(); if (pMeta.canRead()) { ClassMeta<?> cMeta = p.getClassMeta(); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java index b5934b5..ea105eb 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java @@ -236,7 +236,7 @@ public class XmlSerializerSession extends WriterSerializerSession { findNsfMappings(o2); } if (bm != null) { - for (BeanPropertyValue p : bm.getValues(isTrimNulls())) { + for (BeanPropertyValue p : bm.getValues(isTrimNullProperties())) { Namespace ns = bpXml(p.getMeta()).getNamespace(); if (ns != null && ns.uri != null) @@ -544,7 +544,7 @@ public class XmlSerializerSession extends WriterSerializerSession { boolean hasChildren = false; BeanMeta<?> bm = m.getMeta(); - List<BeanPropertyValue> lp = m.getValues(isTrimNulls()); + List<BeanPropertyValue> lp = m.getValues(isTrimNullProperties()); XmlBeanMeta xbm = bXml(bm); @@ -672,7 +672,7 @@ public class XmlSerializerSession extends WriterSerializerSession { serializeAnything(out, content, contentType, null, null, false, cf, isMixed, preserveWhitespace, null); } } else { - if (! isTrimNulls()) { + if (! isTrimNullProperties()) { if (! isMixed) out.i(indent); out.text(content); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlSerializerSession.java index 804ff87..ea29023 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlSerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlSerializerSession.java @@ -172,7 +172,7 @@ public class YamlSerializerSession extends WriterSerializerSession { out.append('{'); boolean addComma = false; - for (BeanPropertyValue p : m.getValues(isTrimNulls(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null)) { + for (BeanPropertyValue p : m.getValues(isTrimNullProperties(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null)) { BeanPropertyMeta pMeta = p.getMeta(); if (pMeta.canRead()) { ClassMeta<?> cMeta = p.getClassMeta();