Jackson deserialization for sorting Criterion and subclasses

This commit is contained in:
Antonin Delpeuch 2018-10-22 11:22:27 +01:00
parent 242a3abb7d
commit 5f671e5e81
7 changed files with 52 additions and 95 deletions

View File

@ -33,91 +33,53 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.refine.sorting;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.google.refine.expr.ExpressionUtils;
import com.google.refine.model.Column;
import com.google.refine.model.Project;
import com.google.refine.model.Record;
import com.google.refine.model.Row;
import com.google.refine.util.ParsingUtilities;
@JsonTypeInfo(
use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY,
property="valueType")
@JsonSubTypes({
@Type(value = BooleanCriterion.class, name = "boolean"),
@Type(value = DateCriterion.class, name = "date"),
@Type(value = NumberCriterion.class, name = "number"),
@Type(value = StringCriterion.class, name = "string") })
abstract public class Criterion {
@JsonProperty("column")
public String columnName;
@JsonIgnore
protected int cellIndex = -2;
// These take on positive and negative values to indicate where blanks and errors
// go relative to non-blank values. They are also relative to each another.
// Blanks and errors are not affected by the reverse flag.
@JsonProperty("blankPosition")
public int blankPosition = 1;
@JsonProperty("errorPosition")
public int errorPosition = 2;
public boolean reverse;
@JsonProperty("reverse")
public boolean reverse = false;
public void initializeFromJSON(JSONObject obj)
throws JSONException {
if (obj.has("column") && !obj.isNull("column")) {
columnName = obj.getString("column");
}
if (obj.has("blankPosition") && !obj.isNull("blankPosition")) {
blankPosition = obj.getInt("blankPosition");
}
if (obj.has("errorPosition") && !obj.isNull("errorPosition")) {
errorPosition = obj.getInt("errorPosition");
}
if (obj.has("reverse") && !obj.isNull("reverse")) {
reverse = obj.getBoolean("reverse");
}
}
public static Criterion reconstruct(JSONObject obj) throws JSONException {
String valueType = "string";
if (obj.has("valueType") && !obj.isNull("valueType")) {
valueType = obj.getString("valueType");
}
Criterion c = null;
if ("boolean".equals(valueType)) {
c = new BooleanCriterion();
} else if ("date".equals(valueType)) {
c = new DateCriterion();
} else if ("number".equals(valueType)) {
c = new NumberCriterion();
} else {
c = new StringCriterion(obj.getBoolean("caseSensitive"));
}
c.initializeFromJSON(obj);
return c;
}
@JsonProperty("valueType")
public abstract String getValueType();
@JsonProperty("reverse")
public boolean getReverse() {
return reverse;
}
@JsonProperty("column")
public String getColumnName() {
return columnName;
}
@JsonProperty("blankPosition")
public int getBlankPosition() {
return blankPosition;
}
@JsonProperty("errorPosition")
public int getErrorPosition() {
return errorPosition;
}
// Returns a cached cell index
// We delay this fetching because the column might not exist
// at deserialization (for instance if the column is created by an operation

View File

@ -1,11 +1,14 @@
package com.google.refine.sorting;
import org.json.JSONArray;
import java.io.IOException;
import org.json.JSONObject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.refine.util.ParsingUtilities;
/**
* Stores the configuration of a row/record sorting setup.
@ -28,22 +31,7 @@ public final class SortingConfig {
return _criteria;
}
public static SortingConfig reconstruct(JSONObject obj) {
Criterion[] criteria;
if (obj != null && obj.has("criteria") && !obj.isNull("criteria")) {
JSONArray a = obj.getJSONArray("criteria");
int count = a.length();
criteria = new Criterion[count];
for (int i = 0; i < count; i++) {
JSONObject obj2 = a.getJSONObject(i);
criteria[i] = Criterion.reconstruct(obj2);
}
} else {
criteria = new Criterion[0];
}
return new SortingConfig(criteria);
public static SortingConfig reconstruct(JSONObject obj) throws IOException {
return ParsingUtilities.mapper.readValue(obj.toString(), SortingConfig.class);
}
}

View File

@ -36,30 +36,27 @@ package com.google.refine.sorting;
import java.text.CollationKey;
import java.text.Collator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.refine.expr.ExpressionUtils;
public class StringCriterion extends Criterion {
@JsonProperty("caseSensitive")
public boolean caseSensitive;
@JsonIgnore
Collator collator;
/**
*
*/
public StringCriterion(boolean caseSensitive) {
public StringCriterion() {
super();
collator = Collator.getInstance();
collator.setDecomposition(Collator.FULL_DECOMPOSITION);
collator.setStrength(Collator.SECONDARY);
this.caseSensitive = caseSensitive;
}
@JsonProperty("caseSensitive")
public boolean isCaseSensitive() {
return caseSensitive;
}
@Override
public KeyMaker createKeyMaker() {
return new KeyMaker() {

View File

@ -1,14 +1,17 @@
package com.google.refine.tests.sorting;
import org.json.JSONObject;
import java.io.IOException;
import org.json.JSONException;
import org.testng.annotations.Test;
import com.google.refine.sorting.Criterion;
import com.google.refine.tests.util.TestUtils;
import com.google.refine.util.ParsingUtilities;
public class BooleanCriterionTest {
@Test
public void serializeBooleanCriterion() {
public void serializeBooleanCriterion() throws JSONException, IOException {
String json =
" {\n" +
" \"errorPosition\": 1,\n" +
@ -17,6 +20,6 @@ public class BooleanCriterionTest {
" \"blankPosition\": 2,\n" +
" \"reverse\": false\n" +
" }\n";
TestUtils.isSerializedTo(Criterion.reconstruct(new JSONObject(json)), json);
TestUtils.isSerializedTo(ParsingUtilities.mapper.readValue(json, Criterion.class), json);
}
}

View File

@ -1,14 +1,16 @@
package com.google.refine.tests.sorting;
import org.json.JSONObject;
import java.io.IOException;
import org.testng.annotations.Test;
import com.google.refine.sorting.Criterion;
import com.google.refine.tests.util.TestUtils;
import com.google.refine.util.ParsingUtilities;
public class DateCriterionTest {
@Test
public void serializeDateCriterion() {
public void serializeDateCriterion() throws IOException {
String json =
" {\n" +
" \"errorPosition\": 2,\n" +
@ -17,6 +19,6 @@ public class DateCriterionTest {
" \"blankPosition\": -1,\n" +
" \"reverse\": true\n" +
" }\n";
TestUtils.isSerializedTo(Criterion.reconstruct(new JSONObject(json)), json);
TestUtils.isSerializedTo(ParsingUtilities.mapper.readValue(json, Criterion.class), json);
}
}

View File

@ -1,14 +1,16 @@
package com.google.refine.tests.sorting;
import org.json.JSONObject;
import java.io.IOException;
import org.testng.annotations.Test;
import com.google.refine.sorting.Criterion;
import com.google.refine.tests.util.TestUtils;
import com.google.refine.util.ParsingUtilities;
public class NumberCriterionTest {
@Test
public void serializeNumberCriterion() {
public void serializeNumberCriterion() throws IOException {
String json =
" {\n" +
" \"errorPosition\": 2,\n" +
@ -17,6 +19,6 @@ public class NumberCriterionTest {
" \"blankPosition\": 1,\n" +
" \"reverse\": true\n" +
" }\n";
TestUtils.isSerializedTo(Criterion.reconstruct(new JSONObject(json)), json);
TestUtils.isSerializedTo(ParsingUtilities.mapper.readValue(json, Criterion.class), json);
}
}

View File

@ -1,5 +1,8 @@
package com.google.refine.tests.sorting;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import org.testng.annotations.Test;
@ -8,7 +11,7 @@ import com.google.refine.tests.util.TestUtils;
public class SortingConfigTests {
@Test
public void serializeSortingConfig() {
public void serializeSortingConfig() throws JSONException, IOException {
String json = "{\n" +
" \"criteria\": [\n" +
" {\n" +