Jackson serialization for preferences
This commit is contained in:
parent
418b21dda2
commit
18c2183cbc
@ -44,6 +44,7 @@ import org.json.JSONObject;
|
|||||||
import org.json.JSONWriter;
|
import org.json.JSONWriter;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
|
|
||||||
import com.google.refine.Jsonizable;
|
import com.google.refine.Jsonizable;
|
||||||
import com.google.refine.browsing.facets.Facet;
|
import com.google.refine.browsing.facets.Facet;
|
||||||
@ -72,6 +73,7 @@ public class Engine implements Jsonizable {
|
|||||||
|
|
||||||
protected Project _project;
|
protected Project _project;
|
||||||
protected List<Facet> _facets = new LinkedList<Facet>();
|
protected List<Facet> _facets = new LinkedList<Facet>();
|
||||||
|
@JsonValue
|
||||||
protected EngineConfig _config = new EngineConfig(Collections.emptyList(), Mode.RowBased);
|
protected EngineConfig _config = new EngineConfig(Collections.emptyList(), Mode.RowBased);
|
||||||
|
|
||||||
static public String modeToString(Mode mode) {
|
static public String modeToString(Mode mode) {
|
||||||
|
@ -33,6 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
package com.google.refine.preference;
|
package com.google.refine.preference;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -40,10 +41,18 @@ import java.util.Map;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.json.JSONWriter;
|
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.Jsonizable;
|
||||||
import com.google.refine.RefineServlet;
|
import com.google.refine.RefineServlet;
|
||||||
|
|
||||||
@ -54,21 +63,40 @@ public class PreferenceStore implements Jsonizable {
|
|||||||
public static final String USER_NAME = "username";
|
public static final String USER_NAME = "username";
|
||||||
|
|
||||||
private boolean dirty = false;
|
private boolean dirty = false;
|
||||||
protected Map<String, Object> _prefs = new HashMap<String, Object>();
|
protected Map<String, Object> _prefs = new HashMap<>();
|
||||||
|
|
||||||
|
// Temporary wrapper while serialization has not been migrated yet.
|
||||||
|
@JsonProperty("entries")
|
||||||
|
protected Map<String, Object> _prefsJackson = new HashMap<>();
|
||||||
|
|
||||||
public void put(String key, Object value) {
|
public void put(String key, Object value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
_prefs.remove(key);
|
_prefs.remove(key);
|
||||||
|
_prefsJackson.remove(key);
|
||||||
} else {
|
} else {
|
||||||
_prefs.put(key, value);
|
_prefs.put(key, value);
|
||||||
|
_prefsJackson.put(key, wrapJSONArray(value));
|
||||||
}
|
}
|
||||||
dirty = true;
|
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) {
|
public Object get(String key) {
|
||||||
return _prefs.get(key);
|
return _prefs.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
public Set<String> getKeys() {
|
public Set<String> getKeys() {
|
||||||
return _prefs.keySet();
|
return _prefs.keySet();
|
||||||
}
|
}
|
||||||
@ -98,10 +126,24 @@ public class PreferenceStore implements Jsonizable {
|
|||||||
/**
|
/**
|
||||||
* @return true if the preference store has unsaved changes
|
* @return true if the preference store has unsaved changes
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnore
|
||||||
public boolean isDirty() {
|
public boolean isDirty() {
|
||||||
return dirty;
|
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")
|
@SuppressWarnings("unchecked")
|
||||||
public void load(JSONObject obj) throws JSONException {
|
public void load(JSONObject obj) throws JSONException {
|
||||||
if (obj.has("entries") && !obj.isNull("entries")) {
|
if (obj.has("entries") && !obj.isNull("entries")) {
|
||||||
@ -111,8 +153,9 @@ public class PreferenceStore implements Jsonizable {
|
|||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
String key = i.next();
|
String key = i.next();
|
||||||
if (!entries.isNull(key)) {
|
if (!entries.isNull(key)) {
|
||||||
Object o = entries.get(key);
|
Object o = entries.get(key), loaded = loadObject(o);
|
||||||
_prefs.put(key, loadObject(o));
|
_prefs.put(key, loaded);
|
||||||
|
_prefsJackson.put(key, wrapJSONArray(loaded));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dirty = false; // internal puts don't count
|
dirty = false; // internal puts don't count
|
||||||
|
@ -44,10 +44,14 @@ import org.json.JSONException;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.json.JSONWriter;
|
import org.json.JSONWriter;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import com.google.refine.Jsonizable;
|
import com.google.refine.Jsonizable;
|
||||||
|
|
||||||
public class TopList implements Jsonizable, Iterable<String> {
|
public class TopList implements Jsonizable, Iterable<String> {
|
||||||
|
|
||||||
|
@JsonProperty("top")
|
||||||
final protected int _top;
|
final protected int _top;
|
||||||
final protected List<String> _list = new ArrayList<String>();
|
final protected List<String> _list = new ArrayList<String>();
|
||||||
|
|
||||||
@ -56,6 +60,7 @@ public class TopList implements Jsonizable, Iterable<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@JsonProperty("list")
|
||||||
public List<String> getList() {
|
public List<String> getList() {
|
||||||
return UnmodifiableList.decorate(_list);
|
return UnmodifiableList.decorate(_list);
|
||||||
}
|
}
|
||||||
@ -72,11 +77,16 @@ public class TopList implements Jsonizable, Iterable<String> {
|
|||||||
{
|
{
|
||||||
_list.remove(element);
|
_list.remove(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonProperty("class")
|
||||||
|
public String getClassName() {
|
||||||
|
return this.getClass().getName();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JSONWriter writer, Properties options) throws JSONException {
|
public void write(JSONWriter writer, Properties options) throws JSONException {
|
||||||
writer.object();
|
writer.object();
|
||||||
writer.key("class"); writer.value(this.getClass().getName());
|
writer.key("class"); writer.value(getClassName());
|
||||||
|
|
||||||
writer.key("top"); writer.value(_top);
|
writer.key("top"); writer.value(_top);
|
||||||
writer.key("list");
|
writer.key("list");
|
||||||
@ -107,7 +117,8 @@ public class TopList implements Jsonizable, Iterable<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@JsonIgnore
|
||||||
public Iterator<String> iterator() {
|
public Iterator<String> iterator() {
|
||||||
return _list.iterator();
|
return _list.iterator();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.google.refine.tests.preference;
|
package com.google.refine.tests.preference;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.testng.annotations.Test;
|
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.starred-expressions\":{\"class\":\"com.google.refine.preference.TopList\",\"top\":2147483647,\"list\":[]},"
|
||||||
+ " \"scripting.expressions\":{\"class\":\"com.google.refine.preference.TopList\",\"top\":100,\"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();
|
PreferenceStore prefStore = new PreferenceStore();
|
||||||
prefStore.load(new JSONObject(json));
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user