Created
October 3, 2015 21:21
-
-
Save dimzon/de35924ad5a38ef4ac78 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.dimzon.gson.gbson; | |
import com.google.gson.*; | |
import com.google.gson.internal.JsonReaderInternalAccess; | |
import com.google.gson.internal.bind.TypeAdapters; | |
import com.google.gson.stream.JsonReader; | |
import com.google.gson.stream.JsonToken; | |
import com.google.gson.stream.JsonWriter; | |
import com.mongodb.BasicDBList; | |
import com.mongodb.BasicDBObject; | |
import com.mongodb.DBObject; | |
import org.bson.BSONObject; | |
import org.bson.types.Binary; | |
import org.bson.types.ObjectId; | |
import sun.plugin.dom.exception.InvalidStateException; | |
import java.io.IOException; | |
import java.lang.reflect.Type; | |
import java.math.BigDecimal; | |
import java.math.BigInteger; | |
import java.nio.charset.StandardCharsets; | |
import java.util.*; | |
/** | |
* User: me | |
* Date: 03.10.15 | |
* Time: 1:33 | |
*/ | |
@SuppressWarnings("unused") | |
public final class Gbson { | |
static { | |
final JsonReaderInternalAccess previous = JsonReaderInternalAccess.INSTANCE; | |
JsonReaderInternalAccess.INSTANCE = new JsonReaderInternalAccess() { | |
@Override | |
public void promoteNameToValue(JsonReader jsonReader) throws IOException { | |
if (jsonReader instanceof MongoReader) { | |
((MongoReader) jsonReader).promoteNameToValue(); | |
return; | |
} | |
previous.promoteNameToValue(jsonReader); | |
} | |
}; | |
} | |
private final Gson gson; | |
private Gbson(Gson gson) { | |
this.gson = gson; | |
} | |
public static Gbson newInstance() { | |
return newBuilder().newGbison(); | |
} | |
public static Builder newBuilder() { | |
return new Builder(); | |
} | |
public <T> DBObject toBson(T src, Class<T> tClass) { | |
return toBson(src, (Type) tClass); | |
} | |
public DBObject toBson(Object src) { | |
if (src == null) return null; | |
return toBson(src, src.getClass()); | |
} | |
public DBObject toBson(Object src, Type typeOfSrc) throws JsonIOException { | |
if (src == null) return null; | |
MongoWriter w = new MongoWriter(); | |
gson.toJson(src, typeOfSrc, w); | |
return (DBObject) w.toObj(); | |
} | |
@SuppressWarnings("unchecked") | |
public <T> T fromBson(DBObject bson, Class<T> classOfT) throws JsonSyntaxException { | |
return (T) fromBson(bson, (Type) classOfT); | |
} | |
public Object fromBson(DBObject bson, Type typeOfT) throws JsonSyntaxException { | |
MongoReader r = new MongoReader(bson); | |
return gson.fromJson(r, typeOfT); | |
} | |
@SuppressWarnings("unused") | |
public static class Builder { | |
private final GsonBuilder gsonBuilder; | |
public Builder(GsonBuilder gsonBuilder) { | |
this.gsonBuilder = gsonBuilder; | |
Adapters.register(this); | |
} | |
public Builder() { | |
this(new GsonBuilder()); | |
} | |
public Gbson newGbison() { | |
return new Gbson(gsonBuilder.create()); | |
} | |
public Builder setVersion(double ignoreVersionsAfter) { | |
gsonBuilder.setVersion(ignoreVersionsAfter); | |
return this; | |
} | |
public Builder excludeFieldsWithModifiers(int... modifiers) { | |
gsonBuilder.excludeFieldsWithModifiers(modifiers); | |
return this; | |
} | |
public Builder excludeFieldsWithoutExposeAnnotation() { | |
gsonBuilder.excludeFieldsWithoutExposeAnnotation(); | |
return this; | |
} | |
public Builder enableComplexMapKeySerialization() { | |
gsonBuilder.enableComplexMapKeySerialization(); | |
return this; | |
} | |
public Builder disableInnerClassSerialization() { | |
gsonBuilder.disableInnerClassSerialization(); | |
return this; | |
} | |
public Builder setFieldNamingPolicy(FieldNamingPolicy namingConvention) { | |
gsonBuilder.setFieldNamingPolicy(namingConvention); | |
return this; | |
} | |
public Builder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) { | |
gsonBuilder.setFieldNamingStrategy(fieldNamingStrategy); | |
return this; | |
} | |
public Builder setExclusionStrategies(ExclusionStrategy... strategies) { | |
gsonBuilder.setExclusionStrategies(strategies); | |
return this; | |
} | |
public Builder addSerializationExclusionStrategy(ExclusionStrategy strategy) { | |
gsonBuilder.addSerializationExclusionStrategy(strategy); | |
return this; | |
} | |
public Builder addDeserializationExclusionStrategy(ExclusionStrategy strategy) { | |
gsonBuilder.addDeserializationExclusionStrategy(strategy); | |
return this; | |
} | |
public Builder registerTypeAdapter(Type type, Object typeAdapter) { | |
gsonBuilder.registerTypeAdapter(type, typeAdapter); | |
return this; | |
} | |
public Builder registerTypeAdapterFactory(TypeAdapterFactory factory) { | |
gsonBuilder.registerTypeAdapterFactory(factory); | |
return this; | |
} | |
public Builder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) { | |
gsonBuilder.registerTypeHierarchyAdapter(baseType, typeAdapter); | |
return this; | |
} | |
} | |
private static class Adapters { | |
final static TypeAdapter<Long> LONG_TYPE_ADAPTER = new TypeAdapter<Long>() { | |
@Override | |
public void write(JsonWriter jsonWriter, Long aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public Long read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Long) return ((Long) obj); | |
if (obj instanceof Number) return ((Number) obj).longValue(); | |
try { | |
return Long.parseLong(obj.toString()); | |
} catch (NumberFormatException ex) { | |
throw new JsonParseException(ex); | |
} | |
} | |
}; | |
final static TypeAdapterFactory LONG_FACTORY = TypeAdapters.newFactory(long.class, Long.class, LONG_TYPE_ADAPTER); | |
final static TypeAdapter<Integer> INT_TYPE_ADAPTER = new TypeAdapter<Integer>() { | |
@Override | |
public void write(JsonWriter jsonWriter, Integer aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public Integer read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Integer) return ((Integer) obj); | |
if (obj instanceof Number) return ((Number) obj).intValue(); | |
try { | |
return Integer.parseInt(obj.toString()); | |
} catch (NumberFormatException ex) { | |
throw new JsonParseException(ex); | |
} | |
} | |
}; | |
final static TypeAdapterFactory INT_FACTORY = TypeAdapters.newFactory(int.class, Integer.class, INT_TYPE_ADAPTER); | |
final static TypeAdapter<Short> SHORT_TYPE_ADAPTER = new TypeAdapter<Short>() { | |
@Override | |
public void write(JsonWriter jsonWriter, Short aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public Short read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Short) return ((Short) obj); | |
if (obj instanceof Number) return ((Number) obj).shortValue(); | |
try { | |
return Short.parseShort(obj.toString()); | |
} catch (NumberFormatException ex) { | |
throw new JsonParseException(ex); | |
} | |
} | |
}; | |
final static TypeAdapterFactory SHORT_FACTORY = TypeAdapters.newFactory(short.class, Short.class, SHORT_TYPE_ADAPTER); | |
final static TypeAdapter<Byte> BYTE_TYPE_ADAPTER = new TypeAdapter<Byte>() { | |
@Override | |
public void write(JsonWriter jsonWriter, Byte aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public Byte read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Byte) return ((Byte) obj); | |
if (obj instanceof Number) return ((Number) obj).byteValue(); | |
try { | |
return Byte.parseByte(obj.toString()); | |
} catch (NumberFormatException ex) { | |
throw new JsonParseException(ex); | |
} | |
} | |
}; | |
final static TypeAdapterFactory BYTE_FACTORY = TypeAdapters.newFactory(byte.class, Byte.class, BYTE_TYPE_ADAPTER); | |
final static TypeAdapter<Float> FLOAT_TYPE_ADAPTER = new TypeAdapter<Float>() { | |
@Override | |
public void write(JsonWriter jsonWriter, Float aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public Float read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Float) return ((Float) obj); | |
if (obj instanceof Number) return ((Number) obj).floatValue(); | |
try { | |
return Float.parseFloat(obj.toString()); | |
} catch (NumberFormatException ex) { | |
throw new JsonParseException(ex); | |
} | |
} | |
}; | |
final static TypeAdapterFactory FLOAT_FACTORY = TypeAdapters.newFactory(float.class, Float.class, FLOAT_TYPE_ADAPTER); | |
final static TypeAdapter<Double> DOUBLE_TYPE_ADAPTER = new TypeAdapter<Double>() { | |
@Override | |
public void write(JsonWriter jsonWriter, Double aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public Double read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Double) return ((Double) obj); | |
if (obj instanceof Number) return ((Number) obj).doubleValue(); | |
try { | |
return Double.parseDouble(obj.toString()); | |
} catch (NumberFormatException ex) { | |
throw new JsonParseException(ex); | |
} | |
} | |
}; | |
final static TypeAdapterFactory DOUBLE_FACTORY = TypeAdapters.newFactory(double.class, Double.class, DOUBLE_TYPE_ADAPTER); | |
final static TypeAdapter<Boolean> BOOLEAN_TYPE_ADAPTER = new TypeAdapter<Boolean>() { | |
@Override | |
public void write(JsonWriter jsonWriter, Boolean aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public Boolean read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Boolean) return ((Boolean) obj); | |
if (obj instanceof Number) return ((Number) obj).longValue() != 0; | |
return Boolean.parseBoolean(obj.toString()); | |
} | |
}; | |
final static TypeAdapterFactory BOOLEAN_FACTORY = TypeAdapters.newFactory(boolean.class, Boolean.class, BOOLEAN_TYPE_ADAPTER); | |
final static TypeAdapter<UUID> UUID_TYPE_ADAPTER = new TypeAdapter<UUID>() { | |
@Override | |
public void write(JsonWriter jsonWriter, UUID aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public UUID read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof UUID) return ((UUID) obj); | |
return UUID.fromString(obj.toString()); | |
} | |
}; | |
final static TypeAdapterFactory UUID_FACTORY = TypeAdapters.newFactory(UUID.class, UUID_TYPE_ADAPTER); | |
final static TypeAdapter<byte[]> BINARY_TYPE_ADAPTER = new TypeAdapter<byte[]>() { | |
@Override | |
public void write(JsonWriter jsonWriter, byte[] aLong) throws IOException { | |
if (aLong == null) { | |
jsonWriter.nullValue(); | |
return; | |
} | |
((MongoWriter) jsonWriter).put(new Binary(aLong)); | |
} | |
@Override | |
public byte[] read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Binary) return ((Binary) obj).getData(); | |
return obj.toString().getBytes(StandardCharsets.UTF_8); | |
} | |
}; | |
final static TypeAdapterFactory BINARY_FACTORY = TypeAdapters.newFactory(byte[].class, BINARY_TYPE_ADAPTER); | |
final static TypeAdapter<Binary> BINARY1_TYPE_ADAPTER = new TypeAdapter<Binary>() { | |
@Override | |
public void write(JsonWriter jsonWriter, Binary aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public Binary read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof Binary) return ((Binary) obj); | |
return new Binary(obj.toString().getBytes(StandardCharsets.UTF_8)); | |
} | |
}; | |
final static TypeAdapterFactory BINARY1_FACTORY = TypeAdapters.newFactory(Binary.class, BINARY1_TYPE_ADAPTER); | |
final static TypeAdapter<ObjectId> ID_TYPE_ADAPTER = new TypeAdapter<ObjectId>() { | |
@Override | |
public void write(JsonWriter jsonWriter, ObjectId aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public ObjectId read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof ObjectId) return ((ObjectId) obj); | |
if (obj instanceof Binary) return new ObjectId(((Binary) obj).getData()); | |
return new ObjectId(obj.toString()); | |
} | |
}; | |
final static TypeAdapterFactory ID_FACTORY = TypeAdapters.newFactory(ObjectId.class, ID_TYPE_ADAPTER); | |
final static TypeAdapter<BigDecimal> DECIMAL_TYPE_ADAPTER = new TypeAdapter<BigDecimal>() { | |
@Override | |
public void write(JsonWriter jsonWriter, BigDecimal aLong) throws IOException { | |
if (aLong == null) { | |
jsonWriter.nullValue(); | |
return; | |
} | |
((MongoWriter) jsonWriter).put(aLong.toString()); | |
} | |
@Override | |
public BigDecimal read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof BigDecimal) return (BigDecimal) obj; | |
if (obj instanceof String) return new BigDecimal((String) obj); | |
if (obj instanceof Long) return new BigDecimal((Long) obj); | |
if (obj instanceof Integer) return new BigDecimal((Integer) obj); | |
if (obj instanceof Double) return new BigDecimal((Double) obj); | |
return new BigDecimal(obj.toString()); | |
} | |
}; | |
final static TypeAdapterFactory DECIMAL_FACTORY = TypeAdapters.newFactory(BigDecimal.class, DECIMAL_TYPE_ADAPTER); | |
final static TypeAdapter<BigInteger> BIGINT_TYPE_ADAPTER = new TypeAdapter<BigInteger>() { | |
@Override | |
public void write(JsonWriter jsonWriter, BigInteger aLong) throws IOException { | |
if (aLong == null) { | |
jsonWriter.nullValue(); | |
return; | |
} | |
((MongoWriter) jsonWriter).put(aLong.toString()); | |
} | |
@Override | |
public BigInteger read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
if (obj == null) return null; | |
if (obj instanceof BigInteger) return (BigInteger) obj; | |
return new BigInteger(obj.toString()); | |
} | |
}; | |
final static TypeAdapterFactory BIGINT_FACTORY = TypeAdapters.newFactory(BigInteger.class, BIGINT_TYPE_ADAPTER); | |
final static TypeAdapter<java.util.Date> DATE_TYPE_ADAPTER = new TypeAdapter<java.util.Date>() { | |
@Override | |
public void write(JsonWriter jsonWriter, java.util.Date aLong) throws IOException { | |
((MongoWriter) jsonWriter).put(aLong); | |
} | |
@Override | |
public java.util.Date read(JsonReader jsonReader) throws IOException { | |
Object obj = ((MongoReader) jsonReader).nextObj(); | |
return (Date) obj; | |
} | |
}; | |
final static TypeAdapterFactory DATE_FACTORY = TypeAdapters.newFactory(Date.class, DATE_TYPE_ADAPTER); | |
public static void register(Builder builder) { | |
builder.registerTypeAdapterFactory(LONG_FACTORY); | |
builder.registerTypeAdapterFactory(INT_FACTORY); | |
builder.registerTypeAdapterFactory(SHORT_FACTORY); | |
builder.registerTypeAdapterFactory(BYTE_FACTORY); | |
builder.registerTypeAdapterFactory(FLOAT_FACTORY); | |
builder.registerTypeAdapterFactory(DOUBLE_FACTORY); | |
builder.registerTypeAdapterFactory(BOOLEAN_FACTORY); | |
builder.registerTypeAdapterFactory(UUID_FACTORY); | |
builder.registerTypeAdapterFactory(BINARY_FACTORY); | |
builder.registerTypeAdapterFactory(BINARY1_FACTORY); | |
builder.registerTypeAdapterFactory(ID_FACTORY); | |
builder.registerTypeAdapterFactory(DECIMAL_FACTORY); | |
builder.registerTypeAdapterFactory(BIGINT_FACTORY); | |
builder.registerTypeAdapterFactory(DATE_FACTORY); | |
//builder.registerTypeAdapter() | |
} | |
} | |
private static class MongoReader extends JsonReader { | |
private static final java.io.Reader NullReader = new java.io.Reader() { | |
@SuppressWarnings("NullableProblems") | |
@Override | |
public int read(char[] cbuf, int off, int len) throws IOException { | |
return 0; | |
} | |
@Override | |
public void close() throws IOException { | |
} | |
}; | |
private static final Object SENTINEL_CLOSED = new Object(); | |
private final List<Object> stack = new ArrayList<Object>(); | |
public MongoReader(DBObject basicDBObject) { | |
super(NullReader); | |
stack.add(basicDBObject); | |
} | |
public Object nextObj() throws IOException { | |
JsonToken peek = peek(); | |
if (peek == JsonToken.NULL || peek == JsonToken.BOOLEAN || peek == JsonToken.NUMBER || peek == JsonToken.STRING) | |
return popStack(); | |
throw new InvalidStateException("peek=" + peek); | |
} | |
@Override | |
public void beginArray() throws IOException { | |
expect(JsonToken.BEGIN_ARRAY); | |
JsonArray array = (JsonArray) peekStack(); | |
stack.add(array.iterator()); | |
} | |
@Override | |
public void endArray() throws IOException { | |
expect(JsonToken.END_ARRAY); | |
popStack(); // empty iterator | |
popStack(); // array | |
} | |
@Override | |
public void beginObject() throws IOException { | |
expect(JsonToken.BEGIN_OBJECT); | |
BSONObject object = (BSONObject) peekStack(); | |
if (object instanceof Map) { | |
stack.add(((Map) object).entrySet().iterator()); | |
} else { | |
stack.add(object.toMap().entrySet().iterator()); | |
} | |
} | |
@Override | |
public void endObject() throws IOException { | |
expect(JsonToken.END_OBJECT); | |
popStack(); // empty iterator | |
popStack(); // object | |
} | |
@Override | |
public boolean hasNext() throws IOException { | |
JsonToken token = peek(); | |
return token != JsonToken.END_OBJECT && token != JsonToken.END_ARRAY; | |
} | |
@Override | |
public JsonToken peek() throws IOException { | |
if (stack.isEmpty()) { | |
return JsonToken.END_DOCUMENT; | |
} | |
Object o = peekStack(); | |
if (o instanceof Iterator) { | |
boolean isObject = !(stack.get(stack.size() - 2) instanceof List); | |
Iterator<?> iterator = (Iterator<?>) o; | |
if (iterator.hasNext()) { | |
if (isObject) { | |
return JsonToken.NAME; | |
} else { | |
stack.add(iterator.next()); | |
return peek(); | |
} | |
} else { | |
return isObject ? JsonToken.END_OBJECT : JsonToken.END_ARRAY; | |
} | |
} else if (o instanceof List) { | |
return JsonToken.BEGIN_ARRAY; | |
} else if (o instanceof BSONObject) { | |
return JsonToken.BEGIN_OBJECT; | |
} else if (o instanceof Boolean) { | |
return JsonToken.BOOLEAN; | |
} else if (o instanceof Number) { | |
return JsonToken.NUMBER; | |
} else if (o == null) { | |
return JsonToken.NULL; | |
} else if (o == SENTINEL_CLOSED) { | |
throw new IllegalStateException("JsonReader is closed"); | |
} else { | |
return JsonToken.STRING; | |
} | |
} | |
private Object peekStack() { | |
return stack.get(stack.size() - 1); | |
} | |
private Object popStack() { | |
return stack.remove(stack.size() - 1); | |
} | |
private void expect(JsonToken expected) throws IOException { | |
if (peek() != expected) { | |
throw new IllegalStateException("Expected " + expected + " but was " + peek()); | |
} | |
} | |
@Override | |
public String nextName() throws IOException { | |
expect(JsonToken.NAME); | |
Iterator<?> i = (Iterator<?>) peekStack(); | |
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next(); | |
stack.add(entry.getValue()); | |
return (String) entry.getKey(); | |
} | |
@Override | |
public String nextString() throws IOException { | |
return nextObj().toString(); | |
} | |
@Override | |
public boolean nextBoolean() throws IOException { | |
expect(JsonToken.BOOLEAN); | |
return ((Boolean) popStack()); | |
} | |
@Override | |
public void nextNull() throws IOException { | |
expect(JsonToken.NULL); | |
popStack(); | |
} | |
@Override | |
public double nextDouble() throws IOException { | |
expect(JsonToken.NUMBER); | |
return ((Number) popStack()).doubleValue(); | |
} | |
@Override | |
public long nextLong() throws IOException { | |
expect(JsonToken.NUMBER); | |
return ((Number) popStack()).longValue(); | |
} | |
@Override | |
public int nextInt() throws IOException { | |
expect(JsonToken.NUMBER); | |
return ((Number) popStack()).intValue(); | |
} | |
@Override | |
public void close() throws IOException { | |
stack.clear(); | |
stack.add(SENTINEL_CLOSED); | |
} | |
@Override | |
public void skipValue() throws IOException { | |
if (peek() == JsonToken.NAME) { | |
nextName(); | |
} else { | |
popStack(); | |
} | |
} | |
@Override | |
public String toString() { | |
return getClass().getSimpleName(); | |
} | |
public void promoteNameToValue() throws IOException { | |
expect(JsonToken.NAME); | |
Iterator<?> i = (Iterator<?>) peekStack(); | |
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next(); | |
stack.add(entry.getValue()); | |
stack.add(entry.getKey()); | |
} | |
} | |
private static class MongoWriter extends JsonWriter { | |
private static final java.io.Writer NullWriter = new java.io.Writer() { | |
@SuppressWarnings("NullableProblems") | |
@Override | |
public void write(char[] buffer, int off, int len) throws IOException { | |
} | |
@Override | |
public void flush() throws IOException { | |
} | |
@Override | |
public void close() throws IOException { | |
} | |
}; | |
final ListAppender listAppender; | |
private final Stack<Appender> appenderStack = new Stack<Appender>(); | |
public MongoWriter() { | |
super(NullWriter); | |
appenderStack.push(listAppender = new ListAppender()); | |
} | |
public Object toObj() { | |
return listAppender.basicDBList.get(0); | |
} | |
@Override | |
public JsonWriter beginArray() throws IOException { | |
ListAppender appender = new ListAppender(); | |
appenderStack.peek().value(appender.basicDBList); | |
appenderStack.push(appender); | |
return this; | |
} | |
@Override | |
public JsonWriter endArray() throws IOException { | |
appenderStack.pop(); | |
return this; | |
} | |
@Override | |
public JsonWriter beginObject() throws IOException { | |
DocAppender appender = new DocAppender(); | |
appenderStack.peek().value(appender.basicDBObject); | |
appenderStack.push(appender); | |
return this; | |
} | |
@Override | |
public JsonWriter endObject() throws IOException { | |
appenderStack.pop(); | |
return this; | |
} | |
@Override | |
public JsonWriter name(String name) throws IOException { | |
((DocAppender) appenderStack.peek()).name = name; | |
return this; | |
} | |
@Override | |
public JsonWriter nullValue() throws IOException { | |
put(null); | |
return this; | |
} | |
@Override | |
public JsonWriter value(String value) throws IOException { | |
put(value); | |
return this; | |
} | |
@Override | |
public JsonWriter value(boolean value) throws IOException { | |
put(value); | |
return this; | |
} | |
@Override | |
public JsonWriter value(double value) throws IOException { | |
put(value); | |
return this; | |
} | |
@Override | |
public JsonWriter value(long value) throws IOException { | |
put(value); | |
return this; | |
} | |
@Override | |
public JsonWriter value(Number value) throws IOException { | |
put(value); | |
return this; | |
} | |
@Override | |
public void flush() throws IOException { | |
} | |
@Override | |
public void close() throws IOException { | |
} | |
@Override | |
public boolean isLenient() { | |
return true; | |
} | |
public void put(Object obj) { | |
appenderStack.peek().value(obj); | |
} | |
private static abstract class Appender { | |
public abstract void value(Object value); | |
} | |
private static class DocAppender extends Appender { | |
BasicDBObject basicDBObject = new BasicDBObject(); | |
String name; | |
@Override | |
public void value(Object value) { | |
basicDBObject.append(name, value); | |
} | |
} | |
private static class ListAppender extends Appender { | |
BasicDBList basicDBList = new BasicDBList(); | |
@Override | |
public void value(Object value) { | |
basicDBList.add(value); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment