/**
* Copyright (C) 2012 10gen Inc.
*
* 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 com.mongodb.util;
import com.mongodb.*;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.bson.types.*;
public class BSONSerializerFactory {
public BSONSerializerFactory() {
}
public static BSONObjectSerializer buildLegacyBSONSerializer() {
BSONObjectSerializer serializer = new BSONObjectSerializer();
serializer.addObjectSerializer(byte[].class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
buf.append("<Binary Data>");
}
});
serializer.addObjectSerializer(Object[].class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
buf.append("[ ");
for (int i = 0; i < Array.getLength(obj); i++) {
if (i > 0)
buf.append(" , ");
serializer.serialize(Array.get(obj, i), buf);
}
buf.append("]");
}
});
serializer.addObjectSerializer(Binary.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
buf.append("<Binary Data>");
}
});
serializer.addObjectSerializer(Boolean.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
buf.append(obj.toString());
}
});
serializer.addObjectSerializer(BSONTimestamp.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
BSONTimestamp t = (BSONTimestamp) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$ts", Integer.valueOf(t.getTime()));
temp.put("$inc", Integer.valueOf(t.getInc()));
serializer.serialize(temp, buf);
}
});
serializer.addObjectSerializer(byte[].class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
buf.append("<Binary Data>");
}
});
serializer.addObjectSerializer(Code.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
Code c = (Code) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$code", c.getCode());
serializer.serialize(temp, buf);
}
});
serializer.addObjectSerializer(CodeWScope.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
CodeWScope c = (CodeWScope) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$code", c.getCode());
temp.put("$scope", c.getScope());
serializer.serialize(temp, buf);
}
});
serializer.addObjectSerializer(Date.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
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")));
serializer.serialize(
new BasicDBObject("$date", format.format(d)),
buf);
}
});
serializer.addObjectSerializer(DBObject.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
boolean first = true;
buf.append("{ ");
DBObject dbo = (DBObject) obj;
String name;
Iterator<String> it = dbo.keySet().iterator();
while (it.hasNext() ){
name = it.next();
if (first)
first = false;
else
buf.append(" , ");
JSON.string(buf, name);
buf.append(" : ");
serializer.serialize(dbo.get(name), buf);
}
buf.append("}");
}
});
serializer.addObjectSerializer(DBRefBase.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
DBRefBase ref = (DBRefBase) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$ref", ref.getRef());
temp.put("$id", ref.getId());
serializer.serialize(temp, buf);
}
});
serializer.addObjectSerializer(Iterable.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
boolean first = true;
buf.append("[ ");
Iterator it = ((Iterable) obj).iterator();
while ( it.hasNext() ) {
if (first)
first = false;
else
buf.append(" , ");
serializer.serialize(it.next(), buf);
}
buf.append("]");
}
});
serializer.addObjectSerializer(Map.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
boolean first = true;
buf.append("{ ");
Map m = (Map) obj;
Entry entry;
Iterator it = m.entrySet().iterator();
while ( it.hasNext()) {
entry = (Entry) it.next();
if (first)
first = false;
else
buf.append(" , ");
JSON.string(buf, entry.getKey().toString());
buf.append(" : ");
serializer.serialize(entry.getValue(), buf);
}
buf.append("}");
}
});
serializer.addObjectSerializer(MaxKey.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
serializer.serialize(new BasicDBObject("$maxKey",
Integer.valueOf(1)), buf);
}
});
serializer.addObjectSerializer(MinKey.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
serializer.serialize(new BasicDBObject("$minKey",
Integer.valueOf(1)), buf);
}
});
serializer.addObjectSerializer(Number.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
buf.append(obj.toString());
}
});
serializer.addObjectSerializer(ObjectId.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
serializer.serialize(
new BasicDBObject("$oid", obj.toString()), buf);
}
});
serializer.addObjectSerializer(Pattern.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
DBObject externalForm = new BasicDBObject();
externalForm.put("$regex", obj.toString());
if (((Pattern) obj).flags() != 0)
externalForm.put("$options",
Bytes.regexFlags(((Pattern) obj).flags()));
serializer.serialize(externalForm, buf);
}
});
serializer.addObjectSerializer(String.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
JSON.string(buf, (String) obj);
}
});
serializer.addObjectSerializer(UUID.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
UUID uuid = (UUID) obj;
BasicDBObject temp = new BasicDBObject();
temp.put("$uuid", uuid.toString());
serializer.serialize(temp, buf);
}
});
return serializer;
}
public static BSONObjectSerializer buildStrictBSONSerializer() {
BSONObjectSerializer serializer = buildLegacyBSONSerializer();
serializer.addObjectSerializer(Binary.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
Binary bin = (Binary) obj;
DBObject temp = new BasicDBObject();
temp.put("$binary",
(new Base64Codec()).encode(bin.getData()));
temp.put("$type", Byte.valueOf(bin.getType()));
serializer.serialize(temp, buf);
}
});
serializer.addObjectSerializer(BSONTimestamp.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
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);
serializer.serialize(timestampObj, buf);
}
});
serializer.addObjectSerializer(byte[].class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
DBObject temp = new BasicDBObject();
temp.put("$binary", (new Base64Codec()).encode((byte[]) obj));
temp.put("$type", Byte.valueOf((byte) 0));
serializer.serialize(temp, buf);
}
});
serializer.addObjectSerializer(Date.class,
new BSONObjectSerializer.ObjectSerializer() {
@Override
public void serialize(Object obj,
BSONObjectSerializer serializer, StringBuilder buf) {
Date d = (Date) obj;
serializer.serialize(
new BasicDBObject("$date", Long.valueOf(d.getTime() / 1000L)), buf);
}
});
return serializer;
}
}