Save project metadata to disk as JSON now rather than through Java serialization API.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@199 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-03-04 19:15:46 +00:00
parent a8177131b4
commit 1dc3d4abbd
4 changed files with 272 additions and 86 deletions

View File

@ -3,6 +3,8 @@ package com.metaweb.gridworks;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
@ -11,10 +13,18 @@ import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.json.JSONWriter;
import com.codeberry.jdatapath.DataPath; import com.codeberry.jdatapath.DataPath;
import com.codeberry.jdatapath.JDataPathSystem; import com.codeberry.jdatapath.JDataPathSystem;
import com.metaweb.gridworks.model.Project; import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.util.JSONUtilities;
public class ProjectManager implements Serializable { public class ProjectManager implements Serializable {
@ -33,10 +43,11 @@ public class ProjectManager implements Serializable {
if (singleton == null) { if (singleton == null) {
File dir = getProjectLocation(); File dir = getProjectLocation();
Gridworks.log("Using data directory: " + dir.getAbsolutePath()); Gridworks.log("Using data directory: " + dir.getAbsolutePath());
File file = new File(dir, "projects");
if (file.exists()) { if (dir.exists()) {
singleton = load(file); singleton = load(dir);
} else { }
if (singleton == null) {
singleton = new ProjectManager(dir); singleton = new ProjectManager(dir);
} }
} }
@ -80,54 +91,12 @@ public class ProjectManager implements Serializable {
} }
} }
static protected ProjectManager load(File file) {
Gridworks.log("Loading project metadata from " + file.getAbsolutePath());
ProjectManager pm = null;
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(file);
in = new ObjectInputStream(fis);
pm = (ProjectManager) in.readObject();
} catch(IOException e) {
e.printStackTrace();
} catch(ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (Exception e) {
}
}
if (in != null) {
try {
in.close();
} catch (Exception e) {
}
}
}
return pm;
}
private ProjectManager(File dir) { private ProjectManager(File dir) {
_dir = dir; _dir = dir;
_dir.mkdirs(); _dir.mkdirs();
_projectsMetadata = new HashMap<Long, ProjectMetadata>(); _projectsMetadata = new HashMap<Long, ProjectMetadata>();
_expressions = new LinkedList<String>(); _expressions = new LinkedList<String>();
internalInitialize();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
internalInitialize();
}
private void internalInitialize() {
_projects = new HashMap<Long, Project>(); _projects = new HashMap<Long, Project>();
} }
@ -202,30 +171,101 @@ public class ProjectManager implements Serializable {
public void save() { public void save() {
Gridworks.log("Saving project metadata ..."); Gridworks.log("Saving project metadata ...");
File file = new File(_dir, "projects"); File tempFile = new File(_dir, "projects.json.temp");
FileOutputStream fos = null;
ObjectOutputStream out = null;
try { try {
fos = new FileOutputStream(file); saveToFile(tempFile);
out = new ObjectOutputStream(fos); } catch (Exception e) {
out.writeObject(this);
out.flush();
} catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
Gridworks.log("Failed to save project");
return;
}
File file = new File(_dir, "projects.json");
File oldFile = new File(_dir, "projects.json.old");
if (file.exists()) {
file.renameTo(oldFile);
}
tempFile.renameTo(file);
if (oldFile.exists()) {
oldFile.delete();
}
Gridworks.log("Project metadata saved.");
}
public void saveToFile(File file) throws IOException, JSONException {
FileWriter writer = new FileWriter(file);
try {
JSONWriter jsonWriter = new JSONWriter(writer);
Properties options = new Properties();
options.setProperty("mode", "save");
jsonWriter.object();
jsonWriter.key("projectMetadata");
jsonWriter.array();
for (Long id : _projectsMetadata.keySet()) {
jsonWriter.object();
jsonWriter.key("id"); jsonWriter.value(id);
jsonWriter.key("metadata"); _projectsMetadata.get(id).write(jsonWriter, options);
jsonWriter.endObject();
writer.write('\n');
}
jsonWriter.endArray();
writer.write('\n');
jsonWriter.key("expressions"); JSONUtilities.writeStringList(jsonWriter, _expressions);
jsonWriter.endObject();
} finally { } finally {
if (fos != null) { writer.close();
}
}
static protected ProjectManager load(File dir) {
try { try {
fos.close(); return loadFromFile(new File(dir, "projects.json"));
} catch (Exception e) { } catch (Exception e) {
} }
}
if (out != null) {
try { try {
out.close(); return loadFromFile(new File(dir, "projects.json.temp"));
} catch (Exception e) { } catch (Exception e) {
} }
try {
return loadFromFile(new File(dir, "projects.json.old"));
} catch (Exception e) {
} }
return null;
}
static protected ProjectManager loadFromFile(File file) throws IOException, JSONException {
Gridworks.log("Loading project metadata from " + file.getAbsolutePath());
FileReader reader = new FileReader(file);
try {
JSONTokener tokener = new JSONTokener(reader);
ProjectManager pm = new ProjectManager(file.getParentFile());
JSONObject obj = (JSONObject) tokener.nextValue();
JSONArray a = obj.getJSONArray("projectMetadata");
int count = a.length();
for (int i = 0; i < count; i++) {
JSONObject obj2 = a.getJSONObject(i);
long id = obj2.getLong("id");
pm._projectsMetadata.put(id, ProjectMetadata.loadFromJSON(obj2.getJSONObject("metadata")));
}
JSONUtilities.getStringList(obj, "expressions", pm._expressions);
return pm;
} finally {
reader.close();
} }
} }

View File

@ -1,27 +1,71 @@
package com.metaweb.gridworks; package com.metaweb.gridworks;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
public class ProjectMetadata implements Serializable, Jsonizable { import com.metaweb.gridworks.util.JSONUtilities;
private static final long serialVersionUID = 7959027046468240844L; import com.metaweb.gridworks.util.ParsingUtilities;
public class ProjectMetadata implements Jsonizable {
private static final int s_expressionHistoryMax = 20; // last n expressions used in this project private static final int s_expressionHistoryMax = 20; // last n expressions used in this project
private final Date _created = new Date(); private final Date _created;
private Date _modified;
private String _name; private String _name;
private String _password; private String _password;
private String _encoding; private String _encoding;
private int _encodingConfidence; private int _encodingConfidence;
private Date _modified = new Date();
private List<String> _expressions = new LinkedList<String>(); private List<String> _expressions = new LinkedList<String>();
static public ProjectMetadata loadFromJSON(JSONObject obj) {
ProjectMetadata pm = new ProjectMetadata(JSONUtilities.getDate(obj, "modified", new Date()));
pm._modified = JSONUtilities.getDate(obj, "modified", new Date());
pm._name = JSONUtilities.getString(obj, "name", "<Error recovering project name>");
pm._password = JSONUtilities.getString(obj, "password", "");
pm._encoding = JSONUtilities.getString(obj, "encoding", "");
pm._encodingConfidence = JSONUtilities.getInt(obj, "encodingConfidence", 0);
JSONUtilities.getStringList(obj, "expressions", pm._expressions);
return pm;
}
protected ProjectMetadata(Date date) {
_created = date;
}
public ProjectMetadata() {
_created = new Date();
_modified = _created;
}
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("name"); writer.value(_name);
writer.key("created"); writer.value(ParsingUtilities.dateToString(_created));
writer.key("modified"); writer.value(ParsingUtilities.dateToString(_modified));
if ("save".equals(options.getProperty("mode"))) {
writer.key("password"); writer.value(_password);
writer.key("encoding"); writer.value(_encoding);
writer.key("encodingConfidence"); writer.value(_encodingConfidence);
writer.key("expressions"); JSONUtilities.writeStringList(writer, _expressions);
}
writer.endObject();
}
public Date getCreated() { public Date getCreated() {
return _created; return _created;
} }
@ -83,16 +127,4 @@ public class ProjectMetadata implements Serializable, Jsonizable {
public List<String> getExpressions() { public List<String> getExpressions() {
return _expressions; return _expressions;
} }
public void write(JSONWriter writer, Properties options)
throws JSONException {
SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.getDateTimeInstance();
writer.object();
writer.key("name"); writer.value(getName());
writer.key("created"); writer.value(sdf.format(getCreated()));
writer.key("modified"); writer.value(sdf.format(_modified));
writer.endObject();
}
} }

View File

@ -0,0 +1,97 @@
package com.metaweb.gridworks.util;
import java.util.Date;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
public class JSONUtilities {
static public String getString(JSONObject obj, String key, String def) {
try {
return obj.getString(key);
} catch (JSONException e) {
return def;
}
}
static public int getInt(JSONObject obj, String key, int def) {
try {
return obj.getInt(key);
} catch (JSONException e) {
return def;
}
}
static public boolean getBoolean(JSONObject obj, String key, boolean def) {
try {
return obj.getBoolean(key);
} catch (JSONException e) {
return def;
}
}
static public double getDouble(JSONObject obj, String key, double def) {
try {
return obj.getDouble(key);
} catch (JSONException e) {
return def;
}
}
static public long getLong(JSONObject obj, String key, long def) {
try {
return obj.getLong(key);
} catch (JSONException e) {
return def;
}
}
static public Date getDate(JSONObject obj, String key, Date def) {
try {
Date d = ParsingUtilities.stringToDate(obj.getString(key));
return d != null ? d : def;
} catch (JSONException e) {
return def;
}
}
static public String[] getStringArray(JSONObject obj, String key) {
try {
JSONArray a = obj.getJSONArray(key);
String[] r = new String[a.length()];
for (int i = 0; i < r.length; i++) {
r[i] = a.getString(i);
}
return r;
} catch (JSONException e) {
return new String[0];
}
}
static public void getStringList(JSONObject obj, String key, List<String> list) {
try {
JSONArray a = obj.getJSONArray(key);
int count = a.length();
for (int i = 0; i < count; i++) {
list.add(a.getString(i));
}
} catch (JSONException e) {
}
}
static public void writeStringList(JSONWriter writer, List<String> list) throws JSONException {
writer.array();
for (String s : list) {
writer.value(s);
}
writer.endArray();
}
}

View File

@ -5,6 +5,9 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.net.URLCodec; import org.apache.commons.codec.net.URLCodec;
@ -14,6 +17,8 @@ import org.json.JSONObject;
import org.json.JSONTokener; import org.json.JSONTokener;
public class ParsingUtilities { public class ParsingUtilities {
static public SimpleDateFormat s_sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
static public String inputStreamToString(InputStream is) throws IOException { static public String inputStreamToString(InputStream is) throws IOException {
Reader reader = new InputStreamReader(is, "UTF-8"); Reader reader = new InputStreamReader(is, "UTF-8");
try { try {
@ -65,4 +70,16 @@ public class ParsingUtilities {
return s; // should not happen return s; // should not happen
} }
} }
static public String dateToString(Date d) {
return s_sdf.format(d);
}
static public Date stringToDate(String s) {
try {
return s_sdf.parse(s);
} catch (ParseException e) {
return null;
}
}
} }