org.apache.juneau.marshall.Marshall Maven / Gradle / Ivy
package org.apache.juneau.marshall;
// ***************************************************************************************************************************
// * 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. *
// ***************************************************************************************************************************
import java.io.*;
import java.lang.reflect.*;
import org.apache.juneau.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.serializer.*;
/**
* Top-level class for a pairing of a {@link Serializer} and {@link Parser} into a single class with convenience read/write methods.
*
*
* The general idea is to combine a single serializer and parser inside a simplified API for reading and writing POJOs.
*
*
Examples:
*
* // Using instance.
* Marshall json = new Json();
* MyPojo myPojo = json.read(string, MyPojo.class );
* String string = json.write(myPojo);
*
*
* // Using DEFAULT instance.
* MyPojo myPojo = Json.DEFAULT .read(string, MyPojo.class );
* String string = Json.DEFAULT .write(myPojo);
*
*
* See Also:
*
* - {@doc juneau-marshall.Marshalls}
*
*/
public abstract class Marshall {
private final Serializer s;
private final Parser p;
/**
* Constructor.
*
* @param s
* The serializer to use for serializing output.
*
Must not be null .
* @param p
* The parser to use for parsing input.
*
Must not be null .
*/
protected Marshall(Serializer s, Parser p) {
this.s = s;
this.p = p;
}
/**
* Serializes a POJO 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 write(Object o) throws SerializeException {
return s.createSession().serialize(o);
}
/**
* 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.
*/
public final void write(Object o, Object output) throws SerializeException {
s.createSession().serialize(o, output);
}
/**
* Convenience method for serializing an object to a String.
*
*
* For writer-based serializers, this is identical to calling {@link Serializer#serialize(Object)}.
*
For stream-based serializers, this converts the returned byte array to a string based on
* the {@link OutputStreamSerializer#OSSERIALIZER_binaryFormat} setting.
*
* @param o The object to serialize.
* @return The output serialized to a string.
*/
public final String toString(Object o) {
try {
return s.serializeToString(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Convenience method for calling System.out.println(...)
on the specified object after calling {@link #toString(Object)}.
*
* @param o The object to serialize and then send to the console.
* @return This object (for method chaining).
*/
public final Marshall println(Object o) {
System.out.println(toString(o));
return this;
}
/**
* Parses input into the specified object type.
*
*
* The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
*
*
Examples:
*
* Marshall m = Json.DEFAULT ;
*
* // Parse into a linked-list of strings.
* List l = m.read(json, LinkedList.class , String.class );
*
* // Parse into a linked-list of beans.
* List l = m.read(json, LinkedList.class , MyBean.class );
*
* // Parse into a linked-list of linked-lists of strings.
* List l = m.read(json, LinkedList.class , LinkedList.class , String.class );
*
* // Parse into a map of string keys/values.
* Map m = m.read(json, TreeMap.class , String.class , String.class );
*
* // Parse into a map containing string keys and values of lists containing beans.
* Map m = m.read(json, TreeMap.class , String.class , List.class , MyBean.class );
*
*
*
* Collection
classes are assumed to be followed by zero or one objects indicating the element type.
*
*
* Map
classes are assumed to be followed by zero or two meta objects indicating the key and value types.
*
*
* The array can be arbitrarily long to indicate arbitrarily complex data structures.
*
*
Notes:
*
* -
* Use the {@link #read(Object, Class)} method instead if you don't need a parameterized map/collection.
*
*
* @param The class type of the object to create.
* @param input
* The input.
*
Character-based parsers can handle the following input class types:
*
* null
* - {@link Reader}
*
- {@link CharSequence}
*
- {@link InputStream} containing UTF-8 encoded text (or charset defined by
* {@link ReaderParser#RPARSER_inputStreamCharset} property value).
*
byte []
containing UTF-8 encoded text (or charset defined by
* {@link ReaderParser#RPARSER_inputStreamCharset} property value).
* - {@link File} containing system encoded text (or charset defined by
* {@link ReaderParser#RPARSER_fileCharset} property value).
*
*
Stream-based parsers can handle the following input class types:
*
* null
* - {@link InputStream}
*
byte []
* - {@link File}
*
- {@link CharSequence} containing encoded bytes according to the {@link InputStreamParser#ISPARSER_binaryFormat} setting.
*
* @param type
* The object type to create.
*
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
* @param args
* The type arguments of the class if it's a collection or map.
*
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
*
Ignored if the main type is not a map or collection.
* @return The parsed object.
* @throws ParseException
* If the input contains a syntax error or is malformed, or is not valid for the specified type.
* @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections.
*/
public final T read(Object input, Type type, Type...args) throws ParseException {
return p.createSession().parse(input, type, args);
}
/**
* Same as {@link #read(Object, Type, Type...)} except optimized for a non-parameterized class.
*
*
* This is the preferred parse method for simple types since you don't need to cast the results.
*
*
Examples:
*
* Marshall m = Json.DEFAULT ;
*
* // Parse into a string.
* String s = m.read(json, String.class );
*
* // Parse into a bean.
* MyBean b = m.read(json, MyBean.class );
*
* // Parse into a bean array.
* MyBean[] ba = m.read(json, MyBean[].class );
*
* // Parse into a linked-list of objects.
* List l = m.read(json, LinkedList.class );
*
* // Parse into a map of object keys/values.
* Map m = m.read(json, TreeMap.class );
*
*
* @param The class type of the object being created.
* @param input
* The input.
* See {@link #read(Object, Type, Type...)} for details.
* @param type The object type to create.
* @return The parsed object.
* @throws ParseException
* If the input contains a syntax error or is malformed, or is not valid for the specified type.
*/
public final T read(Object input, Class type) throws ParseException {
return p.createSession().parse(input, type);
}
}