![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.juneau.serializer.Serializer Maven / Gradle / Ivy
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
// * with the License. You may obtain a copy of the License at *
// * *
// * http://www.apache.org/licenses/LICENSE-2.0 *
// * *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
// * specific language governing permissions and limitations under the License. *
// ***************************************************************************************************************************
package org.apache.juneau.serializer;
import static org.apache.juneau.collections.JsonMap.*;
import static org.apache.juneau.common.internal.StringUtils.*;
import java.io.*;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.soap.*;
import org.apache.juneau.utils.*;
/**
* Parent class for all Juneau serializers.
*
* Description
*
* Base serializer class that serves as the parent class for all serializers.
*
*
* The purpose of this class is:
*
* - Maintain a read-only configuration state of a serializer.
*
- Create session objects used for serializing POJOs (i.e. {@link SerializerSession}).
*
- Provide convenience methods for serializing POJOs without having to construct session objects.
*
*
*
* Subclasses should (but are not required to) extend directly from {@link OutputStreamSerializer} or {@link WriterSerializer} depending on
* whether it's a stream or character based serializer.
*
*
* Subclasses must implement parsing via one of the following methods:
*
* - {@link #doSerialize(SerializerSession, SerializerPipe, Object)}
*
- {@link SerializerSession#doSerialize(SerializerPipe, Object)}
*
*
*
* Notes:
* - This class is thread safe and reusable.
*
*
* See Also:
*/
public class Serializer extends BeanTraverseContext {
//-------------------------------------------------------------------------------------------------------------------
// Static
//-------------------------------------------------------------------------------------------------------------------
/**
* Creates a new builder for this object.
*
* @return A new builder.
*/
public static Builder create() {
return new Builder();
}
/**
* Represents no Serializer.
*/
public static abstract class Null extends Serializer {
private Null(Builder builder) {
super(builder);
}
}
/**
* Instantiates a builder of the specified serializer class.
*
*
* Looks for a public static method called create that returns an object that can be passed into a public
* or protected constructor of the class.
*
* @param c The builder to create.
* @return A new builder.
*/
public static Builder createSerializerBuilder(Class extends Serializer> c) {
return (Builder)Context.createBuilder(c);
}
//-------------------------------------------------------------------------------------------------------------------
// Builder
//-------------------------------------------------------------------------------------------------------------------
/**
* Builder class.
*/
@FluentSetters
public static class Builder extends BeanTraverseContext.Builder {
boolean addBeanTypes, addRootType, keepNullProperties, sortCollections, sortMaps, trimEmptyCollections,
trimEmptyMaps, trimStrings;
String produces, accept;
UriContext uriContext;
UriRelativity uriRelativity;
UriResolution uriResolution;
Class extends SerializerListener> listener;
/**
* Constructor, default settings.
*/
protected Builder() {
produces = null;
accept = null;
addBeanTypes = env("Serializer.addBeanTypes", false);
addRootType = env("Serializer.addRootType", false);
keepNullProperties = env("Serializer.keepNullProperties", false);
sortCollections = env("Serializer.sortCollections", false);
sortMaps = env("Serializer.sortMaps", false);
trimEmptyCollections = env("Serializer.trimEmptyCollections", false);
trimEmptyMaps = env("Serializer.trimEmptyMaps", false);
trimStrings = env("Serializer.trimStrings", false);
uriContext = UriContext.DEFAULT;
uriRelativity = UriRelativity.RESOURCE;
uriResolution = UriResolution.NONE;
listener = null;
}
/**
* Copy constructor.
*
* @param copyFrom The bean to copy from.
*/
protected Builder(Serializer copyFrom) {
super(copyFrom);
produces = copyFrom.produces;
accept = copyFrom.accept;
addBeanTypes = copyFrom.addBeanTypes;
addRootType = copyFrom.addRootType;
keepNullProperties = copyFrom.keepNullProperties;
sortCollections = copyFrom.sortCollections;
sortMaps = copyFrom.sortMaps;
trimEmptyCollections = copyFrom.trimEmptyCollections;
trimEmptyMaps = copyFrom.trimEmptyMaps;
trimStrings = copyFrom.trimStrings;
uriContext = copyFrom.uriContext;
uriRelativity = copyFrom.uriRelativity;
uriResolution = copyFrom.uriResolution;
listener = copyFrom.listener;
}
/**
* Copy constructor.
*
* @param copyFrom The builder to copy from.
*/
protected Builder(Builder copyFrom) {
super(copyFrom);
produces = copyFrom.produces;
accept = copyFrom.accept;
addBeanTypes = copyFrom.addBeanTypes;
addRootType = copyFrom.addRootType;
keepNullProperties = copyFrom.keepNullProperties;
sortCollections = copyFrom.sortCollections;
sortMaps = copyFrom.sortMaps;
trimEmptyCollections = copyFrom.trimEmptyCollections;
trimEmptyMaps = copyFrom.trimEmptyMaps;
trimStrings = copyFrom.trimStrings;
uriContext = copyFrom.uriContext;
uriRelativity = copyFrom.uriRelativity;
uriResolution = copyFrom.uriResolution;
listener = copyFrom.listener;
}
@Override /* Context.Builder */
public Builder copy() {
return new Builder(this);
}
@Override /* Context.Builder */
public Serializer build() {
return build(Serializer.class);
}
@Override /* Context.Builder */
public HashKey hashKey() {
return HashKey.of(
super.hashKey(),
produces,
accept,
addBeanTypes,
addRootType,
keepNullProperties,
sortCollections,
sortMaps,
trimEmptyCollections,
trimEmptyMaps,
trimStrings,
uriContext,
uriRelativity,
uriResolution,
listener
);
}
//-----------------------------------------------------------------------------------------------------------------
// Properties
//-----------------------------------------------------------------------------------------------------------------
/**
* Specifies the media type that this serializer produces.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder produces(String value) {
this.produces = value;
return this;
}
/**
* Returns the current value for the 'produces' property.
*
* @return The current value for the 'produces' property.
*/
public String getProduces() {
return produces;
}
/**
* Specifies the accept media types that the serializer can handle.
*
*
* Can contain meta-characters per the media-type specification of RFC2616/14.1
*
* If empty, then assumes the only media type supported is produces .
*
* For example, if this serializer produces "application/json" but should handle media types of
* "application/json" and "text/json" , then the arguments should be:
*
* builder .produces("application/json" );
* builder .accept("application/json,text/json" );
*
*
* The accept value can also contain q-values.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder accept(String value) {
this.accept = value;
return this;
}
/**
* Returns the current value for the 'accept' property.
*
* @return The current value for the 'accept' property.
*/
public String getAccept() {
return accept;
}
/**
* Add "_type" properties when needed.
*
*
* When enabled, "_type" properties will be added to beans if their type cannot be inferred
* through reflection.
*
*
* This is used to recreate the correct objects during parsing if the object types cannot be inferred.
*
For example, when serializing a Map<String,Object> field where the bean class cannot be determined from
* the type of the values.
*
*
* Note the differences between the following settings:
*
* - {@link #addRootType()} - Affects whether
'_type' is added to root node.
* - {@link #addBeanTypes()} - Affects whether
'_type' is added to any nodes.
*
*
* Example:
*
* // Create a serializer that adds _type to nodes.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .addBeanTypes()
* .build();
*
* // Our map of beans to serialize.
* @Bean (typeName="mybean" )
* public class MyBean {
* public String foo = "bar" ;
* }
* JsonMap myMap = JsonMap.of("foo" , new MyBean());
*
* // Will contain: {"foo":{"_type":"mybean","foo":"bar"}}
* String json = serializer .serialize(myMap );
*
*
* @return This object.
*/
@FluentSetter
public Builder addBeanTypes() {
return addBeanTypes(true);
}
/**
* Same as {@link #addBeanTypes()} but allows you to explicitly specify the value.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder addBeanTypes(boolean value) {
addBeanTypes = value;
return this;
}
/**
* Add type attribute to root nodes.
*
*
* When enabled, "_type" properties will be added to top-level beans.
*
*
* When disabled, it is assumed that the parser knows the exact Java POJO type being parsed, and therefore top-level
* type information that might normally be included to determine the data type will not be serialized.
*
*
* For example, when serializing a top-level POJO with a {@link Bean#typeName() @Bean(typeName)} value, a
* '_type' attribute will only be added when this setting is enabled.
*
*
* Note the differences between the following settings:
*
* - {@link #addRootType()} - Affects whether
'_type' is added to root node.
* - {@link #addBeanTypes()} - Affects whether
'_type' is added to any nodes.
*
*
* Example:
*
* // Create a serializer that adds _type to root node.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .addRootType()
* .build();
*
* // Our bean to serialize.
* @Bean (typeName="mybean" )
* public class MyBean {
* public String foo = "bar" ;
* }
*
* // Will contain: {"_type":"mybean","foo":"bar"}
* String json = serializer .serialize(new MyBean());
*
*
* @return This object.
*/
@FluentSetter
public Builder addRootType() {
return addRootType(true);
}
/**
* Same as {@link #addRootType()} but allows you to explicitly specify the value.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder addRootType(boolean value) {
addRootType = value;
return this;
}
/**
* Don't trim null bean property values.
*
*
* When enabled, null bean values will be serialized to the output.
*
*
Notes:
* - Not enabling this setting will cause
Map s with null values to be lost during parsing.
*
*
* Example:
*
* // Create a serializer that serializes null properties.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .keepNullProperties()
* .build();
*
* // Our bean to serialize.
* public class MyBean {
* public String foo = null ;
* }
*
* // Will contain "{foo:null}".
* String json = serializer .serialize(new MyBean());
*
*
* @return This object.
*/
@FluentSetter
public Builder keepNullProperties() {
return keepNullProperties(true);
}
/**
* Same as {@link #keepNullProperties()} but allows you to explicitly specify the value.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder keepNullProperties(boolean value) {
keepNullProperties = value;
return this;
}
/**
* Serializer listener.
*
*
* Class used to listen for errors and warnings that occur during serialization.
*
*
Example:
*
* // Define our serializer listener.
* // Simply captures all errors.
* public class MySerializerListener extends SerializerListener {
*
* // A simple property to store our events.
* public List<String> events = new LinkedList<>();
*
* @Override
* public <T> void onError(SerializerSession session , Throwable throwable , String msg ) {
* events .add(session .getLastLocation() + "," + msg + "," + throwable );
* }
* }
*
* // Create a serializer using our listener.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .listener(MySerializerListener.class )
* .build();
*
* // Create a session object.
* // Needed because listeners are created per-session.
* try (WriterSerializerSession session = serializer .createSession()) {
*
* // Serialize a bean.
* String json = session .serialize(new MyBean());
*
* // Get the listener.
* MySerializerListener listener = session .getListener(MySerializerListener.class );
*
* // Dump the results to the console.
* Json5.DEFAULT .println(listener .events );
* }
*
*
* @param value
* The new value for this property.
* @return This object.
*/
@FluentSetter
public Builder listener(Class extends SerializerListener> value) {
listener = value;
return this;
}
/**
* Sort arrays and collections alphabetically.
*
*
* When enabled, copies and sorts the contents of arrays and collections before serializing them.
*
*
* Note that this introduces a performance penalty since it requires copying the existing collection.
*
*
Example:
*
* // Create a serializer that sorts arrays and collections before serialization.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .sortCollections()
* .build();
*
* // An unsorted array
* String[] myArray = {"foo" ,"bar" ,"baz" };
*
* // Produces ["bar","baz","foo"]
* String json = serializer .serialize(myArray );
*
*
* @return This object.
*/
@FluentSetter
public Builder sortCollections() {
return sortCollections(true);
}
/**
* Same as {@link #sortCollections()} but allows you to explicitly specify the value.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder sortCollections(boolean value) {
sortCollections = value;
return this;
}
/**
* Sort maps alphabetically.
*
*
* When enabled, copies and sorts the contents of maps by their keys before serializing them.
*
*
* Note that this introduces a performance penalty.
*
*
Example:
*
* // Create a serializer that sorts maps before serialization.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .sortMaps()
* .build();
*
* // An unsorted map.
* JsonMap myMap = JsonMap.of ("foo" ,1,"bar" ,2,"baz" ,3);
*
* // Produces {"bar":2,"baz":3,"foo":1}
* String json = serializer .serialize(myMap );
*
*
* @return This object.
*/
@FluentSetter
public Builder sortMaps() {
return sortMaps(true);
}
/**
* Same as {@link #sortMaps()} but allows you to explicitly specify the value.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder sortMaps(boolean value) {
sortMaps = value;
return this;
}
/**
* Trim empty lists and arrays.
*
*
* When enabled, empty lists and arrays will not be serialized.
*
*
* Note that enabling this setting has the following effects on parsing:
*
* -
* Map entries with empty list values will be lost.
*
-
* Bean properties with empty list values will not be set.
*
*
* Example:
*
* // Create a serializer that skips empty arrays and collections.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .trimEmptyCollections()
* .build();
*
* // A bean with a field with an empty array.
* public class MyBean {
* public String[] foo = {};
* }
*
* // Produces {}
* String json = serializer .serialize(new MyBean());
*
*
* @return This object.
*/
@FluentSetter
public Builder trimEmptyCollections() {
return trimEmptyCollections(true);
}
/**
* Same as {@link #trimEmptyCollections()} but allows you to explicitly specify the value.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder trimEmptyCollections(boolean value) {
trimEmptyCollections = value;
return this;
}
/**
* Trim empty maps.
*
*
* When enabled, empty map values will not be serialized to the output.
*
*
* Note that enabling this setting has the following effects on parsing:
*
* -
* Bean properties with empty map values will not be set.
*
*
* Example:
*
* // Create a serializer that skips empty maps.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .trimEmptyMaps()
* .build();
*
* // A bean with a field with an empty map.
* public class MyBean {
* public JsonMap foo = JsonMap.of ();
* }
*
* // Produces {}
* String json = serializer .serialize(new MyBean());
*
*
* @return This object.
*/
@FluentSetter
public Builder trimEmptyMaps() {
return trimEmptyMaps(true);
}
/**
* Same as {@link #trimEmptyMaps()} but allows you to explicitly specify the value.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder trimEmptyMaps(boolean value) {
trimEmptyMaps = value;
return this;
}
/**
* Trim strings.
*
*
* When enabled, string values will be trimmed of whitespace using {@link String#trim()} before being serialized.
*
*
Example:
*
* // Create a serializer that trims strings before serialization.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .trimStrings()
* .build();
*
* // A map with space-padded keys/values
* JsonMap myMap = JsonMap.of (" foo " , " bar " );
*
* // Produces "{foo:'bar'}"
* String json = serializer .toString(myMap );
*
*
* @return This object.
*/
@FluentSetter
public Builder trimStrings() {
return trimStrings(true);
}
/**
* Same as {@link #trimStrings()} but allows you to explicitly specify the value.
*
* @param value The value for this setting.
* @return This object.
*/
@FluentSetter
public Builder trimStrings(boolean value) {
trimStrings = value;
return this;
}
/**
* URI context bean.
*
*
* Bean used for resolution of URIs to absolute or root-relative form.
*
*
Example:
*
* // Our URI contextual information.
* String authority = "http://localhost:10000" ;
* String contextRoot = "/myContext" ;
* String servletPath = "/myServlet" ;
* String pathInfo = "/foo" ;
*
* // Create a UriContext object.
* UriContext uriContext = new UriContext(authority , contextRoot , servletPath , pathInfo );
*
* // Associate it with our serializer.
* WriterSerializer serializer = JsonSerializer
* .create ()
* .uriContext(uriContext )
* .uriRelativity(RESOURCE ) // Assume relative paths are relative to servlet.
* .uriResolution(ABSOLUTE ) // Serialize URLs as absolute paths.
* .build();
*
* // A relative URL
* URL myUrl = new URL("bar" );
*
* // Produces "http://localhost:10000/myContext/myServlet/foo/bar"
* String json = serializer .toString(myUrl );
*
*
* See Also:
* - URIs
*
*
* @param value The new value for this property.
* @return This object.
*/
@FluentSetter
public Builder uriContext(UriContext value) {
uriContext = value;
return this;
}
/**
* URI relativity.
*
*
* Defines what relative URIs are relative to when serializing any of the following:
*
* - {@link java.net.URI}
*
- {@link java.net.URL}
*
- Properties and classes annotated with {@link Uri @Uri}
*
*
*
* See {@link #uriContext(UriContext)} for examples.
*
*
* - {@link org.apache.juneau.UriRelativity#RESOURCE}
* - Relative URIs should be considered relative to the servlet URI.
*
- {@link org.apache.juneau.UriRelativity#PATH_INFO}
* - Relative URIs should be considered relative to the request URI.
*
*
* See Also:
* - URIs
*
*
* @param value
* The new value for this property.
*
The default is {@link UriRelativity#RESOURCE}
* @return This object.
*/
@FluentSetter
public Builder uriRelativity(UriRelativity value) {
uriRelativity = value;
return this;
}
/**
* URI resolution.
*
*
* Defines the resolution level for URIs when serializing any of the following:
*
* - {@link java.net.URI}
*
- {@link java.net.URL}
*
- Properties and classes annotated with {@link Uri @Uri}
*
*
*
* See {@link #uriContext(UriContext)} for examples.
*
*
* - {@link UriResolution#ABSOLUTE}
* - Resolve to an absolute URL (e.g.
"http://host:port/context-root/servlet-path/path-info" ).
* - {@link UriResolution#ROOT_RELATIVE}
* - Resolve to a root-relative URL (e.g.
"/context-root/servlet-path/path-info" ).
* - {@link UriResolution#NONE}
* - Don't do any URL resolution.
*
*
* See Also:
* - URIs
*
*
* @param value
* The new value for this property.
*
The default is {@link UriResolution#NONE}
* @return This object.
*/
@FluentSetter
public Builder uriResolution(UriResolution value) {
uriResolution = value;
return this;
}
//
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder annotations(Annotation...values) {
super.annotations(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder apply(AnnotationWorkList work) {
super.apply(work);
return this;
}
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder applyAnnotations(java.lang.Class>...fromClasses) {
super.applyAnnotations(fromClasses);
return this;
}
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder applyAnnotations(Method...fromMethods) {
super.applyAnnotations(fromMethods);
return this;
}
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder cache(Cache value) {
super.cache(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder debug() {
super.debug();
return this;
}
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder debug(boolean value) {
super.debug(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder impl(Context value) {
super.impl(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.Context.Builder */
public Builder type(Class extends org.apache.juneau.Context> value) {
super.type(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanClassVisibility(Visibility value) {
super.beanClassVisibility(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanConstructorVisibility(Visibility value) {
super.beanConstructorVisibility(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanContext(BeanContext value) {
super.beanContext(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanContext(BeanContext.Builder value) {
super.beanContext(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanDictionary(java.lang.Class>...values) {
super.beanDictionary(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanFieldVisibility(Visibility value) {
super.beanFieldVisibility(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanInterceptor(Class> on, Class extends org.apache.juneau.swap.BeanInterceptor>> value) {
super.beanInterceptor(on, value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanMapPutReturnsOldValue() {
super.beanMapPutReturnsOldValue();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanMethodVisibility(Visibility value) {
super.beanMethodVisibility(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanProperties(Map values) {
super.beanProperties(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanProperties(Class> beanClass, String properties) {
super.beanProperties(beanClass, properties);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanProperties(String beanClassName, String properties) {
super.beanProperties(beanClassName, properties);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesExcludes(Map values) {
super.beanPropertiesExcludes(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesExcludes(Class> beanClass, String properties) {
super.beanPropertiesExcludes(beanClass, properties);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesExcludes(String beanClassName, String properties) {
super.beanPropertiesExcludes(beanClassName, properties);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesReadOnly(Map values) {
super.beanPropertiesReadOnly(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesReadOnly(Class> beanClass, String properties) {
super.beanPropertiesReadOnly(beanClass, properties);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
super.beanPropertiesReadOnly(beanClassName, properties);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesWriteOnly(Map values) {
super.beanPropertiesWriteOnly(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesWriteOnly(Class> beanClass, String properties) {
super.beanPropertiesWriteOnly(beanClass, properties);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
super.beanPropertiesWriteOnly(beanClassName, properties);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beansRequireDefaultConstructor() {
super.beansRequireDefaultConstructor();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beansRequireSerializable() {
super.beansRequireSerializable();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder beansRequireSettersForGetters() {
super.beansRequireSettersForGetters();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder dictionaryOn(Class> on, java.lang.Class>...values) {
super.dictionaryOn(on, values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder disableBeansRequireSomeProperties() {
super.disableBeansRequireSomeProperties();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder disableIgnoreMissingSetters() {
super.disableIgnoreMissingSetters();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder disableIgnoreTransientFields() {
super.disableIgnoreTransientFields();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder disableIgnoreUnknownNullBeanProperties() {
super.disableIgnoreUnknownNullBeanProperties();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder disableInterfaceProxies() {
super.disableInterfaceProxies();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder example(Class pojoClass, T o) {
super.example(pojoClass, o);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder example(Class pojoClass, String json) {
super.example(pojoClass, json);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder findFluentSetters() {
super.findFluentSetters();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder findFluentSetters(Class> on) {
super.findFluentSetters(on);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder ignoreInvocationExceptionsOnGetters() {
super.ignoreInvocationExceptionsOnGetters();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder ignoreInvocationExceptionsOnSetters() {
super.ignoreInvocationExceptionsOnSetters();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder ignoreUnknownBeanProperties() {
super.ignoreUnknownBeanProperties();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder ignoreUnknownEnumValues() {
super.ignoreUnknownEnumValues();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder implClass(Class> interfaceClass, Class> implClass) {
super.implClass(interfaceClass, implClass);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder implClasses(Map,Class>> values) {
super.implClasses(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder interfaceClass(Class> on, Class> value) {
super.interfaceClass(on, value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder interfaces(java.lang.Class>...value) {
super.interfaces(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder locale(Locale value) {
super.locale(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder mediaType(MediaType value) {
super.mediaType(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder notBeanClasses(java.lang.Class>...values) {
super.notBeanClasses(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder notBeanPackages(String...values) {
super.notBeanPackages(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder propertyNamer(Class extends org.apache.juneau.PropertyNamer> value) {
super.propertyNamer(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder propertyNamer(Class> on, Class extends org.apache.juneau.PropertyNamer> value) {
super.propertyNamer(on, value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder sortProperties() {
super.sortProperties();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder sortProperties(java.lang.Class>...on) {
super.sortProperties(on);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder stopClass(Class> on, Class> value) {
super.stopClass(on, value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder swap(Class normalClass, Class swappedClass, ThrowingFunction swapFunction) {
super.swap(normalClass, swappedClass, swapFunction);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder swap(Class normalClass, Class swappedClass, ThrowingFunction swapFunction, ThrowingFunction unswapFunction) {
super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder swaps(java.lang.Class>...values) {
super.swaps(values);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder timeZone(TimeZone value) {
super.timeZone(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder typeName(Class> on, String value) {
super.typeName(on, value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder typePropertyName(String value) {
super.typePropertyName(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder typePropertyName(Class> on, String value) {
super.typePropertyName(on, value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder useEnumNames() {
super.useEnumNames();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
public Builder useJavaBeanIntrospector() {
super.useJavaBeanIntrospector();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
public Builder detectRecursions() {
super.detectRecursions();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
public Builder detectRecursions(boolean value) {
super.detectRecursions(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
public Builder ignoreRecursions() {
super.ignoreRecursions();
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
public Builder ignoreRecursions(boolean value) {
super.ignoreRecursions(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
public Builder initialDepth(int value) {
super.initialDepth(value);
return this;
}
@Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
public Builder maxDepth(int value) {
super.maxDepth(value);
return this;
}
//
}
//-------------------------------------------------------------------------------------------------------------------
// Instance
//-------------------------------------------------------------------------------------------------------------------
final String produces, accept;
final boolean
addBeanTypes,
keepNullProperties,
trimEmptyCollections,
trimEmptyMaps,
trimStrings,
sortCollections,
sortMaps,
addRootType;
final UriContext uriContext;
final UriResolution uriResolution;
final UriRelativity uriRelativity;
final Class extends SerializerListener> listener;
private final MediaRanges acceptRanges;
private final MediaType[] acceptMediaTypes;
private final MediaType producesMediaType;
/**
* Constructor
*
* @param builder The builder this object.
*/
protected Serializer(Builder builder) {
super(builder);
produces = builder.produces;
accept = builder.accept;
addBeanTypes = builder.addBeanTypes;
keepNullProperties = builder.keepNullProperties;
trimEmptyCollections = builder.trimEmptyCollections;
trimEmptyMaps = builder.trimEmptyMaps;
trimStrings = builder.trimStrings;
sortCollections = builder.sortCollections;
sortMaps = builder.sortMaps;
addRootType = builder.addRootType;
uriContext = builder.uriContext;
uriResolution = builder.uriResolution;
uriRelativity = builder.uriRelativity;
listener = builder.listener;
this.producesMediaType = MediaType.of(produces);
this.acceptRanges = accept != null ? MediaRanges.of(accept) : MediaRanges.of(produces);
this.acceptMediaTypes = builder.accept != null ? MediaType.ofAll(split(builder.accept)) : new MediaType[] {this.producesMediaType};
}
@Override /* Context */
public Builder copy() {
return new Builder(this);
}
@Override /* Context */
public SerializerSession.Builder createSession() {
return SerializerSession.create(this);
}
@Override /* Context */
public SerializerSession getSession() {
return createSession().build();
}
/**
* Returns true if this serializer subclasses from {@link WriterSerializer}.
*
* @return true if this serializer subclasses from {@link WriterSerializer}.
*/
public boolean isWriterSerializer() {
return false;
}
//-----------------------------------------------------------------------------------------------------------------
// Convenience methods
//-----------------------------------------------------------------------------------------------------------------
/**
* Serializes a POJO to the specified output stream or writer.
*
*
* Equivalent to calling serializer.createSession().serialize(o, output);
*
* @param o The object to serialize.
* @param output
* The output object.
*
Character-based serializers can handle the following output class types:
*
* - {@link Writer}
*
- {@link OutputStream} - Output will be written as UTF-8 encoded stream.
*
- {@link File} - Output will be written as system-default encoded stream.
*
- {@link StringBuilder} - Output will be written to the specified string builder.
*
*
Stream-based serializers can handle the following output class types:
*
* - {@link OutputStream}
*
- {@link File}
*
* @throws SerializeException If a problem occurred trying to convert the output.
* @throws IOException Thrown by the underlying stream.
*/
public final void serialize(Object o, Object output) throws SerializeException, IOException {
getSession().serialize(o, output);
}
/**
* Shortcut method for serializing objects directly to either a String or byte []
* depending on the serializer type.
*
* @param o The object to serialize.
* @return
* The serialized object.
*
Character-based serializers will return a String
*
Stream-based serializers will return a byte []
* @throws SerializeException If a problem occurred trying to convert the output.
*/
public Object serialize(Object o) throws SerializeException {
return getSession().serialize(o);
}
/**
* Convenience method for serializing an object to a String.
*
*
* For writer-based serializers, this is identical to calling {@link #serialize(Object)}.
*
For stream-based serializers, this converts the returned byte array to a string based on
* the {@link OutputStreamSerializer.Builder#binaryFormat(BinaryFormat)} setting.
*
* @param o The object to serialize.
* @return The output serialized to a string.
* @throws SerializeException If a problem occurred trying to convert the output.
*/
public final String serializeToString(Object o) throws SerializeException {
return getSession().serializeToString(o);
}
//-----------------------------------------------------------------------------------------------------------------
// Other methods
//-----------------------------------------------------------------------------------------------------------------
/**
* Serializes a POJO to the specified pipe.
*
* @param session The current session.
* @param pipe Where to send the output from the serializer.
* @param o The object to serialize.
* @throws IOException Thrown by underlying stream.
* @throws SerializeException Problem occurred trying to serialize object.
*/
protected void doSerialize(SerializerSession session, SerializerPipe pipe, Object o) throws IOException, SerializeException {
throw new UnsupportedOperationException();
}
/**
* Optional method that specifies HTTP request headers for this serializer.
*
*
* For example, {@link SoapXmlSerializer} needs to set a SOAPAction header.
*
*
* This method is typically meaningless if the serializer is being used stand-alone (i.e. outside of a REST server
* or client).
*
* @param session The current session.
* @return
* The HTTP headers to set on HTTP requests.
* Never null .
*/
public Map getResponseHeaders(SerializerSession session) {
return Collections.emptyMap();
}
/**
* Returns the media types handled based on the value of the accept parameter passed into the constructor.
*
*
* Note that the order of these ranges are from high to low q-value.
*
* @return The list of media types. Never null .
*/
public final MediaRanges getMediaTypeRanges() {
return acceptRanges;
}
/**
* Returns the first entry in the accept parameter passed into the constructor.
*
*
* This signifies the 'primary' media type for this serializer.
*
* @return The media type. Never null .
*/
public final MediaType getPrimaryMediaType() {
return acceptMediaTypes[0];
}
/**
* Performs an action on the media types handled based on the value of the accept parameter passed into the constructor.
*
*
* The order of the media types are the same as those in the accept parameter.
*
* @param action The action to perform on the media types.
* @return This object.
*/
public final Serializer forEachAcceptMediaType(Consumer action) {
for (MediaType m : acceptMediaTypes)
action.accept(m);
return this;
}
/**
* Optional method that returns the response Content-Type for this serializer if it is different from
* the matched media type.
*
*
* This method is specified to override the content type for this serializer.
* For example, the {@link org.apache.juneau.json.Json5Serializer} class returns that it handles media type
* "text/json5" , but returns "text/json" as the actual content type.
* This allows clients to request specific 'flavors' of content using specialized Accept header values.
*
*
* 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 null , then the matched media type is used.
*/
public final MediaType getResponseContentType() {
return producesMediaType;
}
//-----------------------------------------------------------------------------------------------------------------
// Properties
//-----------------------------------------------------------------------------------------------------------------
/**
* Add "_type" properties when needed.
*
* @see Serializer.Builder#addBeanTypes()
* @return
* true if "_type" properties added to beans if their type cannot be inferred
* through reflection.
*/
protected boolean isAddBeanTypes() {
return addBeanTypes;
}
/**
* Add type attribute to root nodes.
*
* @see Serializer.Builder#addRootType()
* @return
* true if type property should be added to root node.
*/
protected final boolean isAddRootType() {
return addRootType;
}
/**
* Serializer listener.
*
* @see Serializer.Builder#listener(Class)
* @return
* Class used to listen for errors and warnings that occur during serialization.
*/
protected final Class extends SerializerListener> getListener() {
return listener;
}
/**
* Sort arrays and collections alphabetically.
*
* @see Serializer.Builder#sortCollections()
* @return
* true if arrays and collections are copied and sorted before serialization.
*/
protected final boolean isSortCollections() {
return sortCollections;
}
/**
* Sort maps alphabetically.
*
* @see Serializer.Builder#sortMaps()
* @return
* true if maps are copied and sorted before serialization.
*/
protected final boolean isSortMaps() {
return sortMaps;
}
/**
* Trim empty lists and arrays.
*
* @see Serializer.Builder#trimEmptyCollections()
* @return
* true if empty lists and arrays are not serialized to the output.
*/
protected final boolean isTrimEmptyCollections() {
return trimEmptyCollections;
}
/**
* Trim empty maps.
*
* @see Serializer.Builder#trimEmptyMaps()
* @return
* true if empty map values are not serialized to the output.
*/
protected final boolean isTrimEmptyMaps() {
return trimEmptyMaps;
}
/**
* Don't trim null bean property values.
*
* @see Serializer.Builder#keepNullProperties()
* @return
* true if null bean values are serialized to the output.
*/
protected final boolean isKeepNullProperties() {
return keepNullProperties;
}
/**
* Trim strings.
*
* @see Serializer.Builder#trimStrings()
* @return
* true if string values will be trimmed of whitespace using {@link String#trim()} before being serialized.
*/
protected final boolean isTrimStrings() {
return trimStrings;
}
/**
* URI context bean.
*
* @see Serializer.Builder#uriContext(UriContext)
* @return
* Bean used for resolution of URIs to absolute or root-relative form.
*/
protected final UriContext getUriContext() {
return uriContext;
}
/**
* URI relativity.
*
* @see Serializer.Builder#uriRelativity(UriRelativity)
* @return
* Defines what relative URIs are relative to when serializing any of the following:
*/
protected final UriRelativity getUriRelativity() {
return uriRelativity;
}
/**
* URI resolution.
*
* @see Serializer.Builder#uriResolution(UriResolution)
* @return
* Defines the resolution level for URIs when serializing URIs.
*/
protected final UriResolution getUriResolution() {
return uriResolution;
}
//-----------------------------------------------------------------------------------------------------------------
// Other methods
//-----------------------------------------------------------------------------------------------------------------
@Override /* Context */
protected JsonMap properties() {
return filteredMap()
.append("addBeanTypes", addBeanTypes)
.append("keepNullProperties", keepNullProperties)
.append("trimEmptyCollections", trimEmptyCollections)
.append("trimEmptyMaps", trimEmptyMaps)
.append("trimStrings", trimStrings)
.append("sortCollections", sortCollections)
.append("sortMaps", sortMaps)
.append("addRootType", addRootType)
.append("uriContext", uriContext)
.append("uriResolution", uriResolution)
.append("uriRelativity", uriRelativity)
.append("listener", listener);
}
}