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; package com.google.refine.sorting;
import java.io.IOException;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; 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.expr.ExpressionUtils;
import com.google.refine.model.Column; import com.google.refine.model.Column;
import com.google.refine.model.Project; import com.google.refine.model.Project;
import com.google.refine.model.Record; import com.google.refine.model.Record;
import com.google.refine.model.Row; 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 { abstract public class Criterion {
@JsonProperty("column")
public String columnName; public String columnName;
@JsonIgnore
protected int cellIndex = -2; protected int cellIndex = -2;
// These take on positive and negative values to indicate where blanks and errors // 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. // go relative to non-blank values. They are also relative to each another.
// Blanks and errors are not affected by the reverse flag. // Blanks and errors are not affected by the reverse flag.
@JsonProperty("blankPosition")
public int blankPosition = 1; public int blankPosition = 1;
@JsonProperty("errorPosition")
public int errorPosition = 2; 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") @JsonProperty("valueType")
public abstract String getValueType(); 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 // Returns a cached cell index
// We delay this fetching because the column might not exist // We delay this fetching because the column might not exist
// at deserialization (for instance if the column is created by an operation // at deserialization (for instance if the column is created by an operation

View File

@ -1,11 +1,14 @@
package com.google.refine.sorting; package com.google.refine.sorting;
import org.json.JSONArray; import java.io.IOException;
import org.json.JSONObject; import org.json.JSONObject;
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.google.refine.util.ParsingUtilities;
/** /**
* Stores the configuration of a row/record sorting setup. * Stores the configuration of a row/record sorting setup.
@ -28,22 +31,7 @@ public final class SortingConfig {
return _criteria; return _criteria;
} }
public static SortingConfig reconstruct(JSONObject obj) { public static SortingConfig reconstruct(JSONObject obj) throws IOException {
Criterion[] criteria; return ParsingUtilities.mapper.readValue(obj.toString(), SortingConfig.class);
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);
} }
} }

View File

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

View File

@ -1,14 +1,17 @@
package com.google.refine.tests.sorting; package com.google.refine.tests.sorting;
import org.json.JSONObject; import java.io.IOException;
import org.json.JSONException;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.refine.sorting.Criterion; import com.google.refine.sorting.Criterion;
import com.google.refine.tests.util.TestUtils; import com.google.refine.tests.util.TestUtils;
import com.google.refine.util.ParsingUtilities;
public class BooleanCriterionTest { public class BooleanCriterionTest {
@Test @Test
public void serializeBooleanCriterion() { public void serializeBooleanCriterion() throws JSONException, IOException {
String json = String json =
" {\n" + " {\n" +
" \"errorPosition\": 1,\n" + " \"errorPosition\": 1,\n" +
@ -17,6 +20,6 @@ public class BooleanCriterionTest {
" \"blankPosition\": 2,\n" + " \"blankPosition\": 2,\n" +
" \"reverse\": false\n" + " \"reverse\": false\n" +
" }\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; package com.google.refine.tests.sorting;
import org.json.JSONObject; import java.io.IOException;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.refine.sorting.Criterion; import com.google.refine.sorting.Criterion;
import com.google.refine.tests.util.TestUtils; import com.google.refine.tests.util.TestUtils;
import com.google.refine.util.ParsingUtilities;
public class DateCriterionTest { public class DateCriterionTest {
@Test @Test
public void serializeDateCriterion() { public void serializeDateCriterion() throws IOException {
String json = String json =
" {\n" + " {\n" +
" \"errorPosition\": 2,\n" + " \"errorPosition\": 2,\n" +
@ -17,6 +19,6 @@ public class DateCriterionTest {
" \"blankPosition\": -1,\n" + " \"blankPosition\": -1,\n" +
" \"reverse\": true\n" + " \"reverse\": true\n" +
" }\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; package com.google.refine.tests.sorting;
import org.json.JSONObject; import java.io.IOException;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.refine.sorting.Criterion; import com.google.refine.sorting.Criterion;
import com.google.refine.tests.util.TestUtils; import com.google.refine.tests.util.TestUtils;
import com.google.refine.util.ParsingUtilities;
public class NumberCriterionTest { public class NumberCriterionTest {
@Test @Test
public void serializeNumberCriterion() { public void serializeNumberCriterion() throws IOException {
String json = String json =
" {\n" + " {\n" +
" \"errorPosition\": 2,\n" + " \"errorPosition\": 2,\n" +
@ -17,6 +19,6 @@ public class NumberCriterionTest {
" \"blankPosition\": 1,\n" + " \"blankPosition\": 1,\n" +
" \"reverse\": true\n" + " \"reverse\": true\n" +
" }\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; package com.google.refine.tests.sorting;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -8,7 +11,7 @@ import com.google.refine.tests.util.TestUtils;
public class SortingConfigTests { public class SortingConfigTests {
@Test @Test
public void serializeSortingConfig() { public void serializeSortingConfig() throws JSONException, IOException {
String json = "{\n" + String json = "{\n" +
" \"criteria\": [\n" + " \"criteria\": [\n" +
" {\n" + " {\n" +