Start to migrate ProjectMetadata to Jackson

This commit is contained in:
Antonin Delpeuch 2018-11-16 10:50:06 +00:00
parent 4a067cb110
commit 62190d36c0
3 changed files with 56 additions and 115 deletions

View File

@ -1,6 +1,7 @@
package com.google.refine.model.metadata; package com.google.refine.model.metadata;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.beanutils.PropertyUtils;
@ -8,6 +9,7 @@ import org.json.JSONObject;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.refine.util.ParsingUtilities;
public abstract class AbstractMetadata implements IMetadata { public abstract class AbstractMetadata implements IMetadata {
@JsonIgnore @JsonIgnore
@ -27,8 +29,9 @@ public abstract class AbstractMetadata implements IMetadata {
this.formatName = formatName; this.formatName = formatName;
} }
@Override public void loadFromJSON(String obj) throws IOException {
public abstract void loadFromJSON(JSONObject obj); ParsingUtilities.mapper.readerForUpdating(this).readValue(obj);
}
@Override @Override
public abstract void loadFromFile(File metadataFile); public abstract void loadFromFile(File metadataFile);

View File

@ -11,7 +11,6 @@ import org.json.JSONObject;
* Interface to import/export metadata * Interface to import/export metadata
*/ */
public interface IMetadata { public interface IMetadata {
public void loadFromJSON(JSONObject obj);
public void loadFromFile(File metadataFile); public void loadFromFile(File metadataFile);

View File

@ -48,6 +48,7 @@ import java.util.Map;
import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.json.JSONArray; import org.json.JSONArray;
@ -57,12 +58,15 @@ import org.json.JSONTokener;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRawValue; import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.annotation.JsonUnwrapped; import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.refine.ProjectManager; import com.google.refine.ProjectManager;
import com.google.refine.preference.PreferenceStore; import com.google.refine.preference.PreferenceStore;
@ -77,7 +81,7 @@ public class ProjectMetadata extends AbstractMetadata {
final public static String OLD_FILE_NAME = "metadata.old.json"; final public static String OLD_FILE_NAME = "metadata.old.json";
@JsonProperty("created") @JsonProperty("created")
private final LocalDateTime _created; private LocalDateTime _created;
@JsonProperty("name") @JsonProperty("name")
private String _name = ""; private String _name = "";
@JsonProperty("password") @JsonProperty("password")
@ -93,7 +97,8 @@ public class ProjectMetadata extends AbstractMetadata {
@JsonProperty("rowCount") @JsonProperty("rowCount")
private int _rowCount; private int _rowCount;
// user metadata // user metadata
private JSONArray _userMetadata = new JSONArray(); @JsonIgnore
private ArrayNode _userMetadata = ParsingUtilities.mapper.createArrayNode();
// _tags maps to keywords of the data package metadata // _tags maps to keywords of the data package metadata
@JsonProperty("tags") @JsonProperty("tags")
@ -108,9 +113,10 @@ public class ProjectMetadata extends AbstractMetadata {
private String _description = ""; // free form of comment private String _description = ""; // free form of comment
// import options is an array for 1-n data sources // import options is an array for 1-n data sources
private JSONArray _importOptionMetadata = new JSONArray(); @JsonIgnore
private ArrayNode _importOptionMetadata = ParsingUtilities.mapper.createArrayNode();
@JsonUnwrapped @JsonProperty("customMetadata")
private Map<String, Serializable> _customMetadata = new HashMap<String, Serializable>(); private Map<String, Serializable> _customMetadata = new HashMap<String, Serializable>();
@JsonProperty("preferences") @JsonProperty("preferences")
@JsonView(JsonViews.SaveMode.class) @JsonView(JsonViews.SaveMode.class)
@ -128,24 +134,40 @@ public class ProjectMetadata extends AbstractMetadata {
@JsonProperty("version") @JsonProperty("version")
private String version = ""; private String version = "";
@JsonProperty("userMetadata") @JsonProperty(PreferenceStore.USER_METADATA_KEY)
@JsonRawValue
@JsonInclude(Include.NON_NULL) @JsonInclude(Include.NON_NULL)
public String getJsonUserMetadata() { public ArrayNode getJsonUserMetadata() {
if (_userMetadata.length() > 0) { if (_userMetadata.size() > 0) {
return _userMetadata.toString(); return _userMetadata;
}
return null;
}
@JsonProperty(PreferenceStore.USER_METADATA_KEY)
protected void setUserMetadataJson(ArrayNode json) {
_userMetadata = json;
}
@JsonProperty("importOptionMetadata")
@JsonInclude(Include.NON_NULL)
public ArrayNode getJsonImportOptionMetadata() {
if (_importOptionMetadata.size() > 0) {
return _importOptionMetadata;
} }
return null; return null;
} }
@JsonProperty("importOptionMetadata") @JsonProperty("importOptionMetadata")
@JsonRawValue public void setImportOptionMetadataJson(ArrayNode options) {
@JsonInclude(Include.NON_NULL) _importOptionMetadata = options;
public String getJsonImportOptionMetadata() { // this field should always be present so we can update the last updated time here
if (_importOptionMetadata.length() > 0) { this.written = LocalDateTime.now();
return _importOptionMetadata.toString();
} }
return null;
// backwards compatibility
@JsonProperty("expressions")
protected void setExpressions(TopList expressions) {
this._preferenceStore.put("scripting.expressions", expressions);
} }
private final static Logger logger = LoggerFactory.getLogger("project_metadata"); private final static Logger logger = LoggerFactory.getLogger("project_metadata");
@ -180,91 +202,6 @@ public class ProjectMetadata extends AbstractMetadata {
return null; return null;
} }
public void loadFromJSON(JSONObject obj) {
extractModifiedLocalTime(obj);
this._name = JSONUtilities.getString(obj, "name", "<Error recovering project name>");
this._password = JSONUtilities.getString(obj, "password", "");
this._encoding = JSONUtilities.getString(obj, "encoding", "");
this._encodingConfidence = JSONUtilities.getInt(obj, "encodingConfidence", 0);
this._creator = JSONUtilities.getString(obj, "creator", "");
this._contributors = JSONUtilities.getString(obj, "contributors", "");
this._subject = JSONUtilities.getString(obj, "subject", "");
this._description = JSONUtilities.getString(obj, "description", "");
this._rowCount = JSONUtilities.getInt(obj, "rowCount", 0);
this.title = JSONUtilities.getString(obj, "title", "");
this.homepage = JSONUtilities.getString(obj, "homepage", "");
this.image = JSONUtilities.getString(obj, "image", "");
this.license = JSONUtilities.getString(obj, "license", "");
this.version = JSONUtilities.getString(obj, "version", "");
this._tags = JSONUtilities.getStringArray(obj, "tags");
if (obj.has("preferences") && !obj.isNull("preferences")) {
try {
this._preferenceStore = ParsingUtilities.mapper.readValue(obj.getJSONObject("preferences").toString(), PreferenceStore.class);
} catch (IOException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
try {
TopList newExpressions = ParsingUtilities.mapper.readValue(obj.getJSONArray("expressions").toString(), TopList.class);
this._preferenceStore.put("scripting.expressions", newExpressions);
} catch (IOException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
if (obj.has("customMetadata") && !obj.isNull("customMetadata")) {
try {
JSONObject obj2 = obj.getJSONObject("customMetadata");
Iterator<String> keys = obj2.keys();
while (keys.hasNext()) {
String key = keys.next();
Object value = obj2.get(key);
if (value != null && value instanceof Serializable) {
this._customMetadata.put(key, (Serializable) value);
}
}
} catch (JSONException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
if (obj.has("importOptionMetadata") && !obj.isNull("importOptionMetadata")) {
try {
JSONArray jsonArray = obj.getJSONArray("importOptionMetadata");
this._importOptionMetadata = jsonArray;
} catch (JSONException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
if (obj.has(PreferenceStore.USER_METADATA_KEY) && !obj.isNull(PreferenceStore.USER_METADATA_KEY)) {
try {
JSONArray jsonArray = obj.getJSONArray(PreferenceStore.USER_METADATA_KEY);
this._userMetadata = jsonArray;
} catch (JSONException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
this.written = LocalDateTime.now(); // Mark it as not needing writing until modified
}
private void extractModifiedLocalTime(JSONObject obj) {
String modified = JSONUtilities.getString(obj, "modified", LocalDateTime.now().toString());
this._modified = ParsingUtilities.stringToLocalDate(modified);
}
static protected void preparePreferenceStore(PreferenceStore ps) { static protected void preparePreferenceStore(PreferenceStore ps) {
ProjectManager.preparePreferenceStore(ps); ProjectManager.preparePreferenceStore(ps);
// Any project specific preferences? // Any project specific preferences?
@ -353,17 +290,19 @@ public class ProjectMetadata extends AbstractMetadata {
updateModified(); updateModified();
} }
public JSONArray getImportOptionMetadata() { @JsonIgnore
public ArrayNode getImportOptionMetadata() {
return _importOptionMetadata; return _importOptionMetadata;
} }
public void setImportOptionMetadata(JSONArray jsonArray) { @JsonIgnore
public void setImportOptionMetadata(ArrayNode jsonArray) {
_importOptionMetadata = jsonArray; _importOptionMetadata = jsonArray;
updateModified(); updateModified();
} }
public void appendImportOptionMetadata(ObjectNode options) { public void appendImportOptionMetadata(ObjectNode options) {
_importOptionMetadata.put(options); _importOptionMetadata.add(options);
updateModified(); updateModified();
} }
@ -477,20 +416,20 @@ public class ProjectMetadata extends AbstractMetadata {
updateModified(); updateModified();
} }
public JSONArray getUserMetadata() { public ArrayNode getUserMetadata() {
return _userMetadata; return _userMetadata;
} }
public void setUserMetadata(JSONArray userMetadata) { public void setUserMetadata(ArrayNode userMetadata) {
this._userMetadata = userMetadata; this._userMetadata = userMetadata;
} }
private void updateUserMetadata(String metaName, String valueString) { private void updateUserMetadata(String metaName, String valueString) {
for (int i = 0; i < _userMetadata.length(); i++) { for (int i = 0; i < _userMetadata.size(); i++) {
try { try {
JSONObject obj = _userMetadata.getJSONObject(i); JsonNode obj = _userMetadata.get(i);
if (obj.getString("name").equals(metaName)) { if (obj.get("name").asText("").equals(metaName)) {
obj.put("value", valueString); ((ObjectNode) obj).put("value", valueString);
} }
} catch (JSONException e) { } catch (JSONException e) {
logger.error(ExceptionUtils.getStackTrace(e)); logger.error(ExceptionUtils.getStackTrace(e));
@ -530,7 +469,7 @@ public class ProjectMetadata extends AbstractMetadata {
JSONTokener tokener = new JSONTokener(reader); JSONTokener tokener = new JSONTokener(reader);
JSONObject obj = (JSONObject) tokener.nextValue(); JSONObject obj = (JSONObject) tokener.nextValue();
this.loadFromJSON(obj); this.loadFromJSON(IOUtils.toString(inputStream));
} catch (IOException e) { } catch (IOException e) {
logger.error(ExceptionUtils.getStackTrace(e)); logger.error(ExceptionUtils.getStackTrace(e));
} }