michel-kraemer/bson4jackson — Issue #9: Field name lost when using JsonParser.readValueAsTree()
Author: audistard
Created: 2011-10-21 06:56:27+00:00
State: open

When reading am embedded object/document with JsonParser.readValueAsTree() the _nextToken is set to null which forces a new document in BsonParser.nextToken(). This in turn loses the field name of a following field. Try the test below. It will result in expecting a field_name but getting a start_object.

To fix, only start a new document in nextToken() if there is nether a _currentToken nor _contexts.peek(). See suggested patch at end of test code.

```java
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.JsonNode;
@Test
public void parseEmbeddedDocumentAsTree() throws Exception {
BSONObject o2 = new BasicBSONObject();
o2.put("Int64", 10L);

BSONObject o3 = new BasicBSONObject();
o3.put("Int64", 11L);

BSONObject o1 = new BasicBSONObject();
o1.put("Obj2", o2);
o1.put("Obj3", o3);

BSONEncoder enc = new BSONEncoder();
byte[] b = enc.encode(o1);

ByteArrayInputStream bais = new ByteArrayInputStream(b);
BsonFactory fac = new BsonFactory();
ObjectMapper mapper = new ObjectMapper(fac);
fac.setCodec(mapper);

BsonParser dec = fac.createJsonParser(bais);

assertEquals(JsonToken.START_OBJECT, dec.nextToken());

assertEquals(JsonToken.FIELD_NAME, dec.nextToken());
assertEquals("Obj2", dec.getCurrentName());
assertEquals(JsonToken.START_OBJECT, dec.nextToken());
JsonNode obj2 = dec.readValueAsTree();
assertEquals(1, obj2.size());
assertNotNull(obj2.get("Int64"));
assertEquals(10L, obj2.get("Int64").getValueAsLong());

assertEquals(JsonToken.FIELD_NAME, dec.nextToken());
assertEquals("Obj3", dec.getCurrentName());
assertEquals(JsonToken.START_OBJECT, dec.nextToken());

assertEquals(JsonToken.FIELD_NAME, dec.nextToken());
assertEquals("Int64", dec.getCurrentName());
assertEquals(JsonToken.VALUE_NUMBER_INT, dec.nextToken());
assertEquals(11L, dec.getLongValue());

assertEquals(JsonToken.END_OBJECT, dec.nextToken());

assertEquals(JsonToken.END_OBJECT, dec.nextToken());
}
```

```java
public JsonToken nextToken() throws IOException, JsonParseException {
Context ctx = _contexts.peek();
if (_currToken == null && ctx == null) {
_currToken = handleNewDocument(false);
} else {
_tokenPos = _counter.getPosition();
if (ctx == null) {
throw new JsonParseException("Found element outside the document", getTokenLocation());
}
...etc
```