Jackson serialization for project managers
This commit is contained in:
parent
49b84574da
commit
987c2d1c80
@ -54,6 +54,9 @@ import org.json.JSONObject;
|
|||||||
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.JsonProperty;
|
||||||
|
|
||||||
import com.google.refine.history.HistoryEntryManager;
|
import com.google.refine.history.HistoryEntryManager;
|
||||||
import com.google.refine.model.Project;
|
import com.google.refine.model.Project;
|
||||||
import com.google.refine.model.metadata.IMetadata;
|
import com.google.refine.model.metadata.IMetadata;
|
||||||
@ -342,6 +345,7 @@ public abstract class ProjectManager {
|
|||||||
/**
|
/**
|
||||||
* Gets the InterProjectModel from memory
|
* Gets the InterProjectModel from memory
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnore
|
||||||
public InterProjectModel getInterProjectModel() {
|
public InterProjectModel getInterProjectModel() {
|
||||||
return _interProjectModel;
|
return _interProjectModel;
|
||||||
}
|
}
|
||||||
@ -472,7 +476,7 @@ public abstract class ProjectManager {
|
|||||||
* Gets all the project Metadata currently held in memory.
|
* Gets all the project Metadata currently held in memory.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnore
|
||||||
public Map<Long, ProjectMetadata> getAllProjectMetadata() {
|
public Map<Long, ProjectMetadata> getAllProjectMetadata() {
|
||||||
for(Project project : _projects.values()) {
|
for(Project project : _projects.values()) {
|
||||||
mergeEmptyUserMetadata(project.getMetadata());
|
mergeEmptyUserMetadata(project.getMetadata());
|
||||||
@ -486,6 +490,7 @@ public abstract class ProjectManager {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnore
|
||||||
public Map<String, Integer> getAllProjectTags() {
|
public Map<String, Integer> getAllProjectTags() {
|
||||||
return _projectsTags;
|
return _projectsTags;
|
||||||
}
|
}
|
||||||
@ -517,6 +522,7 @@ public abstract class ProjectManager {
|
|||||||
* Gets the preference store
|
* Gets the preference store
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@JsonProperty("preferences")
|
||||||
public PreferenceStore getPreferenceStore() {
|
public PreferenceStore getPreferenceStore() {
|
||||||
return _preferenceStore;
|
return _preferenceStore;
|
||||||
}
|
}
|
||||||
@ -525,6 +531,7 @@ public abstract class ProjectManager {
|
|||||||
* Gets all expressions from the preference store
|
* Gets all expressions from the preference store
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnore
|
||||||
public List<String> getExpressions() {
|
public List<String> getExpressions() {
|
||||||
return ((TopList) _preferenceStore.get("scripting.expressions")).getList();
|
return ((TopList) _preferenceStore.get("scripting.expressions")).getList();
|
||||||
}
|
}
|
||||||
@ -533,6 +540,7 @@ public abstract class ProjectManager {
|
|||||||
* The history entry manager deals with changes
|
* The history entry manager deals with changes
|
||||||
* @return manager for handling history
|
* @return manager for handling history
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnore
|
||||||
public abstract HistoryEntryManager getHistoryEntryManager();
|
public abstract HistoryEntryManager getHistoryEntryManager();
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,9 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
@ -57,6 +59,10 @@ import org.json.JSONWriter;
|
|||||||
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.JsonProperty;
|
||||||
|
|
||||||
|
import com.google.refine.Jsonizable;
|
||||||
import com.google.refine.ProjectManager;
|
import com.google.refine.ProjectManager;
|
||||||
import com.google.refine.history.HistoryEntryManager;
|
import com.google.refine.history.HistoryEntryManager;
|
||||||
import com.google.refine.model.Project;
|
import com.google.refine.model.Project;
|
||||||
@ -67,7 +73,7 @@ import com.google.refine.model.metadata.ProjectMetadata;
|
|||||||
import com.google.refine.preference.TopList;
|
import com.google.refine.preference.TopList;
|
||||||
|
|
||||||
|
|
||||||
public class FileProjectManager extends ProjectManager {
|
public class FileProjectManager extends ProjectManager implements Jsonizable {
|
||||||
final static protected String PROJECT_DIR_SUFFIX = ".project";
|
final static protected String PROJECT_DIR_SUFFIX = ".project";
|
||||||
|
|
||||||
protected File _workspaceDir;
|
protected File _workspaceDir;
|
||||||
@ -95,6 +101,7 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
public File getWorkspaceDir() {
|
public File getWorkspaceDir() {
|
||||||
return _workspaceDir;
|
return _workspaceDir;
|
||||||
}
|
}
|
||||||
@ -107,6 +114,7 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
public File getProjectDir(long projectID) {
|
public File getProjectDir(long projectID) {
|
||||||
return getProjectDir(_workspaceDir, projectID);
|
return getProjectDir(_workspaceDir, projectID);
|
||||||
}
|
}
|
||||||
@ -267,6 +275,7 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
@Override
|
@Override
|
||||||
protected void saveWorkspace() {
|
protected void saveWorkspace() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
// TODO refactor this so that we check if the save is needed before writing to the file!
|
||||||
File tempFile = new File(_workspaceDir, "workspace.temp.json");
|
File tempFile = new File(_workspaceDir, "workspace.temp.json");
|
||||||
try {
|
try {
|
||||||
if (!saveToFile(tempFile)) {
|
if (!saveToFile(tempFile)) {
|
||||||
@ -294,39 +303,32 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tempFile.renameTo(file);
|
tempFile.renameTo(file);
|
||||||
|
|
||||||
logger.info("Saved workspace");
|
logger.info("Saved workspace");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean saveNeeded() {
|
||||||
|
boolean projectSaveNeeded = _projectsMetadata.entrySet().stream()
|
||||||
|
.anyMatch(e -> e.getValue() != null && e.getValue().isDirty());
|
||||||
|
return projectSaveNeeded || _preferenceStore.isDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void saveProjectMetadata() throws JSONException, IOException {
|
||||||
|
for(Entry<Long,ProjectMetadata> entry : _projectsMetadata.entrySet()) {
|
||||||
|
ProjectMetadata metadata = entry.getValue();
|
||||||
|
if (metadata != null && metadata.isDirty()) {
|
||||||
|
ProjectMetadataUtilities.save(metadata, getProjectDir(entry.getKey()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean saveToFile(File file) throws IOException, JSONException {
|
protected boolean saveToFile(File file) throws IOException, JSONException {
|
||||||
FileWriter writer = new FileWriter(file);
|
FileWriter writer = new FileWriter(file);
|
||||||
boolean saveWasNeeded = false;
|
boolean saveWasNeeded = saveNeeded();
|
||||||
try {
|
try {
|
||||||
JSONWriter jsonWriter = new JSONWriter(writer);
|
JSONWriter jsonWriter = new JSONWriter(writer);
|
||||||
jsonWriter.object();
|
write(jsonWriter, new Properties());
|
||||||
jsonWriter.key("projectIDs");
|
saveProjectMetadata();
|
||||||
jsonWriter.array();
|
|
||||||
for (Long id : _projectsMetadata.keySet()) {
|
|
||||||
ProjectMetadata metadata = _projectsMetadata.get(id);
|
|
||||||
if (metadata != null) {
|
|
||||||
jsonWriter.value(id);
|
|
||||||
if (metadata.isDirty()) {
|
|
||||||
Project project = ProjectManager.singleton.getProject(id);
|
|
||||||
metadata.setRowCount(project.rows.size());
|
|
||||||
ProjectMetadataUtilities.save(metadata, getProjectDir(id));
|
|
||||||
saveWasNeeded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jsonWriter.endArray();
|
|
||||||
writer.write('\n');
|
|
||||||
|
|
||||||
jsonWriter.key("preferences");
|
|
||||||
saveWasNeeded |= _preferenceStore.isDirty();
|
|
||||||
_preferenceStore.write(jsonWriter, new Properties());
|
|
||||||
|
|
||||||
jsonWriter.endObject();
|
|
||||||
} finally {
|
} finally {
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
@ -370,7 +372,7 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
}
|
}
|
||||||
logger.error("Failed to load workspace from any attempted alternatives.");
|
logger.error("Failed to load workspace from any attempted alternatives.");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean loadFromFile(File file) {
|
protected boolean loadFromFile(File file) {
|
||||||
logger.info("Loading workspace: {}", file.getAbsolutePath());
|
logger.info("Loading workspace: {}", file.getAbsolutePath());
|
||||||
|
|
||||||
@ -484,4 +486,28 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
gos.close();
|
gos.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JSONWriter jsonWriter, Properties options)
|
||||||
|
throws JSONException {
|
||||||
|
jsonWriter.object();
|
||||||
|
jsonWriter.key("projectIDs");
|
||||||
|
jsonWriter.array();
|
||||||
|
for (Long id : _projectsMetadata.keySet()) {
|
||||||
|
ProjectMetadata metadata = _projectsMetadata.get(id);
|
||||||
|
if (metadata != null) {
|
||||||
|
jsonWriter.value(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonWriter.endArray();
|
||||||
|
|
||||||
|
jsonWriter.key("preferences");
|
||||||
|
_preferenceStore.write(jsonWriter, new Properties());
|
||||||
|
jsonWriter.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("projectIDs")
|
||||||
|
public Set<Long> getProjectIds() {
|
||||||
|
return _projectsMetadata.keySet();
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.google.refine.tests.io;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import com.google.refine.io.FileProjectManager;
|
||||||
|
import com.google.refine.model.metadata.ProjectMetadata;
|
||||||
|
import com.google.refine.tests.RefineTest;
|
||||||
|
import com.google.refine.tests.util.TestUtils;
|
||||||
|
|
||||||
|
public class FileProjectManagerTests extends RefineTest {
|
||||||
|
|
||||||
|
protected class FileProjectManagerStub extends FileProjectManager {
|
||||||
|
|
||||||
|
protected FileProjectManagerStub(File dir) {
|
||||||
|
super(dir);
|
||||||
|
_projectsMetadata.put(1234L, mock(ProjectMetadata.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serializeFileProjectManager() {
|
||||||
|
FileProjectManager manager = new FileProjectManagerStub(workspaceDir);
|
||||||
|
String json = "{\n" +
|
||||||
|
" \"preferences\" : {\n" +
|
||||||
|
" \"entries\" : {\n" +
|
||||||
|
" \"scripting.expressions\" : {\n" +
|
||||||
|
" \"class\" : \"com.google.refine.preference.TopList\",\n" +
|
||||||
|
" \"list\" : [ ],\n" +
|
||||||
|
" \"top\" : 100\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"scripting.starred-expressions\" : {\n" +
|
||||||
|
" \"class\" : \"com.google.refine.preference.TopList\",\n" +
|
||||||
|
" \"list\" : [ ],\n" +
|
||||||
|
" \"top\" : 2147483647\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"projectIDs\" : [ 1234 ]\n" +
|
||||||
|
" }";
|
||||||
|
TestUtils.isSerializedTo(manager, json);
|
||||||
|
}
|
||||||
|
}
|
@ -7,19 +7,22 @@ import org.json.JSONObject;
|
|||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
public class PreferenceStoreTests {
|
public class PreferenceStoreTests {
|
||||||
|
public static String json = "{"
|
||||||
|
+ "\"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\":[]}"
|
||||||
|
+ "}}";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serializePreferenceStore() {
|
public void serializePreferenceStore() {
|
||||||
String json = "{"
|
|
||||||
+ "\"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\":[]}"
|
|
||||||
+ "}}";
|
|
||||||
String jsonAfter = "{"
|
String jsonAfter = "{"
|
||||||
+ "\"entries\":{"
|
+ "\"entries\":{"
|
||||||
+ " \"reconciliation.standardServices\":["
|
+ " \"reconciliation.standardServices\":["
|
||||||
|
Loading…
Reference in New Issue
Block a user