package com.mongodb.jee.util;
import com.mongodb.BasicDBObject;
import com.mongodb.Bytes;
import com.mongodb.DBObject;
import com.mongodb.DBRefBase;
import com.mongodb.util.Base64Codec;
import org.bson.types.*;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
/**
* Defines static methods for getting ObjectSerializer
instances that produce various flavors of
* JSON.
*/
public class JSONSerializers {
private JSONSerializers() {
}
/**
* Returns an ObjectSerializer
that mostly conforms to the strict JSON format defined in
* getStrict in preference to this method.
*
* @return object serializer
* @see #getStrict()
*/
public static ObjectSerializer getLegacy() {
ClassMapBasedObjectSerializer serializer = addCommonSerializers();
serializer.addObjectSerializer(Date.class, new LegacyDateSerializer(serializer));
serializer.addObjectSerializer(BSONTimestamp.class, new LegacyBSONTimestampSerializer(serializer));
serializer.addObjectSerializer(Binary.class, new LegacyBinarySerializer());
serializer.addObjectSerializer(byte[].class, new LegacyBinarySerializer());
return serializer;
}
/**
* Returns an ObjectSerializer
that conforms to the strict JSON format defined in
* ", writer, out);
}
}
private static class ObjectArraySerializer extends CompoundObjectSerializer {
ObjectArraySerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
JSON.append("[ ", writer, out);
for (int i = 0; i < Array.getLength(obj); i++) {
if (i > 0)
JSON.append(" , ", writer, out);
JSON.serialize(serializer, Array.get(obj, i), writer, out);
}
JSON.append("]", writer, out);
}
}
private static class ToStringSerializer extends AbstractObjectSerializer {
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
JSON.append(obj.toString(), writer, out);
}
}
private static class LegacyBSONTimestampSerializer extends CompoundObjectSerializer {
LegacyBSONTimestampSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
BSONTimestamp t = (BSONTimestamp) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$ts", Integer.valueOf(t.getTime()));
temp.put("$inc", Integer.valueOf(t.getInc()));
JSON.serialize(serializer, temp, writer, out);
}
}
private static class CodeSerializer extends CompoundObjectSerializer {
CodeSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
Code c = (Code) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$code", c.getCode());
JSON.serialize(serializer, temp, writer, out);
}
}
private static class CodeWScopeSerializer extends CompoundObjectSerializer {
CodeWScopeSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
CodeWScope c = (CodeWScope) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$code", c.getCode());
temp.put("$scope", c.getScope());
JSON.serialize(serializer, temp, writer, out);
}
}
private static class LegacyDateSerializer extends CompoundObjectSerializer {
LegacyDateSerializer(ClassMapBasedObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
Date d = (Date) obj;
SimpleDateFormat format = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
format.setCalendar(new GregorianCalendar(
new SimpleTimeZone(0, "GMT")));
JSON.serialize(serializer,
new BasicDBObject("$date", format.format(d)), writer, out);
}
}
private static class DBObjectSerializer extends CompoundObjectSerializer {
DBObjectSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
boolean first = true;
JSON.append("{ ", writer, out);
DBObject dbo = (DBObject) obj;
String name;
for (final String s : dbo.keySet()) {
name = s;
if (first)
first = false;
else
JSON.append(" , ", writer, out);
JSON.string(name, writer, out);
JSON.append(" : ", writer, out);
JSON.serialize(serializer, dbo.get(name), writer, out);
}
JSON.append("}", writer, out);
}
}
private static class DBRefBaseSerializer extends CompoundObjectSerializer {
DBRefBaseSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
DBRefBase ref = (DBRefBase) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$ref", ref.getRef());
temp.put("$id", ref.getId());
JSON.serialize(serializer, temp, writer, out);
}
}
private static class IterableSerializer extends CompoundObjectSerializer {
IterableSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
boolean first = true;
JSON.append("[ ", writer, out);
for (final Object o : ((Iterable) obj)) {
if (first)
first = false;
else
JSON.append(" , ", writer, out);
JSON.serialize(serializer,o, writer, out);
}
JSON.append("]", writer, out);
}
}
private static class MapSerializer extends CompoundObjectSerializer {
MapSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
boolean first = true;
JSON.append("{ ", writer, out);
Map m = (Map) obj;
Entry entry;
for (final Object o : m.entrySet()) {
entry = (Entry) o;
if (first)
first = false;
else
JSON.append(" , ", writer, out);
JSON.string(entry.getKey().toString(), writer, out);
JSON.append(" : ", writer, out);
JSON.serialize(serializer, entry.getValue(), writer, out);
}
JSON.append("}", writer, out);
}
}
private static class MaxKeySerializer extends CompoundObjectSerializer {
MaxKeySerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
JSON.serialize(serializer, new BasicDBObject("$maxKey",
1), writer, out);
}
}
private static class MinKeySerializer extends CompoundObjectSerializer {
MinKeySerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
JSON.serialize(serializer, new BasicDBObject("$minKey",
1), writer, out);
}
}
private static class ObjectIdSerializer extends CompoundObjectSerializer {
ObjectIdSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
JSON.serialize(serializer,
new BasicDBObject("$oid", obj.toString()), writer, out);
}
}
private static class PatternSerializer extends CompoundObjectSerializer {
PatternSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
DBObject externalForm = new BasicDBObject();
externalForm.put("$regex", obj.toString());
if (((Pattern) obj).flags() != 0)
externalForm.put("$options",
Bytes.regexFlags(((Pattern) obj).flags()));
JSON.serialize(serializer, externalForm, writer, out);
}
}
private static class StringSerializer extends AbstractObjectSerializer {
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
JSON.string((String) obj, writer, out);
}
}
private static class UUIDSerializer extends CompoundObjectSerializer {
UUIDSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
UUID uuid = (UUID) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$uuid", uuid.toString());
JSON.serialize(serializer,temp, writer, out);
}
}
private static class BSONTimestampSerializer extends CompoundObjectSerializer {
BSONTimestampSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
BSONTimestamp t = (BSONTimestamp) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$t", Integer.valueOf(t.getTime()));
temp.put("$i", Integer.valueOf(t.getInc()));
BasicDBObject timestampObj = new BasicDBObject();
timestampObj.put("$timestamp", temp);
JSON.serialize(serializer, timestampObj, writer, out);
}
}
private static class DateSerializer extends CompoundObjectSerializer {
DateSerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
Date d = (Date) obj;
JSON.serialize(serializer,
new BasicDBObject("$date", d.getTime()), writer, out);
}
}
private abstract static class BinarySerializerBase extends CompoundObjectSerializer {
BinarySerializerBase(ObjectSerializer serializer) {
super(serializer);
}
protected void serialize(byte[] bytes, byte type, Writer writer, OutputStream out) throws IOException {
DBObject temp = new BasicDBObject();
temp.put("$binary",
(new Base64Codec()).encode(bytes));
temp.put("$type", type);
JSON.serialize(serializer, temp, writer, out);
}
}
private static class BinarySerializer extends BinarySerializerBase {
BinarySerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
Binary bin = (Binary) obj;
serialize(bin.getData(), bin.getType(), writer, out);
}
}
private static class ByteArraySerializer extends BinarySerializerBase {
ByteArraySerializer(ObjectSerializer serializer) {
super(serializer);
}
@Override
protected void serialize(Object obj, Writer writer, OutputStream out)
throws IOException {
serialize((byte[]) obj, (byte) 0, writer, out);
}
}
}