org.modeshape.schematic.document.Json Maven / Gradle / Ivy
Show all versions of modeshape-schematic Show documentation
/*
* ModeShape (http://www.modeshape.org)
*
* Licensed 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.modeshape.schematic.document;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.modeshape.schematic.internal.document.CompactJsonWriter;
import org.modeshape.schematic.internal.document.JsonReader;
import org.modeshape.schematic.internal.document.JsonWriter;
import org.modeshape.schematic.internal.document.PrettyJsonWriter;
/**
* A utility class for working with JSON documents. This class is able to read and write JSON documents that are in a special
* modified format. Modified Format
Any JSON document written in this modified format is still a valid JSON document.
* However, certain value types supported by BSON are written as nested objects in particular patterns. In fact, it is nearly
* identical to the JSON serialization used by MongoDB. All standard JSON values are written as expected, but the types unique to
* BSON are written as follows:
*
*
*
* BSON Type
* Class
* Format
* Example
*
*
* Symbol
* {@link Symbol}
* "value"
* "The quick brown fox"
*
*
* Regular Expression
* {@link Pattern}
* { "$regex" : "pattern", "$otions" : "flags" }
* { "$regex" : "[CH]at\sin", "$options" : "im" }
*
*
* Date
* {@link Date}
* { "$date" : "yyyy-MM-ddTHH:mm:ssZ" }
* { "$date" : "2011-06-11T08:44:25Z" }
*
*
* Timestamp
* {@link Timestamp}
* { "$ts" : timeValue, "$inc" : incValue }
* "\/TS("2011-06-11T08:44:25Z")\/"
*
*
* ObjectId
* {@link ObjectId}
* { "$oid" : "12bytesOfIdInBase16" }
* { "$oid" : "0000012c0000c8000900000f" }
*
*
* Binary
* {@link Binary}
* { "$type" : typeAsInt, "$base64" : "bytesInBase64" }"
* { "$type" : 0, "$base64" : "TWFuIGlzIGRpc3R" }"
*
*
* UUID
* {@link UUID}
* { "$uuid" : "string-form-of-uuid" }
* { "$uuid" : "09e0e949-bba4-459c-bb1d-9352e5ee8958" }
*
*
* Code
* {@link Code}
* { "$code" : "code" }
* { "$code" : "244-I2" }
*
*
* CodeWithScope
* {@link CodeWithScope}
* { "$code" : "code", "$scope" : scope document }
* { "$code" : "244-I2", "$scope" : { "name" : "Joe" } }
*
*
* MinKey
* {@link MinKey}
* "MinKey"
* "MinKey"
*
*
* MaxKey
* {@link MaxKey}
* "MaxKey"
* "MaxKey"
*
*
* Null value
* n/a
* null
* null
*
*
*
*
* @author Randall Hauch (C) 2011 Red Hat Inc.
*/
public class Json {
public static final Charset UTF8;
static {
Charset charset = Charset.defaultCharset();
try {
charset = Charset.forName("UTF-8");
} catch (Throwable t) {
Logger.getLogger(CompactJsonWriter.class.getName()).log(Level.SEVERE,
"Unable to obtain 'UTF-8' character set for JSON writing; using default charset.");
}
UTF8 = charset;
}
private static final CompactJsonWriter SHARED_COMPACT_WRITER = new CompactJsonWriter();
/**
* A set of field names that are reserved for special formatting of non-standard JSON value types as nested objects.
*
* @author Randall Hauch (C) 2011 Red Hat Inc.
* @since 5.1
*/
public class ReservedField {
/**
* The "$oid" field name, used within an {@link ObjectId} value. A single ObjectId will be written
*/
public static final String OBJECT_ID = "$oid";
public static final String DATE = "$date";
public static final String TIMESTAMP = "$ts";
public static final String INCREMENT = "$inc";
public static final String REGEX_PATTERN = "$regex";
public static final String REGEX_OPTIONS = "$options";
public static final String BINARY_TYPE = "$type";
public static final String BASE_64 = "$base64";
public static final String UUID = "$uuid";
public static final String CODE = "$code";
public static final String SCOPE = "$scope";
}
protected static JsonWriter getCompactJsonWriter() {
return SHARED_COMPACT_WRITER;
}
protected static JsonWriter getPrettyWriter() {
return new PrettyJsonWriter();
}
private static final JsonReader SHARED_READER = new JsonReader();
protected static JsonReader getReader() {
return SHARED_READER;
}
/**
* Read the JSON representation from supplied URL and construct the {@link Document} representation, using the
* {@link Charset#defaultCharset() default character set}.
*
* This method will read standard JSON and modified JSON, and tolerates whitespace and use of several delimeters, including
* the standard ':' as well as '=' and '=>'.
*
*
* @param url the URL of the JSON document; may not be null and must be resolvable
* @return the in-memory {@link Document} representation
* @throws ParsingException if there was a problem reading from the stream
*/
public static Document read( URL url ) throws ParsingException {
return SHARED_READER.read(url);
}
/**
* Read the JSON representation from supplied input stream and construct the {@link Document} representation, using the
* {@link Charset#defaultCharset() default character set}.
*
* This method will read standard JSON and modified JSON, and tolerates whitespace and use of several delimeters, including
* the standard ':' as well as '=' and '=>'.
*
*
* @param stream the input stream; may not be null
* @return the in-memory {@link Document} representation
* @throws ParsingException if there was a problem reading from the stream
*/
public static Document read( InputStream stream ) throws ParsingException {
return SHARED_READER.read(stream);
}
/**
* Read the JSON representation from supplied input stream and construct the {@link Document} representation, using the
* {@link Charset#defaultCharset() default character set}.
*
* This method will read standard JSON and modified JSON, and tolerates whitespace and use of several delimeters, including
* the standard ':' as well as '=' and '=>'.
*
*
* @param stream the input stream; may not be null
* @param introspectStringValues true if the string values should be examined for common patterns, or false otherwise
*
* @return the in-memory {@link Document} representation
* @throws ParsingException if there was a problem reading from the stream
*/
public static Document read( InputStream stream, boolean introspectStringValues ) throws ParsingException {
return SHARED_READER.read(stream, introspectStringValues);
}
/**
* Read the JSON representation from supplied input stream and construct the {@link Document} representation, using the
* supplied {@link Charset character set}.
*
* This method will read standard JSON and modified JSON, and tolerates whitespace and use of several delimeters, including
* the standard ':' as well as '=' and '=>'.
*
*
* @param stream the input stream; may not be null
* @param charset the character set that should be used; may not be null
* @return the in-memory {@link Document} representation
* @throws ParsingException if there was a problem reading from the stream
*/
public static Document read( InputStream stream,
Charset charset ) throws ParsingException {
return SHARED_READER.read(stream, charset);
}
/**
* Read the JSON representation from supplied input stream and construct the {@link Document} representation.
*
* This method will read standard JSON and modified JSON, and tolerates whitespace and use of several delimeters, including
* the standard ':' as well as '=' and '=>'.
*
*
* @param reader the IO reader; may not be null
* @return the in-memory {@link Document} representation
* @throws ParsingException if there was a problem reading from the stream
*/
public static Document read( Reader reader ) throws ParsingException {
return SHARED_READER.read(reader);
}
/**
* Read the supplied JSON representation and construct the {@link Document} representation.
*
* This method will read standard JSON and modified JSON, and tolerates whitespace and use of several delimeters, including
* the standard ':' as well as '=' and '=>'.
*
*
* @param json the JSON document string; may not be null
* @return the in-memory {@link Document} representation
* @throws ParsingException if there was a problem reading from the stream
*/
public static Document read( String json ) throws ParsingException {
return SHARED_READER.read(json);
}
/**
* Return a {@link DocumentSequence} that can be used to pull multiple documents from the stream.
*
* @param introspectStringValues true if the string values should be examined for common patterns, or false otherwise
* @param stream the input stream; may not be null
* @return the sequence that can be used to get one or more Document instances from a single input
*/
public static DocumentSequence readMultiple( InputStream stream, boolean introspectStringValues ) {
return SHARED_READER.readMultiple(stream, introspectStringValues);
}
/**
* Return a {@link DocumentSequence} that can be used to pull multiple documents from the stream.
*
* @param reader the IO reader; may not be null
* @return the sequence that can be used to get one or more Document instances from a single input
*/
public static DocumentSequence readMultiple( Reader reader ) {
return SHARED_READER.readMultiple(reader);
}
/**
* Return the modified JSON representation for the supplied in-memory {@link Document}. The resulting JSON will have no
* embedded line feeds or extra spaces.
*
* This format is compact and easy for software to read, but usually very difficult for people to read anything but very small
* documents.
*
*
* @param bson the BSON object or BSON value; may not be null
* @return the string; may not be null
*/
public static String write( Document bson ) {
return getCompactJsonWriter().write(bson);
}
/**
* Return the modified JSON representation for the supplied object value. The resulting JSON will have no embedded line feeds
* or extra spaces.
*
* This format is compact and easy for software to read, but usually very difficult for people to read anything but very small
* documents.
*
*
* @param value the BSON object or BSON value; may not be null
* @return the string; may not be null
*/
public static String write( Object value ) {
return getCompactJsonWriter().write(value);
}
/**
* Write to the supplied writer the modified JSON representation of the supplied in-memory {@link Document}. The resulting
* JSON will have no embedded line feeds or extra spaces.
*
* This format is compact and easy for software to read, but usually very difficult for people to read anything but very small
* documents.
*
*
* @param bson the BSON object or BSON value; may not be null
* @param writer the writer; may not be null
* @throws IOException if there was a problem reading from the stream
*/
public static void write( Document bson,
Writer writer ) throws IOException {
getCompactJsonWriter().write(bson, writer);
}
/**
* Write to the supplied writer the modified JSON representation of the supplied in-memory {@link Document}. The resulting
* JSON will have no embedded line feeds or extra spaces.
*
* This format is compact and easy for software to read, but usually very difficult for people to read anything but very small
* documents.
*
*
* @param bson the BSON object or BSON value; may not be null
* @param stream the output stream; may not be null
* @throws IOException if there was a problem reading from the stream
*/
public static void write( Document bson,
OutputStream stream ) throws IOException {
getCompactJsonWriter().write(bson, stream);
}
/**
* Return the modified JSON representation for the supplied in-memory {@link Document}. The resulting JSON will be indented
* for each name/value pair and each array value.
*
* This format is very readable by people and software, but is less compact due to the extra whitespace.
*
*
* @param bson the BSON object or BSON value; may not be null
* @return the JSON representation; never null
*/
public static String writePretty( Document bson ) {
return getPrettyWriter().write(bson);
}
/**
* Return the modified JSON representation for the supplied object value. The resulting JSON will be indented for each
* name/value pair and each array value.
*
* This format is very readable by people and software, but is less compact due to the extra whitespace.
*
*
* @param value the BSON object or BSON value; may not be null
* @return the JSON representation; never null
*/
public static String writePretty( Object value ) {
return getPrettyWriter().write(value);
}
/**
* Write to the supplied writer the modified JSON representation of the supplied in-memory {@link Document}. The resulting
* JSON will be indented for each name/value pair and each array value.
*
* This format is very readable by people and software, but is less compact due to the extra whitespace.
*
*
* @param bson the BSON object or BSON value; may not be null
* @param writer the writer; may not be null
* @throws IOException if there was a problem reading from the stream
*/
public static void writePretty( Document bson,
Writer writer ) throws IOException {
getPrettyWriter().write(bson, writer);
}
/**
* Write to the supplied writer the modified JSON representation of the supplied in-memory {@link Document}. The resulting
* JSON will be indented for each name/value pair and each array value.
*
* This format is very readable by people and software, but is less compact due to the extra whitespace.
*
*
* @param bson the BSON object or BSON value; may not be null
* @param stream the output stream; may not be null
* @throws IOException if there was a problem reading from the stream
*/
public static void writePretty( Document bson,
OutputStream stream ) throws IOException {
getPrettyWriter().write(bson, stream);
}
}