diff --git a/main/src/com/google/refine/browsing/EngineConfig.java b/main/src/com/google/refine/browsing/EngineConfig.java index b0af26097..3e9a4c4e4 100644 --- a/main/src/com/google/refine/browsing/EngineConfig.java +++ b/main/src/com/google/refine/browsing/EngineConfig.java @@ -1,21 +1,17 @@ package com.google.refine.browsing; +import java.io.IOException; import java.util.Collections; -import java.util.LinkedList; import java.util.List; -import org.json.JSONArray; import org.json.JSONObject; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.refine.browsing.Engine.Mode; import com.google.refine.browsing.facets.FacetConfig; -import com.google.refine.browsing.facets.ListFacet.ListFacetConfig; -import com.google.refine.browsing.facets.RangeFacet.RangeFacetConfig; -import com.google.refine.browsing.facets.ScatterplotFacet.ScatterplotFacetConfig; -import com.google.refine.browsing.facets.TextSearchFacet.TextSearchFacetConfig; -import com.google.refine.browsing.facets.TimeRangeFacet.TimeRangeFacetConfig; +import com.google.refine.util.ParsingUtilities; public class EngineConfig { @@ -23,9 +19,14 @@ public class EngineConfig { protected final List _facets; protected final Mode _mode; - public EngineConfig(List facets, Mode mode) { - _facets = facets; - _mode = mode; + @JsonCreator + public EngineConfig( + @JsonProperty("facets") + List facets, + @JsonProperty("mode") + Mode mode) { + _facets = facets == null ? Collections.emptyList() : facets; + _mode = mode == null ? Mode.RowBased : mode; } @JsonProperty("mode") @@ -39,49 +40,14 @@ public class EngineConfig { } public static EngineConfig reconstruct(JSONObject o) { - if (o == null) { + if(o == null) { return new EngineConfig(Collections.emptyList(), Mode.RowBased); } - - List facets = new LinkedList<>(); - if (o.has("facets") && !o.isNull("facets")) { - JSONArray a = o.getJSONArray("facets"); - int length = a.length(); - - for (int i = 0; i < length; i++) { - JSONObject fo = a.getJSONObject(i); - String type = fo.has("type") ? fo.getString("type") : "list"; - - FacetConfig facet = null; - if ("list".equals(type)) { - facet = new ListFacetConfig(); - } else if ("range".equals(type)) { - facet = new RangeFacetConfig(); - } else if ("timerange".equals(type)) { - facet = new TimeRangeFacetConfig(); - } else if ("scatterplot".equals(type)) { - facet = new ScatterplotFacetConfig(); - } else if ("text".equals(type)) { - facet = new TextSearchFacetConfig(); - } - - if (facet != null) { - facet.initializeFromJSON(fo); - facets.add(facet); - } - } + try { + return ParsingUtilities.mapper.readValue(o.toString(), EngineConfig.class); + } catch (IOException e) { + e.printStackTrace(); + return null; } - - Mode mode = Mode.RowBased; - // for backward compatibility - if (o.has(Engine.INCLUDE_DEPENDENT) && !o.isNull(Engine.INCLUDE_DEPENDENT)) { - mode = o.getBoolean(Engine.INCLUDE_DEPENDENT) ? Mode.RecordBased : Mode.RowBased; - } - - if (o.has(Engine.MODE) && !o.isNull(Engine.MODE)) { - mode = Engine.MODE_ROW_BASED.equals(o.getString(Engine.MODE)) ? Mode.RowBased : Mode.RecordBased; - } - - return new EngineConfig(facets, mode); } } diff --git a/main/src/com/google/refine/browsing/facets/FacetConfig.java b/main/src/com/google/refine/browsing/facets/FacetConfig.java index 22f07e39c..07ffc9156 100644 --- a/main/src/com/google/refine/browsing/facets/FacetConfig.java +++ b/main/src/com/google/refine/browsing/facets/FacetConfig.java @@ -1,8 +1,9 @@ package com.google.refine.browsing.facets; -import org.json.JSONObject; - import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.google.refine.model.Project; @@ -13,16 +14,20 @@ import com.google.refine.model.Project; * of operations. It does not contain the actual values displayed by * the facet. * - * @author antonin + * @author Antonin Delpeuch * */ -public interface FacetConfig { - /** - * Reads the facet configuration from a JSON object (will be removed once we migrate to Jackson) - * @param fo - */ - public void initializeFromJSON(JSONObject fo); - +@JsonTypeInfo( + use=JsonTypeInfo.Id.NAME, + include=JsonTypeInfo.As.PROPERTY, + property="type") +@JsonSubTypes({ + @Type(value = ListFacet.ListFacetConfig.class, name = "list"), + @Type(value = RangeFacet.RangeFacetConfig.class, name = "range"), + @Type(value = TimeRangeFacet.TimeRangeFacetConfig.class, name = "timerange"), + @Type(value = TextSearchFacet.TextSearchFacetConfig.class, name = "text"), + @Type(value = ScatterplotFacet.ScatterplotFacetConfig.class, name = "scatterplot") }) +public interface FacetConfig { /** * Instantiates the given facet on a particular project. * @param project diff --git a/main/src/com/google/refine/browsing/facets/FacetConfigResolver.java b/main/src/com/google/refine/browsing/facets/FacetConfigResolver.java new file mode 100644 index 000000000..0cfac814c --- /dev/null +++ b/main/src/com/google/refine/browsing/facets/FacetConfigResolver.java @@ -0,0 +1,36 @@ +package com.google.refine.browsing.facets; + +import java.io.IOException; + +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import com.fasterxml.jackson.databind.DatabindContext; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase; +import com.fasterxml.jackson.databind.type.TypeFactory; + +import com.google.refine.model.recon.ReconConfig; + +public class FacetConfigResolver extends TypeIdResolverBase { + + protected TypeFactory factory = TypeFactory.defaultInstance(); + + @Override + public Id getMechanism() { + return Id.NAME; + } + + @Override + public String idFromValue(Object instance) { + return ((ReconConfig)instance).getMode(); + } + + @Override + public String idFromValueAndType(Object instance, Class type) { + return ReconConfig.s_opClassToName.get(type); + } + + @Override + public JavaType typeFromId(DatabindContext context, String id) throws IOException { + return factory.constructSimpleType(ReconConfig.getClassFromMode(id), new JavaType[0]); + } +} diff --git a/main/src/com/google/refine/browsing/facets/ListFacet.java b/main/src/com/google/refine/browsing/facets/ListFacet.java index 768b287a1..f1f2ebff9 100644 --- a/main/src/com/google/refine/browsing/facets/ListFacet.java +++ b/main/src/com/google/refine/browsing/facets/ListFacet.java @@ -37,9 +37,6 @@ import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; -import org.json.JSONArray; -import org.json.JSONObject; - import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; @@ -61,7 +58,6 @@ import com.google.refine.expr.MetaParser; import com.google.refine.expr.ParsingException; import com.google.refine.model.Column; import com.google.refine.model.Project; -import com.google.refine.util.JSONUtilities; public class ListFacet implements Facet { public static final String ERR_TOO_MANY_CHOICES = "Too many choices"; @@ -125,36 +121,6 @@ public class ListFacet implements Facet { .collect(Collectors.toList()); } - @Override - public void initializeFromJSON(JSONObject o) { - name = o.getString("name"); - expression = o.getString("expression"); - columnName = o.getString("columnName"); - invert = o.has("invert") && o.getBoolean("invert"); - - JSONArray a = o.getJSONArray("selection"); - int length = a.length(); - - for (int i = 0; i < length; i++) { - JSONObject oc = a.getJSONObject(i); - JSONObject ocv = oc.getJSONObject("v"); - - DecoratedValue decoratedValue = new DecoratedValue( - ocv.get("v"), ocv.getString("l")); - - selection.add(decoratedValue); - } - - omitBlank = JSONUtilities.getBoolean(o, "omitBlank", false); - omitError = JSONUtilities.getBoolean(o, "omitError", false); - - selectNumber = JSONUtilities.getBoolean(o, "selectNumber", false); - selectDateTime = JSONUtilities.getBoolean(o, "selectDateTime", false); - selectBoolean = JSONUtilities.getBoolean(o, "selectBoolean", false); - selectBlank = JSONUtilities.getBoolean(o, "selectBlank", false); - selectError = JSONUtilities.getBoolean(o, "selectError", false); - } - @Override public Facet apply(Project project) { ListFacet facet = new ListFacet(); diff --git a/main/src/com/google/refine/browsing/facets/RangeFacet.java b/main/src/com/google/refine/browsing/facets/RangeFacet.java index 0915c4f2b..4e978849a 100644 --- a/main/src/com/google/refine/browsing/facets/RangeFacet.java +++ b/main/src/com/google/refine/browsing/facets/RangeFacet.java @@ -33,8 +33,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.google.refine.browsing.facets; -import org.json.JSONObject; - import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; @@ -58,7 +56,6 @@ import com.google.refine.expr.MetaParser; import com.google.refine.expr.ParsingException; import com.google.refine.model.Column; import com.google.refine.model.Project; -import com.google.refine.util.JSONUtilities; public class RangeFacet implements Facet { @@ -125,26 +122,6 @@ public class RangeFacet implements Facet { _selected = !_selectNumeric || !_selectNonNumeric || !_selectBlank || !_selectError || from != null || to != null; } - @Override - public void initializeFromJSON(JSONObject o) { - _name = o.getString("name"); - _expression = o.getString("expression"); - _columnName = o.getString("columnName"); - if (o.has(FROM) || o.has(TO)) { - _from = o.has(FROM) ? o.getDouble(FROM) : 0; - _to = o.has(TO) ? o.getDouble(TO) : 0; - _selected = true; - } - _selectNumeric = JSONUtilities.getBoolean(o, "selectNumeric", true); - _selectNonNumeric = JSONUtilities.getBoolean(o, "selectNonNumeric", true); - _selectBlank = JSONUtilities.getBoolean(o, "selectBlank", true); - _selectError = JSONUtilities.getBoolean(o, "selectError", true); - - if (!_selectNumeric || !_selectNonNumeric || !_selectBlank || !_selectError) { - _selected = true; - } - } - @Override public RangeFacet apply(Project project) { RangeFacet facet = new RangeFacet(); diff --git a/main/src/com/google/refine/browsing/facets/ScatterplotFacet.java b/main/src/com/google/refine/browsing/facets/ScatterplotFacet.java index 5d5685b55..f2f3d3243 100644 --- a/main/src/com/google/refine/browsing/facets/ScatterplotFacet.java +++ b/main/src/com/google/refine/browsing/facets/ScatterplotFacet.java @@ -44,7 +44,6 @@ import java.io.IOException; import javax.imageio.ImageIO; import org.apache.commons.codec.binary.Base64; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -111,9 +110,11 @@ public class ScatterplotFacet implements Facet { protected double dot; @JsonIgnore - protected String color_str; + protected String color_str = "000000"; @JsonIgnore - protected Color color; + protected Color getColor() { + return new Color(Integer.parseInt(color_str,16)); + } @JsonProperty(FROM_X) protected double from_x; // the numeric selection for the x axis, from 0 to 1 @@ -147,43 +148,6 @@ public class ScatterplotFacet implements Facet { return facet; } - @Override - public void initializeFromJSON(JSONObject o) { - name = o.getString(NAME); - l = size = (o.has(SIZE)) ? o.getInt(SIZE) : 100; - dot = (o.has(DOT)) ? o.getInt(DOT) : 0.5d; - - dim_x = (o.has(DIM_X)) ? getAxisDim(o.getString(DIM_X)) : LIN; - if (o.has(FROM_X) && o.has(TO_X)) { - from_x = o.getDouble(FROM_X); - to_x = o.getDouble(TO_X); - } else { - from_x = 0; - to_x = 1; - } - - dim_y = (o.has(DIM_Y)) ? getAxisDim(o.getString(DIM_Y)) : LIN; - if (o.has(FROM_Y) && o.has(TO_Y)) { - from_y = o.getDouble(FROM_Y); - to_y = o.getDouble(TO_Y); - } else { - from_y = 0; - to_y = 1; - } - - rotation_str = (o.has(ROTATION) ? o.getString(ROTATION) : ""); - rotation = getRotation(rotation_str); - - color_str = (o.has(COLOR)) ? o.getString(COLOR) : "000000"; - color = new Color(Integer.parseInt(color_str,16)); - - columnName_x = o.getString(X_COLUMN_NAME); - expression_x = o.getString(X_EXPRESSION); - - columnName_y = o.getString(Y_COLUMN_NAME); - expression_y = o.getString(Y_EXPRESSION); - } - public static int getRotation(String rotation) { rotation = rotation.toLowerCase(); if ("cw".equals(rotation) || "right".equals(rotation)) { @@ -469,7 +433,7 @@ public class ScatterplotFacet implements Facet { if (index_x.isNumeric() && index_y.isNumeric()) { ScatterplotDrawingRowVisitor drawer = new ScatterplotDrawingRowVisitor( columnIndex_x, columnIndex_y, min_x, max_x, min_y, max_y, - config.size, config.dim_x, config.dim_y, config.rotation, config.dot, config.color + config.size, config.dim_x, config.dim_y, config.rotation, config.dot, config.getColor() ); filteredRows.accept(project, drawer); @@ -500,7 +464,7 @@ public class ScatterplotFacet implements Facet { if (index_x.isNumeric() && index_y.isNumeric()) { ScatterplotDrawingRowVisitor drawer = new ScatterplotDrawingRowVisitor( columnIndex_x, columnIndex_y, min_x, max_x, min_y, max_y, - config.size, config.dim_x, config.dim_y, config.rotation, config.dot, config.color + config.size, config.dim_x, config.dim_y, config.rotation, config.dot, config.getColor() ); filteredRecords.accept(project, drawer); diff --git a/main/src/com/google/refine/browsing/facets/TextSearchFacet.java b/main/src/com/google/refine/browsing/facets/TextSearchFacet.java index 5e3780e2a..4a5ea6733 100644 --- a/main/src/com/google/refine/browsing/facets/TextSearchFacet.java +++ b/main/src/com/google/refine/browsing/facets/TextSearchFacet.java @@ -36,7 +36,6 @@ package com.google.refine.browsing.facets; import java.util.regex.Pattern; import org.json.JSONException; -import org.json.JSONObject; import com.fasterxml.jackson.annotation.JsonProperty; @@ -78,18 +77,6 @@ public class TextSearchFacet implements Facet { return facet; } - @Override - public void initializeFromJSON(JSONObject o) { - _name = o.getString("name"); - _columnName = o.getString("columnName"); - _mode = o.getString("mode"); - _caseSensitive = o.getBoolean("caseSensitive"); - if (!o.isNull("query")) { - _query = o.getString("query"); - } - _invert = o.has("invert") && o.getBoolean("invert"); - } - @Override public String getJsonType() { return "text"; diff --git a/main/src/com/google/refine/browsing/facets/TimeRangeFacet.java b/main/src/com/google/refine/browsing/facets/TimeRangeFacet.java index 38afab3c1..63ecfcc39 100644 --- a/main/src/com/google/refine/browsing/facets/TimeRangeFacet.java +++ b/main/src/com/google/refine/browsing/facets/TimeRangeFacet.java @@ -33,9 +33,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.google.refine.browsing.facets; -import org.json.JSONException; -import org.json.JSONObject; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -58,7 +55,6 @@ import com.google.refine.expr.MetaParser; import com.google.refine.expr.ParsingException; import com.google.refine.model.Column; import com.google.refine.model.Project; -import com.google.refine.util.JSONUtilities; public class TimeRangeFacet implements Facet { /* diff --git a/main/tests/server/src/com/google/refine/tests/browsing/facets/ListFacetTests.java b/main/tests/server/src/com/google/refine/tests/browsing/facets/ListFacetTests.java index f462f4710..200134d6f 100644 --- a/main/tests/server/src/com/google/refine/tests/browsing/facets/ListFacetTests.java +++ b/main/tests/server/src/com/google/refine/tests/browsing/facets/ListFacetTests.java @@ -2,7 +2,6 @@ package com.google.refine.tests.browsing.facets; import java.io.IOException; -import org.json.JSONObject; import org.testng.annotations.Test; import com.fasterxml.jackson.core.JsonParseException; @@ -65,9 +64,8 @@ public class ListFacetTests extends RefineTest { + "]}"; @Test - public void serializeListFacetConfig() { - ListFacetConfig facetConfig = new ListFacetConfig(); - facetConfig.initializeFromJSON(new JSONObject(jsonConfig)); + public void serializeListFacetConfig() throws JsonParseException, JsonMappingException, IOException { + ListFacetConfig facetConfig = ParsingUtilities.mapper.readValue(jsonConfig, ListFacetConfig.class); TestUtils.isSerializedTo(facetConfig, jsonConfig); } diff --git a/main/tests/server/src/com/google/refine/tests/browsing/facets/ScatterplotFacetTests.java b/main/tests/server/src/com/google/refine/tests/browsing/facets/ScatterplotFacetTests.java index 6c0c0b3c0..29e7e9112 100644 --- a/main/tests/server/src/com/google/refine/tests/browsing/facets/ScatterplotFacetTests.java +++ b/main/tests/server/src/com/google/refine/tests/browsing/facets/ScatterplotFacetTests.java @@ -1,8 +1,12 @@ package com.google.refine.tests.browsing.facets; -import org.json.JSONObject; +import java.io.IOException; + import org.testng.annotations.Test; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + import com.google.refine.browsing.Engine; import com.google.refine.browsing.facets.ScatterplotFacet; import com.google.refine.browsing.facets.ScatterplotFacet.ScatterplotFacetConfig; @@ -10,6 +14,7 @@ import com.google.refine.model.Cell; import com.google.refine.model.Project; import com.google.refine.tests.RefineTest; import com.google.refine.tests.util.TestUtils; +import com.google.refine.util.ParsingUtilities; public class ScatterplotFacetTests extends RefineTest { public static String configJson = "{\n" + @@ -48,14 +53,13 @@ public class ScatterplotFacetTests extends RefineTest { + "}"; @Test - public void serializeScatterplotFacetConfig() { - ScatterplotFacetConfig config = new ScatterplotFacetConfig(); - config.initializeFromJSON(new JSONObject(configJson)); + public void serializeScatterplotFacetConfig() throws JsonParseException, JsonMappingException, IOException { + ScatterplotFacetConfig config = ParsingUtilities.mapper.readValue(configJson, ScatterplotFacetConfig.class); TestUtils.isSerializedTo(config, configJson); } @Test - public void serializeScatterplotFacet() { + public void serializeScatterplotFacet() throws JsonParseException, JsonMappingException, IOException { Project project = createCSVProject("my column,e\n" + "89.2,89.2\n" + "-45.9,-45.9\n" + @@ -69,8 +73,7 @@ public class ScatterplotFacetTests extends RefineTest { project.rows.get(3).cells.set(0, new Cell(0.4, null)); project.rows.get(3).cells.set(1, new Cell(0.4, null)); - ScatterplotFacetConfig config = new ScatterplotFacetConfig(); - config.initializeFromJSON(new JSONObject(configJson)); + ScatterplotFacetConfig config = ParsingUtilities.mapper.readValue(configJson, ScatterplotFacetConfig.class); ScatterplotFacet facet = config.apply(project); facet.computeChoices(project, engine.getAllFilteredRows());