Skip to content

Commit

Permalink
Merge branch 'master' of git@github.com:mongodb/mongo-java-driver
Browse files Browse the repository at this point in the history
  • Loading branch information
erh committed May 14, 2010
2 parents bcfd702 + 63263a3 commit 96ca9e4
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 33 deletions.
6 changes: 3 additions & 3 deletions src/main/com/mongodb/DBCallback.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ public void objectStart(boolean array, String name){
super.objectStart( array , name );
}

public BSONObject objectDone(){
BSONObject o = super.objectDone();
public Object objectDone(){
BSONObject o = (BSONObject)super.objectDone();
if ( ! _lastArray &&
o.containsKey( "$ref" ) &&
o.containsKey( "$id" ) ){
cur().put( _lastName , new DBRef( _db , o ) );
o = (BSONObject)cur().put( _lastName , new DBRef( _db, o ) );
}

return o;
Expand Down
107 changes: 93 additions & 14 deletions src/main/com/mongodb/util/JSON.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.mongodb.util;

import com.mongodb.*;
import org.bson.*;
import org.bson.types.*;

import java.text.*;
Expand Down Expand Up @@ -194,11 +195,21 @@ public static void serialize( Object o , StringBuilder buf ){
* @return DBObject the object
*/
public static Object parse( String s ){
return parse( s, null );
}

/**
* Parses a JSON string into a DBObject.
*
* @param s the string to serialize
* @return DBObject the object
*/
public static Object parse( String s, BSONCallback c ){
if (s == null || (s=s.trim()).equals("")) {
return (DBObject)null;
}

JSONParser p = new JSONParser(s);
JSONParser p = new JSONParser(s, c);
return p.parse();
}

Expand All @@ -215,12 +226,21 @@ class JSONParser {

String s;
int pos = 0;
BSONCallback _callback;

/**
* Create a new parser.
*/
public JSONParser(String s) {
this(s, null);
}

/**
* Create a new parser.
*/
public JSONParser(String s, BSONCallback callback) {
this.s = s;
_callback = (callback == null) ? new JSONCallback() : callback;
}


Expand All @@ -231,13 +251,24 @@ public JSONParser(String s) {
* @throws JSONParseException if invalid JSON is found
*/
public Object parse() {
return parse(null);
}

/**
* Parse an unknown type.
*
* @return Object the next item
* @throws JSONParseException if invalid JSON is found
*/
protected Object parse(String name) {
Object value = null;
char current = get();

switch(current) {
// null
case 'n':
read('n'); read('u'); read('l'); read('l');
value = null;
break;
// true
case 't':
Expand All @@ -261,11 +292,11 @@ public Object parse() {
break;
// array
case '[':
value = parseArray();
value = parseArray(name);
break;
// object
case '{':
value = parseObject();
value = parseObject(name);
break;
case '/':
value = parsePatter();
Expand All @@ -282,17 +313,30 @@ public Object parse() {
* @return DBObject the next object
* @throws JSONParseException if invalid JSON is found
*/
public DBObject parseObject() {
DBObject obj = new BasicDBObject();
read('{');
public Object parseObject() {
return parseObject(null);
}

/**
* Parses an object for the form <i>{}</i> and <i>{ members }</i>.
*
* @return DBObject the next object
* @throws JSONParseException if invalid JSON is found
*/
protected Object parseObject(String name){
if (name != null) {
_callback.objectStart(name);
} else {
_callback.objectStart();
}

read('{');
char current = get();
while(get() != '}') {
String key = parseString();
read(':');
Object value = parse();

obj.put(key, value);
Object value = parse(key);
doCallback(key, value);

if((current = get()) == ',') {
read(',');
Expand All @@ -303,9 +347,25 @@ public DBObject parseObject() {
}
read('}');

return obj;
return _callback.objectDone();
}

protected void doCallback(String name, Object value) {
if (value == null) {
_callback.gotNull(name);
} else if (value instanceof String) {
_callback.gotString(name, (String)value);
} else if (value instanceof Boolean) {
_callback.gotBoolean(name, (Boolean)value);
} else if (value instanceof Integer) {
_callback.gotInt(name, (Integer)value);
} else if (value instanceof Long) {
_callback.gotLong(name, (Long)value);
} else if (value instanceof Double) {
_callback.gotDouble(name, (Double)value);
}
}
// XXX kill parsePattern?
public Pattern parsePatter(){
read( '/' );

Expand Down Expand Up @@ -540,13 +600,31 @@ public void parseFraction() {
* @return the array
* @throws JSONParseException if invalid JSON is found
*/
public List parseArray() {
public Object parseArray() {
return parseArray(null);
}

/**
* Parses the next array.
*
* @return the array
* @throws JSONParseException if invalid JSON is found
*/
protected Object parseArray(String name) {
if (name != null) {
_callback.arrayStart(name);
} else {
_callback.arrayStart();
}

read('[');
List list = new ArrayList();

int i = 0;
char current = get();
while( current != ']' ) {
list.add(parse());
String elemName = "" + i++;
Object elem = parse(elemName);
doCallback(elemName, elem);

if((current = get()) == ',') {
read(',');
Expand All @@ -560,7 +638,8 @@ else if(current == ']') {
}

read(']');
return list;

return _callback.arrayDone();
}

}
Expand Down
70 changes: 70 additions & 0 deletions src/main/com/mongodb/util/JSONCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// JSONCallback.java

package com.mongodb.util;

import java.text.*;
import java.util.*;
import java.util.logging.*;
import java.util.regex.*;

import org.bson.*;
import org.bson.types.*;
import com.mongodb.*;

public class JSONCallback extends BasicBSONCallback {

public BSONObject create(){
return new BasicDBObject();
}

public BSONObject create( boolean array , List<String> path ){
if ( array )
return new BasicDBList();
return new BasicDBObject();
}

public void objectStart(boolean array, String name){
_lastName = name;
_lastArray = array;
super.objectStart( array , name );
}

public Object objectDone(){
Object o = super.objectDone();
BSONObject b = (BSONObject)o;

if ( ! _lastArray ) {
if ( b.containsKey( "$oid" ) ) {
o = new ObjectId((String)b.get("$oid"));
if (!isStackEmpty()) {
gotObjectId( _lastName, (ObjectId)o);
} else {
setRoot(o);
}
} else if ( b.containsKey( "$date" ) ) {
SimpleDateFormat format =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
o = format.parse((String)b.get("$date"), new ParsePosition(0));
if (!isStackEmpty()) {
cur().put( _lastName, o );
} else {
setRoot(o);
}
} else if ( b.containsKey( "$regex" ) ) {
o = Pattern.compile( (String)b.get( "$regex" ),
BSON.regexFlags( (String)b.get( "$options" )) );
if (!isStackEmpty()) {
cur().put( _lastName, o );
} else {
setRoot(o);
}
}
}

return o;
}

private String _lastName;
private boolean _lastArray = false;
}
5 changes: 3 additions & 2 deletions src/main/org/bson/BSONCallback.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ public interface BSONCallback {

void objectStart();
void objectStart(String name);
BSONObject objectDone();
Object objectDone();

void arrayStart();
void arrayStart(String name);
void arrayDone();
Object arrayDone();


void gotNull( String name );
Expand Down
2 changes: 1 addition & 1 deletion src/main/org/bson/BSONDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public BSONObject readObject( InputStream in )
throws IOException {
BasicBSONCallback c = new BasicBSONCallback();
decode( in , c );
return c.get();
return (BSONObject)c.get();
}

public int decode( byte[] b , BSONCallback callback ){
Expand Down
42 changes: 30 additions & 12 deletions src/main/org/bson/BasicBSONCallback.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ public BSONObject create( boolean array , List<String> path ){
}

public void objectStart(){
if ( _stack.size() > 0 )
throw new IllegalStateException( "something is wrong" );
_root = create();
_stack.add( _root );
if ( _stack.size() > 0 ) {
throw new IllegalStateException( "something is wrong" );
}
objectStart(false);
}

public void objectStart(boolean array){
_root = create(array, null);
_stack.add( (BSONObject)_root );
}

public void objectStart(String name){
Expand All @@ -41,21 +46,26 @@ public void objectStart(boolean array, String name){
_stack.addLast( o );
}

public BSONObject objectDone(){
public Object objectDone(){
BSONObject o =_stack.removeLast();
if ( _nameStack.size() > 0 )
_nameStack.removeLast();
else if ( _stack.size() > 0 )
throw new IllegalStateException( "something is wrong" );
else if ( _stack.size() > 0 ) {
throw new IllegalStateException( "something is wrong" );
}
return (BSONObject)BSON.applyDecodingHooks(o);
}

public void arrayStart(){
objectStart( true );
}

public void arrayStart(String name){
objectStart( true , name );
}

public void arrayDone(){
objectDone();
public Object arrayDone(){
return objectDone();
}

public void gotNull( String name ){
Expand Down Expand Up @@ -128,11 +138,19 @@ protected BSONObject cur(){
return _stack.getLast();
}

public BSONObject get(){
return _root;
public Object get(){
return _root;
}

private BSONObject _root;
protected void setRoot(Object o) {
_root = o;
}

protected boolean isStackEmpty() {
return _stack.size() < 1;
}

private Object _root;
private final LinkedList<BSONObject> _stack = new LinkedList<BSONObject>();
private final LinkedList<String> _nameStack = new LinkedList<String>();
}
Loading

0 comments on commit 96ca9e4

Please sign in to comment.