Jackson deserialization for Recon

This commit is contained in:
Antonin Delpeuch 2018-10-21 18:35:23 +01:00
parent ba7879621d
commit d4bdd37bda
8 changed files with 59 additions and 119 deletions

View File

@ -46,13 +46,10 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.google.refine.expr.HasFields; import com.google.refine.expr.HasFields;
import com.google.refine.util.JsonViews; import com.google.refine.util.JsonViews;
import com.google.refine.util.Pool; import com.google.refine.util.ParsingUtilities;
@JsonFilter("reconCandidateFilter") @JsonFilter("reconCandidateFilter")
public class Recon implements HasFields { public class Recon implements HasFields {
@ -111,20 +108,32 @@ public class Recon implements HasFields {
s_featureMap.put("nameWordDistance", Feature_nameWordDistance); s_featureMap.put("nameWordDistance", Feature_nameWordDistance);
} }
@JsonIgnore
final public long id; final public long id;
@JsonIgnore
public String service = "unknown"; public String service = "unknown";
@JsonIgnore
public String identifierSpace = null; public String identifierSpace = null;
@JsonIgnore
public String schemaSpace = null; public String schemaSpace = null;
@JsonIgnore
public Object[] features = new Object[Feature_max]; public Object[] features = new Object[Feature_max];
@JsonIgnore
public List<ReconCandidate> candidates; public List<ReconCandidate> candidates;
@JsonIgnore
public Judgment judgment = Judgment.None; public Judgment judgment = Judgment.None;
@JsonIgnore
public String judgmentAction = "unknown"; public String judgmentAction = "unknown";
@JsonIgnore
public long judgmentHistoryEntry; public long judgmentHistoryEntry;
@JsonIgnore
public int judgmentBatchSize = 0; public int judgmentBatchSize = 0;
@JsonIgnore
public ReconCandidate match = null; public ReconCandidate match = null;
@JsonIgnore
public int matchRank = -1; public int matchRank = -1;
@Deprecated @Deprecated
@ -362,110 +371,46 @@ public class Recon implements HasFields {
return null; return null;
} }
static public Recon loadStreaming(String s, Pool pool) throws Exception { static public Recon loadStreaming(String s) throws Exception {
JsonFactory jsonFactory = new JsonFactory(); return ParsingUtilities.mapper.readValue(s, Recon.class);
JsonParser jp = jsonFactory.createJsonParser(s);
if (jp.nextToken() != JsonToken.START_OBJECT) {
return null;
}
return loadStreaming(jp, pool);
} }
static public Recon loadStreaming(JsonParser jp, Pool pool) throws Exception { public Recon(
JsonToken t = jp.getCurrentToken(); @JsonProperty("id")
if (t == JsonToken.VALUE_NULL || t != JsonToken.START_OBJECT) { long id,
return null; @JsonProperty("judgmentHistoryEntry")
} long judgmentHistoryEntry,
@JsonProperty("j")
Recon recon = null; Judgment judgment,
long id = -1; @JsonProperty("m")
long judgmentHistoryEntry = -1; ReconCandidate match,
@JsonProperty("f")
while (jp.nextToken() != JsonToken.END_OBJECT) { Object[] features,
String fieldName = jp.getCurrentName(); @JsonProperty("c")
jp.nextToken(); List<ReconCandidate> candidates,
@JsonProperty("service")
if ("id".equals(fieldName)) { String service,
id = jp.getLongValue(); @JsonProperty("identifierSpace")
} else if ("judgmentHistoryEntry".equals(fieldName)) { String identifierSpace,
judgmentHistoryEntry = jp.getLongValue(); @JsonProperty("schemaSpace")
if (recon != null) { String schemaSpace,
recon.judgmentHistoryEntry = judgmentHistoryEntry; @JsonProperty("judgmentAction")
} String judgmentAction,
} else { @JsonProperty("judgmentBatchSize")
if (recon == null) { Integer judgmentBatchSize,
recon = new Recon(id, judgmentHistoryEntry); @JsonProperty("matchRank")
} Integer matchRank) {
this.id = id;
if ("j".equals(fieldName)) { this.judgmentHistoryEntry = judgmentHistoryEntry;
recon.judgment = stringToJudgment(jp.getText()); this.judgment = judgment != null ? judgment : Judgment.None;
} else if ("m".equals(fieldName)) { this.match = match;
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { this.features = features != null ? features : new Object[Feature_max];
// legacy case this.candidates = candidates != null ? candidates : new ArrayList<>();
String candidateID = jp.getText(); this.service = service != null ? service : "unknown";
recon.match = pool.getReconCandidate(candidateID); this.identifierSpace = identifierSpace;
} else { this.schemaSpace = schemaSpace;
recon.match = ReconCandidate.loadStreaming(jp); this.judgmentAction = judgmentAction != null ? judgmentAction : "unknown";
} this.judgmentBatchSize = judgmentBatchSize != null ? judgmentBatchSize : 0;
} else if ("f".equals(fieldName)) { this.matchRank = matchRank != null ? matchRank : -1;
if (jp.getCurrentToken() != JsonToken.START_ARRAY) {
return null;
}
int feature = 0;
while (jp.nextToken() != JsonToken.END_ARRAY) {
if (feature < recon.features.length) {
JsonToken token = jp.getCurrentToken();
if (token == JsonToken.VALUE_STRING) {
recon.features[feature++] = jp.getText();
} else if (token == JsonToken.VALUE_NUMBER_INT) {
recon.features[feature++] = jp.getLongValue();
} else if (token == JsonToken.VALUE_NUMBER_FLOAT) {
recon.features[feature++] = jp.getDoubleValue();
} else if (token == JsonToken.VALUE_FALSE) {
recon.features[feature++] = false;
} else if (token == JsonToken.VALUE_TRUE) {
recon.features[feature++] = true;
}
}
}
} else if ("c".equals(fieldName)) {
if (jp.getCurrentToken() != JsonToken.START_ARRAY) {
return null;
}
while (jp.nextToken() != JsonToken.END_ARRAY) {
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
// legacy case
String candidateID = jp.getText();
recon.addCandidate(pool.getReconCandidate(candidateID));
} else {
recon.addCandidate(ReconCandidate.loadStreaming(jp));
}
}
} else if ("service".equals(fieldName)) {
recon.service = jp.getText();
} else if ("identifierSpace".equals(fieldName)) {
recon.identifierSpace = jp.getText();
if ("null".equals(recon.identifierSpace)) {
recon.identifierSpace = FREEBASE_IDENTIFIER_SPACE;
}
} else if ("schemaSpace".equals(fieldName)) {
recon.schemaSpace = jp.getText();
if ("null".equals(recon.schemaSpace)) {
recon.schemaSpace = FREEBASE_SCHEMA_SPACE;
}
} else if ("judgmentAction".equals(fieldName)) {
recon.judgmentAction = jp.getText();
} else if ("judgmentBatchSize".equals(fieldName)) {
recon.judgmentBatchSize = jp.getIntValue();
} else if ("matchRank".equals(fieldName)) {
recon.matchRank = jp.getIntValue();
}
}
}
return recon;
} }
} }

View File

@ -39,7 +39,6 @@ import java.util.Properties;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.JsonToken;

View File

@ -36,16 +36,12 @@ package com.google.refine.model;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.InjectableValues; import com.fasterxml.jackson.databind.InjectableValues;
import com.google.refine.expr.CellTuple; import com.google.refine.expr.CellTuple;

View File

@ -140,7 +140,7 @@ public class MassReconChange implements Change {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
String line = reader.readLine(); String line = reader.readLine();
Recon recon = Recon.loadStreaming(line, pool); Recon recon = Recon.loadStreaming(line);
recons.put(recon.id, recon); recons.put(recon.id, recon);
} }

View File

@ -145,7 +145,7 @@ public class Pool {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
line = reader2.readLine(); line = reader2.readLine();
if (line != null) { if (line != null) {
Recon recon = Recon.loadStreaming(line, this); Recon recon = Recon.loadStreaming(line);
if (recon != null) { if (recon != null) {
pool(recon); pool(recon);
} }

View File

@ -28,7 +28,7 @@ public class CellTests {
@Test @Test
public void serializeCellWithRecon() throws Exception { public void serializeCellWithRecon() throws Exception {
recon = Recon.loadStreaming(reconJson, pool); recon = Recon.loadStreaming(reconJson);
when(pool.getRecon("1533649346002675326")).thenReturn(recon); when(pool.getRecon("1533649346002675326")).thenReturn(recon);
String json = "{\"v\":\"http://www.wikidata.org/entity/Q41522540\",\"r\":\"1533649346002675326\"}"; String json = "{\"v\":\"http://www.wikidata.org/entity/Q41522540\",\"r\":\"1533649346002675326\"}";

View File

@ -32,13 +32,13 @@ public class ReconTests {
@Test @Test
public void serializeReconSaveMode() throws Exception { public void serializeReconSaveMode() throws Exception {
Recon r = Recon.loadStreaming(fullJson, null); Recon r = Recon.loadStreaming(fullJson);
TestUtils.isSerializedTo(r, fullJson, true); TestUtils.isSerializedTo(r, fullJson, true);
} }
@Test @Test
public void serializeReconViewMode() throws Exception { public void serializeReconViewMode() throws Exception {
Recon r = Recon.loadStreaming(fullJson, null); Recon r = Recon.loadStreaming(fullJson);
String shortJson = "{\"id\":1533651559492945033," String shortJson = "{\"id\":1533651559492945033,"
+ "\"service\":\"https://tools.wmflabs.org/openrefine-wikidata/en/api\"," + "\"service\":\"https://tools.wmflabs.org/openrefine-wikidata/en/api\","
+ "\"identifierSpace\":\"http://www.wikidata.org/entity/\"," + "\"identifierSpace\":\"http://www.wikidata.org/entity/\","
@ -66,7 +66,7 @@ public class ReconTests {
+ " {\"id\":\"Q30284245\",\"name\":\"Baylor College of Medicine Children\\u2019s Foundation\",\"score\":48.57142857142858,\"types\":[\"Q163740\"]}" + " {\"id\":\"Q30284245\",\"name\":\"Baylor College of Medicine Children\\u2019s Foundation\",\"score\":48.57142857142858,\"types\":[\"Q163740\"]}"
+ "]" + "]"
+ "}"; + "}";
Recon r = Recon.loadStreaming(fullJson, null); Recon r = Recon.loadStreaming(fullJson);
r.match = null; r.match = null;
r.judgment = Judgment.None; r.judgment = Judgment.None;
TestUtils.isSerializedTo(r, json); TestUtils.isSerializedTo(r, json);

View File

@ -136,7 +136,7 @@ public class RowTests extends RefineTest {
+ "\"c\":[{\"id\":\"Q551479\",\"name\":\"La Monnaie\",\"score\":100,\"types\":[\"Q153562\"]}]," + "\"c\":[{\"id\":\"Q551479\",\"name\":\"La Monnaie\",\"score\":100,\"types\":[\"Q153562\"]}],"
+ "\"f\":[false,false,34,0],\"judgmentAction\":\"auto\",\"judgmentBatchSize\":1,\"matchRank\":0}"; + "\"f\":[false,false,34,0],\"judgmentAction\":\"auto\",\"judgmentBatchSize\":1,\"matchRank\":0}";
Pool pool = mock(Pool.class); Pool pool = mock(Pool.class);
Recon recon = Recon.loadStreaming(reconJson, pool); Recon recon = Recon.loadStreaming(reconJson);
when(pool.getRecon("1533649346002675326")).thenReturn(recon); when(pool.getRecon("1533649346002675326")).thenReturn(recon);
String json = "{\"flagged\":false," String json = "{\"flagged\":false,"