diff --git a/main/src/com/google/refine/browsing/Engine.java b/main/src/com/google/refine/browsing/Engine.java index f0ef66770..4fa193fe1 100644 --- a/main/src/com/google/refine/browsing/Engine.java +++ b/main/src/com/google/refine/browsing/Engine.java @@ -44,6 +44,7 @@ import org.json.JSONObject; import org.json.JSONWriter; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; import com.google.refine.Jsonizable; import com.google.refine.browsing.facets.Facet; @@ -72,6 +73,7 @@ public class Engine implements Jsonizable { protected Project _project; protected List _facets = new LinkedList(); + @JsonValue protected EngineConfig _config = new EngineConfig(Collections.emptyList(), Mode.RowBased); static public String modeToString(Mode mode) { diff --git a/main/src/com/google/refine/preference/PreferenceStore.java b/main/src/com/google/refine/preference/PreferenceStore.java index e44656c6d..7358ad9d1 100644 --- a/main/src/com/google/refine/preference/PreferenceStore.java +++ b/main/src/com/google/refine/preference/PreferenceStore.java @@ -33,6 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.google.refine.preference; +import java.io.IOException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; @@ -40,10 +41,18 @@ import java.util.Map; import java.util.Properties; import java.util.Set; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONWriter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.annotation.JsonProperty; + import com.google.refine.Jsonizable; import com.google.refine.RefineServlet; @@ -54,21 +63,40 @@ public class PreferenceStore implements Jsonizable { public static final String USER_NAME = "username"; private boolean dirty = false; - protected Map _prefs = new HashMap(); + protected Map _prefs = new HashMap<>(); + + // Temporary wrapper while serialization has not been migrated yet. + @JsonProperty("entries") + protected Map _prefsJackson = new HashMap<>(); public void put(String key, Object value) { if (value == null) { _prefs.remove(key); + _prefsJackson.remove(key); } else { _prefs.put(key, value); + _prefsJackson.put(key, wrapJSONArray(value)); } dirty = true; } + private Object wrapJSONArray(Object value) { + ObjectMapper mapper = new ObjectMapper(); + if(value != null && value instanceof JSONArray) { + try { + return mapper.readValue(value.toString(), JsonNode.class); + } catch (IOException e) { + return null; + } + } + return value; + } + public Object get(String key) { return _prefs.get(key); } + @JsonIgnore public Set getKeys() { return _prefs.keySet(); } @@ -98,10 +126,24 @@ public class PreferenceStore implements Jsonizable { /** * @return true if the preference store has unsaved changes */ + @JsonIgnore public boolean isDirty() { return dirty; } + /** + * Mark the object as clean every time it is serialized. + * This behaviour is not very clean - it is inherited from + * the previous deserialization code. + * @return + */ + @JsonProperty("makeClean") + @JsonInclude(Include.NON_NULL) + public Integer markAsClean() { + dirty = false; + return null; + } + @SuppressWarnings("unchecked") public void load(JSONObject obj) throws JSONException { if (obj.has("entries") && !obj.isNull("entries")) { @@ -111,8 +153,9 @@ public class PreferenceStore implements Jsonizable { while (i.hasNext()) { String key = i.next(); if (!entries.isNull(key)) { - Object o = entries.get(key); - _prefs.put(key, loadObject(o)); + Object o = entries.get(key), loaded = loadObject(o); + _prefs.put(key, loaded); + _prefsJackson.put(key, wrapJSONArray(loaded)); } } dirty = false; // internal puts don't count diff --git a/main/src/com/google/refine/preference/TopList.java b/main/src/com/google/refine/preference/TopList.java index dfc96f9c4..846d579bd 100644 --- a/main/src/com/google/refine/preference/TopList.java +++ b/main/src/com/google/refine/preference/TopList.java @@ -44,10 +44,14 @@ import org.json.JSONException; import org.json.JSONObject; import org.json.JSONWriter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + import com.google.refine.Jsonizable; public class TopList implements Jsonizable, Iterable { + @JsonProperty("top") final protected int _top; final protected List _list = new ArrayList(); @@ -56,6 +60,7 @@ public class TopList implements Jsonizable, Iterable { } @SuppressWarnings("unchecked") + @JsonProperty("list") public List getList() { return UnmodifiableList.decorate(_list); } @@ -72,11 +77,16 @@ public class TopList implements Jsonizable, Iterable { { _list.remove(element); } + + @JsonProperty("class") + public String getClassName() { + return this.getClass().getName(); + } @Override public void write(JSONWriter writer, Properties options) throws JSONException { writer.object(); - writer.key("class"); writer.value(this.getClass().getName()); + writer.key("class"); writer.value(getClassName()); writer.key("top"); writer.value(_top); writer.key("list"); @@ -107,7 +117,8 @@ public class TopList implements Jsonizable, Iterable { } } - @Override + @Override + @JsonIgnore public Iterator iterator() { return _list.iterator(); } diff --git a/main/tests/server/src/com/google/refine/tests/preference/PreferenceStoreTests.java b/main/tests/server/src/com/google/refine/tests/preference/PreferenceStoreTests.java index 42911dfc5..86778c971 100644 --- a/main/tests/server/src/com/google/refine/tests/preference/PreferenceStoreTests.java +++ b/main/tests/server/src/com/google/refine/tests/preference/PreferenceStoreTests.java @@ -1,5 +1,8 @@ package com.google.refine.tests.preference; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + import org.json.JSONObject; import org.testng.annotations.Test; @@ -17,8 +20,22 @@ public class PreferenceStoreTests { + " \"scripting.starred-expressions\":{\"class\":\"com.google.refine.preference.TopList\",\"top\":2147483647,\"list\":[]}," + " \"scripting.expressions\":{\"class\":\"com.google.refine.preference.TopList\",\"top\":100,\"list\":[]}" + "}}"; + String jsonAfter = "{" + + "\"entries\":{" + + " \"reconciliation.standardServices\":[" + + " {\"propose_properties\":{\"service_url\":\"https://tools.wmflabs.org/openrefine-wikidata\",\"service_path\":\"/en/propose_properties\"},\"preview\":{\"width\":320,\"url\":\"https://tools.wmflabs.org/openrefine-wikidata/en/preview?id={{id}}\",\"height\":90},\"view\":{\"url\":\"https://www.wikidata.org/wiki/{{id}}\"},\"ui\":{\"handler\":\"ReconStandardServicePanel\"},\"identifierSpace\":\"http://www.wikidata.org/entity/\",\"name\":\"Wikidata Reconciliation for OpenRefine (en)\",\"suggest\":{\"property\":{\"flyout_service_path\":\"/en/flyout/property?id=${id}\",\"service_url\":\"https://tools.wmflabs.org/openrefine-wikidata\",\"service_path\":\"/en/suggest/property\"},\"type\":{\"flyout_service_path\":\"/en/flyout/type?id=${id}\",\"service_url\":\"https://tools.wmflabs.org/openrefine-wikidata\",\"service_path\":\"/en/suggest/type\"},\"entity\":{\"flyout_service_path\":\"/en/flyout/entity?id=${id}\",\"service_url\":\"https://tools.wmflabs.org/openrefine-wikidata\",\"service_path\":\"/en/suggest/entity\"}},\"defaultTypes\":[{\"name\":\"entity\",\"id\":\"Q35120\"}],\"url\":\"https://tools.wmflabs.org/openrefine-wikidata/en/api\",\"schemaSpace\":\"http://www.wikidata.org/prop/direct/\"}" + + " ]," + + " \"scripting.starred-expressions\":{\"class\":\"com.google.refine.preference.TopList\",\"top\":2147483647,\"list\":[]}," + + " \"scripting.expressions\":{\"class\":\"com.google.refine.preference.TopList\",\"top\":100,\"list\":[]}," + + " \"mypreference\":\"myvalue\"" + + "}}"; PreferenceStore prefStore = new PreferenceStore(); prefStore.load(new JSONObject(json)); - TestUtils.isSerializedTo(prefStore, json); + assertFalse(prefStore.isDirty()); + prefStore.put("mypreference", "myvalue"); + assertTrue(prefStore.isDirty()); + TestUtils.isSerializedTo(prefStore, jsonAfter); + assertFalse(prefStore.isDirty()); } + }