Issue 513 - get rid of exception at end of import in JSON parser

git-svn-id: http://google-refine.googlecode.com/svn/trunk@2435 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
Tom Morris 2012-01-27 17:05:45 +00:00
parent ca2afc1dc1
commit 40183aa0ba

View File

@ -1,6 +1,6 @@
/* /*
Copyright 2010, Google Inc. Copyright 2010,2012 Google Inc.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -205,15 +205,17 @@ public class JsonImporter extends TreeImportingParserBase {
JsonFactory factory = new JsonFactory(); JsonFactory factory = new JsonFactory();
JsonParser parser = null; JsonParser parser = null;
//The following is a workaround for inconsistent Jackson JsonParser private JsonToken current = null;
Boolean lastTokenWasAFieldNameAndCurrentTokenIsANewEntity = false; private JsonToken next = null;
Boolean thisTokenIsAFieldName = false; private String fieldName = ANONYMOUS;
String lastFieldName = null; private String fieldValue = null;
//end of workaround
public JSONTreeReader(Reader reader) { public JSONTreeReader(Reader reader) {
try { try {
parser = factory.createJsonParser(reader); parser = factory.createJsonParser(reader);
current = null;
next = parser.nextToken();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -253,33 +255,16 @@ public class JsonImporter extends TreeImportingParserBase {
@Override @Override
public Token current() { public Token current() {
return this.mapToToken(parser.getCurrentToken()); if (current != null) {
return this.mapToToken(current);
} else {
return null;
}
} }
@Override @Override
public String getFieldName() throws TreeReaderException { public String getFieldName() throws TreeReaderException {
try { return fieldName;
String text = parser.getCurrentName();
/*
* If current token is a JsonToken.FIELD_NAME, this will be the
* same as what getText() returns; for field values it will be
* preceding field name; and for others (array values,
* root-level values) null.
*/
//The following is a workaround for inconsistent Jackson JsonParser
if(text == null){
if(this.lastTokenWasAFieldNameAndCurrentTokenIsANewEntity) {
text = this.lastFieldName;
} else {
text = ANONYMOUS;
}
}
//end of workaround
return text;
} catch (IOException e) {
throw new TreeReaderException(e);
}
} }
/** /**
@ -292,57 +277,42 @@ public class JsonImporter extends TreeImportingParserBase {
@Override @Override
public String getFieldValue() throws TreeReaderException { public String getFieldValue() throws TreeReaderException {
try { return fieldValue;
return parser.getText();
} catch (IOException e) {
throw new TreeReaderException(e);
}
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return true; //FIXME fairly obtuse, is there a better way (advancing, then rewinding?) return next != null;
} }
@Override @Override
public Token next() throws TreeReaderException { public Token next() throws TreeReaderException {
JsonToken next; JsonToken previous = current;
current = next;
next = null; // in case an exception is thrown
try { try {
if (current != null) {
if (current.isScalarValue()) {
fieldValue = parser.getText();
} else {
fieldValue = null;
}
if (current == JsonToken.FIELD_NAME) {
fieldName = parser.getText();
} else if (current == JsonToken.START_ARRAY
|| current == JsonToken.START_OBJECT) {
// Use current field name for next level object
// ie elide one level of anonymous fields
if (previous != JsonToken.FIELD_NAME) {
fieldName = ANONYMOUS;
}
}
}
next = parser.nextToken(); next = parser.nextToken();
} catch (JsonParseException e) {
throw new TreeReaderException(e);
} catch (IOException e) { } catch (IOException e) {
throw new TreeReaderException(e); throw new TreeReaderException(e);
} }
return current();
if(next == null) {
throw new TreeReaderException("No more Json Tokens in stream");
}
//The following is a workaround for inconsistent Jackson JsonParser
if(next == JsonToken.FIELD_NAME){
try {
this.thisTokenIsAFieldName = true;
this.lastFieldName = parser.getCurrentName();
} catch (IOException e) {
//silent
}
}else if(next == JsonToken.START_ARRAY || next == JsonToken.START_OBJECT){
if(this.thisTokenIsAFieldName){
this.lastTokenWasAFieldNameAndCurrentTokenIsANewEntity = true;
this.thisTokenIsAFieldName = false;
}else{
this.lastTokenWasAFieldNameAndCurrentTokenIsANewEntity = false;
this.lastFieldName = null;
}
}else{
this.lastTokenWasAFieldNameAndCurrentTokenIsANewEntity = false;
this.lastFieldName = null;
this.thisTokenIsAFieldName = false;
}
//end of workaround
return mapToToken(next);
} }
protected Token mapToToken(JsonToken token){ protected Token mapToToken(JsonToken token){