package com.owlike.genson.stream;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
/**
* ObjectWriter defines the api allowing to write data to different format and the contract for
* classes that implement ObjectWriter to provide different formats support. Implementations are
* extremely efficient as they use low level stream operations and optimizations. If you want
* optimal performance you can directly use the streaming api (ObjectWriter and {@link ObjectReader}
* ) without the databind support that comes with the converters. This will be very close in terms
* of performance as writing manually formated data to the stream.
* <p/>
* If you want to write the array new int[1, 2, 3] to the stream with ObjectWriter:
* <p/>
* <pre>
* writer.beginArray().writeValue(1).writeValue(2).writeValue(3).endArray();
* </pre>
* <p/>
* And to write Person (we simplify, in practice you must handle null values):
* <p/>
* <pre>
* class Person {
* public static void main(String[] args) {
* // we will write from Person to json string
* Person p = new Person();
* p.name = "eugen";
* p.age = 26;
* p.childrenYearOfBirth = new ArrayList<Integer>();
* StringWriter sw = new StringWriter();
* ObjectWriter writer = new JsonWriter(sw);
* p.write(writer);
* writer.flush();
* writer.close();
* // will write {"name":"eugen","age":26,"childrenYearOfBirth":[]}
* System.out.println(sw.toString());
* }
*
* String name;
* int age;
* List<Integer> childrenYearOfBirth;
*
* public void write(ObjectWriter writer) {
* writer.beginObject().writeName("name");
* if (name == null) writer.writeNull();
* else writer.writeValue(name)
* writer.writeName("age").writeAge(age)
* .writeName("childrenYearOfBirth");
* if (childrenYearOfBirth == null) writer.writeNull();
* else {
* writer.beginArray();
* for (Integer year : childrenYearOfBirth)
* writer.writeValue(year);
* writer.endArray()
* }
* writer.endObject();
* }
* }
* </pre>
* <p/>
* Be careful if you instantiate ObjectWriter your self you are responsible of flushing and closing
* the stream.
*
* @author eugen
* @see JsonWriter
* @see ObjectReader
* @see JsonReader
*/
public interface ObjectWriter {
/**
* Starts to write an array (use it also for collections). An array is a suite of values that
* may be literals, arrays or objects. When you finished writing the values don't forget to call
* endArray().
*
* @return a reference to this allowing to chain method calls.
* @throws JsonStreamException if trying to produce invalid json
*/
public ObjectWriter beginArray();
/**
* Ends the array, if beginArray was not called, implementations should throw an exception.
*
* @return a reference to this allowing to chain method calls.
* @throws JsonStreamException if trying to produce invalid json
*/
public ObjectWriter endArray();
/**
* Starts a object, objects are a suite of name/value pairs, values may be literals, arrays or
* objects. Don't forget to call endObject.
*
* @return a reference to this allowing to chain method calls.
* @throws JsonStreamException if trying to produce invalid json
*/
public ObjectWriter beginObject();
/**
* Ends the object being written, if beginObject was not called an exception will be throwed.
*
* @return a reference to this allowing to chain method calls.
* @throws JsonStreamException if trying to produce invalid json
*/
public ObjectWriter endObject();
/**
* Writes the name of a property. Names can be written only in objects and must be called before
* writing the properties value.
*
* @param name a non null String
* @return a reference to this, allowing to chain method calls.
* @throws JsonStreamException if trying to produce invalid json
*/
public ObjectWriter writeName(String name);
/**
* Will write the name without escaping special characters, assuming it has been done by the caller or the string
* doesn't contain any character needing to be escaped.
* @param name a non null escaped String
* @return a reference to this, allowing to chain method calls.
* @throws JsonStreamException if trying to produce invalid json
*/
public ObjectWriter writeEscapedName(char[] name);
/**
* Writes a value to the stream. Values can be written in arrays and in objects (after writing
* the name).
*
* @param value to write.
* @return a reference to this, allowing to chain method calls.
* @throws JsonStreamException if trying to produce invalid json
*/
public ObjectWriter writeValue(int value);
/**
* See {@link #writeValue(int)}.
*
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeValue(double value);
/**
* See {@link #writeValue(int)}.
*
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeValue(long value);
/**
* See {@link #writeValue(int)}.
*
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeValue(short value);
/**
* @see #writeValue(int)
*/
public ObjectWriter writeValue(float value);
/**
* See {@link #writeValue(int)}.
*
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeValue(boolean value);
/**
* @see #writeString(String)
*/
public ObjectWriter writeBoolean(Boolean value);
/**
* See {@link #writeValue(int)}.
*
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeValue(Number value);
/**
* @see #writeString(String)
*/
public ObjectWriter writeNumber(Number value);
/**
* See {@link #writeValue(int)}.
*
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeValue(String value);
/**
* Similar to writeValue(String) but is null safe, meaning that if the value is null,
* then the write will call writeNull for you.
*/
public ObjectWriter writeString(String value);
/**
* Writes an array of bytes as a base64 encoded string. See {@link #writeValue(int)}.
*
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeValue(byte[] value);
/**
* @see #writeString(String)
*/
public ObjectWriter writeBytes(byte[] value);
/**
* Writes value as is without any pre-processing, it's faster than {@link #writeValue(String)}
* but should be used only if you know that it is safe.
*
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeUnsafeValue(String value);
/**
* Must be called when a null value is encountered. Implementations will deal with the null
* representation (just skip it or write null, etc).
*
* @return a reference to this allowing to chain method calls.
* @throws JsonStreamException if trying to produce invalid json
* @see #writeValue(int)
*/
public ObjectWriter writeNull();
/**
* This method is a kind of cheat as it allows us to start writing metadata and then still be
* able to call beginObject. This is mainly intended to be used in wrapped converters that want
* to handle a part of the serialization and then let the chain continue. Have a look at <a
* href=
* "http://code.google.com/p/genson/source/browse/src/main/java/com/owlike/genson/convert/ClassMetadataConverter.java"
* >ClassMetadataConverter</a>
*
* @return a reference to this allowing to chain method calls.
* @throws JsonStreamException
* @see #writeMetadata(String, String)
*/
public ObjectWriter beginNextObjectMetadata();
/**
* Metadata is a suite of name/value pairs, names will be prepended with '@' (handled by the
* library). Metadata feature is experimental for the moment so things may change a bit. The
* signature will not, but the way it is implemented could... Actually the contract is that
* metadata must be written first and only in objects. If it does not respect these conditions
* ObjectReader won't be able to detect it as metadata. Here is an example of two ways to write
* object metadata.
* <p/>
* <pre>
* // here it is transparent for the library if you write metadata or something else, you must call
* // beginObject before being able to start writing its metadata.
* writer.beginObject().writeMetadata("doc", "Object documentation bla bla...").writeName("name")
* .writeNull().endObject().flush();
*
* // previous example works fine, but if you want to write some metadata and still be able to call
* // beginObject (for example in a converter you want to write some metadata and have all the existing
* // continue to work with calling beginObject) you must use beginNextObjectMetadata.
*
* // written from a first converter
* writer.beginNextObjectMetadata().writeMetadata("dataFromConverter1", "writtenFromConverter1");
* // written from a second converter after first one
* writer.beginNextObjectMetadata().writeMetadata("dataFromConverter2", "writtenFromConverter2");
* // finally concrete properties will be written from a custom converter
* writer.beginObject().writeName("name").writeNull().endObject().flush();
* </pre>
*
* @param name of the metadata property, should not start with '@', the library will add it.
* @param value of the metadata property.
* @return a reference to this allowing to chain method calls.
* @throws JsonStreamException
* @see #beginNextObjectMetadata()
*/
public ObjectWriter writeMetadata(String name, String value);
/**
* @see #writeString(String, String)
*/
public ObjectWriter writeBoolean(String name, Boolean value);
/**
* @see #writeString(String, String)
*/
public ObjectWriter writeNumber(String name, Number value);
/**
* Will write the name and the value, it is just a shortcut for writer.writeName("key").writeString(value).
* Note if the value is null, writeNull is used.
*/
public ObjectWriter writeString(String name, String value);
/**
* @see #writeString(String, String)
*/
public ObjectWriter writeBytes(String name, byte[] value);
public void flush();
public void close();
public JsonType enclosingType();
}