Jackson deserialization for PreferenceStore
This commit is contained in:
parent
5cf58d874b
commit
fc7da40055
@ -42,9 +42,11 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONTokener;
|
import org.json.JSONTokener;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.refine.ProjectManager;
|
import com.google.refine.ProjectManager;
|
||||||
import com.google.refine.model.Project;
|
import com.google.refine.model.Project;
|
||||||
import com.google.refine.preference.PreferenceStore;
|
import com.google.refine.preference.PreferenceStore;
|
||||||
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
public class SetPreferenceCommand extends Command {
|
public class SetPreferenceCommand extends Command {
|
||||||
@Override
|
@Override
|
||||||
@ -58,12 +60,12 @@ public class SetPreferenceCommand extends Command {
|
|||||||
String valueString = request.getParameter("value");
|
String valueString = request.getParameter("value");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object o = valueString == null ? null : new JSONTokener(valueString).nextValue();
|
JsonNode o = valueString == null ? null : ParsingUtilities.mapper.readTree(valueString);
|
||||||
|
|
||||||
ps.put(prefName, PreferenceStore.loadObject(o));
|
ps.put(prefName, PreferenceStore.loadObject(o));
|
||||||
|
|
||||||
respond(response, "{ \"code\" : \"ok\" }");
|
respond(response, "{ \"code\" : \"ok\" }");
|
||||||
} catch (JSONException e) {
|
} catch (IOException e) {
|
||||||
respondException(response, e);
|
respondException(response, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ import com.google.refine.model.metadata.DataPackageMetadata;
|
|||||||
import com.google.refine.model.metadata.IMetadata;
|
import com.google.refine.model.metadata.IMetadata;
|
||||||
import com.google.refine.model.metadata.MetadataFormat;
|
import com.google.refine.model.metadata.MetadataFormat;
|
||||||
import com.google.refine.model.metadata.ProjectMetadata;
|
import com.google.refine.model.metadata.ProjectMetadata;
|
||||||
|
import com.google.refine.preference.PreferenceStore;
|
||||||
import com.google.refine.preference.TopList;
|
import com.google.refine.preference.TopList;
|
||||||
import com.google.refine.util.ParsingUtilities;
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
@ -386,7 +387,7 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
|
|
||||||
// load global preferences firstly
|
// load global preferences firstly
|
||||||
if (obj.has("preferences") && !obj.isNull("preferences")) {
|
if (obj.has("preferences") && !obj.isNull("preferences")) {
|
||||||
_preferenceStore.load(obj.getJSONObject("preferences"));
|
_preferenceStore = ParsingUtilities.mapper.readValue(obj.getJSONObject("preferences").toString(), PreferenceStore.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray a = obj.getJSONArray("projectIDs");
|
JSONArray a = obj.getJSONArray("projectIDs");
|
||||||
@ -413,8 +414,8 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
|
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
|
||||||
((TopList) _preferenceStore.get("scripting.expressions"))
|
TopList newExpressions = ParsingUtilities.mapper.readValue(obj.getJSONArray("expressions").toString(), TopList.class);
|
||||||
.load(obj.getJSONArray("expressions"));
|
this._preferenceStore.put("scripting.expressions", newExpressions);
|
||||||
}
|
}
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -205,16 +205,17 @@ public class ProjectMetadata extends AbstractMetadata {
|
|||||||
|
|
||||||
if (obj.has("preferences") && !obj.isNull("preferences")) {
|
if (obj.has("preferences") && !obj.isNull("preferences")) {
|
||||||
try {
|
try {
|
||||||
this._preferenceStore.load(obj.getJSONObject("preferences"));
|
this._preferenceStore = ParsingUtilities.mapper.readValue(obj.getJSONObject("preferences").toString(), PreferenceStore.class);
|
||||||
} catch (JSONException e) {
|
} catch (IOException e) {
|
||||||
logger.error(ExceptionUtils.getStackTrace(e));
|
logger.error(ExceptionUtils.getStackTrace(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
|
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
|
||||||
try {
|
try {
|
||||||
((TopList) this._preferenceStore.get("scripting.expressions")).load(obj.getJSONArray("expressions"));
|
TopList newExpressions = ParsingUtilities.mapper.readValue(obj.getJSONArray("expressions").toString(), TopList.class);
|
||||||
} catch (JSONException e) {
|
this._preferenceStore.put("scripting.expressions", newExpressions);
|
||||||
|
} catch (IOException e) {
|
||||||
logger.error(ExceptionUtils.getStackTrace(e));
|
logger.error(ExceptionUtils.getStackTrace(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ 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.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -50,8 +49,9 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
|||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.google.refine.RefineServlet;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
public class PreferenceStore {
|
public class PreferenceStore {
|
||||||
public static final String USER_METADATA_KEY = "userMetadata";
|
public static final String USER_METADATA_KEY = "userMetadata";
|
||||||
@ -63,7 +63,6 @@ public class PreferenceStore {
|
|||||||
protected Map<String, Object> _prefs = new HashMap<>();
|
protected Map<String, Object> _prefs = new HashMap<>();
|
||||||
|
|
||||||
// Temporary wrapper while serialization has not been migrated yet.
|
// Temporary wrapper while serialization has not been migrated yet.
|
||||||
@JsonProperty("entries")
|
|
||||||
protected Map<String, Object> _prefsJackson = new HashMap<>();
|
protected Map<String, Object> _prefsJackson = new HashMap<>();
|
||||||
|
|
||||||
public void put(String key, Object value) {
|
public void put(String key, Object value) {
|
||||||
@ -119,39 +118,43 @@ public class PreferenceStore {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@JsonProperty("entries")
|
||||||
public void load(JSONObject obj) throws JSONException {
|
public void setEntries(JsonNode entries) throws JSONException {
|
||||||
if (obj.has("entries") && !obj.isNull("entries")) {
|
Iterator<String> i = entries.fieldNames();
|
||||||
JSONObject entries = obj.getJSONObject("entries");
|
|
||||||
|
|
||||||
Iterator<String> i = entries.keys();
|
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
String key = i.next();
|
String key = i.next();
|
||||||
if (!entries.isNull(key)) {
|
System.out.println(key);
|
||||||
Object o = entries.get(key), loaded = loadObject(o);
|
if (entries.get(key) != null) {
|
||||||
|
JsonNode o = entries.get(key);
|
||||||
|
Object loaded = loadObject(o);
|
||||||
_prefs.put(key, loaded);
|
_prefs.put(key, loaded);
|
||||||
_prefsJackson.put(key, wrapJSONArray(loaded));
|
_prefsJackson.put(key, wrapJSONArray(loaded));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dirty = false; // internal puts don't count
|
dirty = false; // internal puts don't count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonProperty("entries")
|
||||||
|
public Map<String, Object> getEntries() {
|
||||||
|
return _prefsJackson;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public Object loadObject(Object o) {
|
static public Object loadObject(JsonNode o) {
|
||||||
if (o instanceof JSONObject) {
|
System.out.println("loading");
|
||||||
|
System.out.println(o.toString());
|
||||||
try {
|
try {
|
||||||
JSONObject obj2 = (JSONObject) o;
|
if (o instanceof ObjectNode) {
|
||||||
String className = obj2.getString("class");
|
ObjectNode obj2 = (ObjectNode) o;
|
||||||
Class<?> klass = RefineServlet.getClass(className);
|
return ParsingUtilities.mapper.treeToValue(obj2, PreferenceValue.class);
|
||||||
Method method = klass.getMethod("load", JSONObject.class);
|
} else if (o instanceof ArrayNode) {
|
||||||
|
return o;
|
||||||
return method.invoke(null, obj2);
|
} else {
|
||||||
|
// basic datatypes (int, double, boolean, string)
|
||||||
|
return ParsingUtilities.mapper.treeToValue(o, Object.class);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,24 +38,32 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.collections.list.UnmodifiableList;
|
import org.apache.commons.collections.list.UnmodifiableList;
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
|
||||||
public class TopList implements Iterable<String> {
|
public class TopList implements Iterable<String>, PreferenceValue {
|
||||||
|
|
||||||
@JsonProperty("top")
|
@JsonProperty("top")
|
||||||
final protected int _top;
|
protected int _top = 10;
|
||||||
final protected List<String> _list = new ArrayList<String>();
|
protected List<String> _list = new ArrayList<String>();
|
||||||
|
|
||||||
public TopList(int top) {
|
public TopList(int top) {
|
||||||
_top = top;
|
_top = top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public TopList(
|
||||||
|
@JsonProperty("top")
|
||||||
|
int top,
|
||||||
|
@JsonProperty("list")
|
||||||
|
List<String> list) {
|
||||||
|
_top = top;
|
||||||
|
_list = list;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@JsonProperty("list")
|
@JsonProperty("list")
|
||||||
public List<String> getList() {
|
public List<String> getList() {
|
||||||
@ -75,30 +83,6 @@ public class TopList implements Iterable<String> {
|
|||||||
_list.remove(element);
|
_list.remove(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonProperty("class")
|
|
||||||
public String getClassName() {
|
|
||||||
return this.getClass().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
static public TopList load(JSONObject obj) throws JSONException {
|
|
||||||
int top = obj.has("top") && !obj.isNull("top") ? obj.getInt("top") : 10;
|
|
||||||
TopList tl = new TopList(top);
|
|
||||||
|
|
||||||
if (obj.has("list") && !obj.isNull("list")) {
|
|
||||||
JSONArray a = obj.getJSONArray("list");
|
|
||||||
|
|
||||||
tl.load(a);
|
|
||||||
}
|
|
||||||
return tl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load(JSONArray a) throws JSONException {
|
|
||||||
int length = a.length();
|
|
||||||
for (int i = 0; i < length && _list.size() < _top; i++) {
|
|
||||||
_list.add(a.getString(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public Iterator<String> iterator() {
|
public Iterator<String> iterator() {
|
||||||
|
@ -3,12 +3,15 @@ package com.google.refine.tests.preference;
|
|||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
import com.google.refine.preference.PreferenceStore;
|
import com.google.refine.preference.PreferenceStore;
|
||||||
import com.google.refine.tests.RefineTest;
|
|
||||||
import com.google.refine.tests.util.TestUtils;
|
import com.google.refine.tests.util.TestUtils;
|
||||||
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
public class PreferenceStoreTests {
|
public class PreferenceStoreTests {
|
||||||
public static String json = "{"
|
public static String json = "{"
|
||||||
@ -21,7 +24,7 @@ public class PreferenceStoreTests {
|
|||||||
+ "}}";
|
+ "}}";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serializePreferenceStore() {
|
public void serializePreferenceStore() throws JsonParseException, JsonMappingException, IOException {
|
||||||
|
|
||||||
String jsonAfter = "{"
|
String jsonAfter = "{"
|
||||||
+ "\"entries\":{"
|
+ "\"entries\":{"
|
||||||
@ -32,8 +35,7 @@ public class PreferenceStoreTests {
|
|||||||
+ " \"scripting.expressions\":{\"class\":\"com.google.refine.preference.TopList\",\"top\":100,\"list\":[]},"
|
+ " \"scripting.expressions\":{\"class\":\"com.google.refine.preference.TopList\",\"top\":100,\"list\":[]},"
|
||||||
+ " \"mypreference\":\"myvalue\""
|
+ " \"mypreference\":\"myvalue\""
|
||||||
+ "}}";
|
+ "}}";
|
||||||
PreferenceStore prefStore = new PreferenceStore();
|
PreferenceStore prefStore = ParsingUtilities.mapper.readValue(json, PreferenceStore.class);
|
||||||
prefStore.load(new JSONObject(json));
|
|
||||||
assertFalse(prefStore.isDirty());
|
assertFalse(prefStore.isDirty());
|
||||||
prefStore.put("mypreference", "myvalue");
|
prefStore.put("mypreference", "myvalue");
|
||||||
assertTrue(prefStore.isDirty());
|
assertTrue(prefStore.isDirty());
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
package com.google.refine.tests.preference;
|
package com.google.refine.tests.preference;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
import com.google.refine.preference.TopList;
|
import com.google.refine.preference.TopList;
|
||||||
import com.google.refine.tests.util.TestUtils;
|
import com.google.refine.tests.util.TestUtils;
|
||||||
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
public class TopListTests {
|
public class TopListTests {
|
||||||
@Test
|
@Test
|
||||||
public void serializeTopList() {
|
public void serializeTopList() throws JsonParseException, JsonMappingException, IOException {
|
||||||
String json = "{"
|
String json = "{"
|
||||||
+ "\"class\":\"com.google.refine.preference.TopList\","
|
+ "\"class\":\"com.google.refine.preference.TopList\","
|
||||||
+ "\"top\":100,"
|
+ "\"top\":100,"
|
||||||
@ -21,7 +25,7 @@ public class TopListTests {
|
|||||||
+ " \"grel:\\\"https://pub.orcid.org/\\\"+value+\\\"/employments\\\"\""
|
+ " \"grel:\\\"https://pub.orcid.org/\\\"+value+\\\"/employments\\\"\""
|
||||||
+ "]}";
|
+ "]}";
|
||||||
TestUtils.isSerializedTo(
|
TestUtils.isSerializedTo(
|
||||||
TopList.load(new JSONObject(json)),
|
ParsingUtilities.mapper.readValue(json, TopList.class),
|
||||||
json);
|
json);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user