Major refactoring:

- Made all Change classes save to and load from .zip files.
- Changed Column.headerLabel to Column.name.
- Save project's raw data to "raw-data" file for now. We'll make it save to a zip file next.


git-svn-id: http://google-refine.googlecode.com/svn/trunk@217 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-03-06 07:43:45 +00:00
parent 589b9cd936
commit 78b1eb7e73
44 changed files with 988 additions and 244 deletions

View File

@ -31,7 +31,7 @@ public class ProjectManager implements Serializable {
private static final long serialVersionUID = -2967415873336723962L;
private static final int s_expressionHistoryMax = 100; // last n expressions used across all projects
protected File _dir;
protected File _workspaceDir;
protected Map<Long, ProjectMetadata> _projectsMetadata;
protected List<String> _expressions;
@ -92,16 +92,24 @@ public class ProjectManager implements Serializable {
}
private ProjectManager(File dir) {
_dir = dir;
_dir.mkdirs();
_workspaceDir = dir;
_workspaceDir.mkdirs();
_projectsMetadata = new HashMap<Long, ProjectMetadata>();
_expressions = new LinkedList<String>();
_projects = new HashMap<Long, Project>();
}
public File getDataDir() {
return _dir;
public File getWorkspaceDir() {
return _workspaceDir;
}
public File getProjectDir(long projectID) {
File dir = new File(_workspaceDir, projectID + ".project");
if (!dir.exists()) {
dir.mkdir();
}
return dir;
}
public void registerProject(Project project, ProjectMetadata projectMetadata) {
@ -121,7 +129,7 @@ public class ProjectManager implements Serializable {
if (_projects.containsKey(id)) {
return _projects.get(id);
} else {
File file = new File(_dir, id + ".project");
File file = new File(getProjectDir(id), "raw-data");
Project project = null;
FileInputStream fis = null;
@ -171,7 +179,7 @@ public class ProjectManager implements Serializable {
public void save() {
Gridworks.log("Saving project metadata ...");
File tempFile = new File(_dir, "projects.json.temp");
File tempFile = new File(_workspaceDir, "projects.json.temp");
try {
saveToFile(tempFile);
} catch (Exception e) {
@ -181,8 +189,8 @@ public class ProjectManager implements Serializable {
return;
}
File file = new File(_dir, "projects.json");
File oldFile = new File(_dir, "projects.json.old");
File file = new File(_workspaceDir, "projects.json");
File oldFile = new File(_workspaceDir, "projects.json.old");
if (file.exists()) {
file.renameTo(oldFile);
@ -281,7 +289,7 @@ public class ProjectManager implements Serializable {
}
protected void saveProject(Project project) {
File file = new File(_dir, project.id + ".project");
File file = new File(getProjectDir(project.id), "raw-data");
FileOutputStream fos = null;
ObjectOutputStream out = null;
@ -313,7 +321,7 @@ public class ProjectManager implements Serializable {
_projects.remove(project.id);
_projectsMetadata.remove(project.id);
File file = new File(_dir, project.id + ".project");
File file = new File(getProjectDir(project.id), "raw-data");
if (file.exists()) {
file.delete();
}

View File

@ -17,7 +17,7 @@ public class AddColumnCommand extends EngineDependentCommand {
String baseColumnName = request.getParameter("baseColumnName");
String expression = request.getParameter("expression");
String headerLabel = request.getParameter("headerLabel");
String newColumnName = request.getParameter("newColumnName");
int columnInsertIndex = Integer.parseInt(request.getParameter("columnInsertIndex"));
String onError = request.getParameter("onError");
@ -26,7 +26,7 @@ public class AddColumnCommand extends EngineDependentCommand {
baseColumnName,
expression,
TextTransformOperation.stringToOnError(onError),
headerLabel,
newColumnName,
columnInsertIndex
);
}

View File

@ -1,6 +1,6 @@
package com.metaweb.gridworks.commands.edit;
import java.io.IOException;
import java.io.IOException;
import java.io.Serializable;
import java.util.Properties;
@ -11,13 +11,11 @@ import javax.servlet.http.HttpServletResponse;
import org.json.JSONWriter;
import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.expr.ExpressionUtils;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.Cell;
import com.metaweb.gridworks.model.Column;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.Recon;
import com.metaweb.gridworks.model.changes.CellChange;
import com.metaweb.gridworks.process.QuickHistoryEntryProcess;
import com.metaweb.gridworks.util.ParsingUtilities;
@ -104,7 +102,7 @@ public class EditOneCellCommand extends Command {
String description =
"Edit single cell on row " + (rowIndex + 1) +
", column " + column.getHeaderLabel();
", column " + column.getName();
Change change = new CellChange(rowIndex, cellIndex, cell, newCell);

View File

@ -118,7 +118,7 @@ public class ReconJudgeOneCellCommand extends Command {
String cellDescription =
"single cell on row " + (rowIndex + 1) +
", column " + column.getHeaderLabel() +
", column " + column.getName() +
", containing \"" + cell.value + "\"";
String description = null;
@ -166,7 +166,7 @@ public class ReconJudgeOneCellCommand extends Command {
Change change = new ReconChange(
new CellChange(rowIndex, cellIndex, cell, newCell),
column.getHeaderLabel(),
column.getName(),
column.getReconConfig(),
stats
);

View File

@ -25,7 +25,7 @@ public class TsvExporter implements Exporter {
} else {
writer.write("\t");
}
writer.write(column.getHeaderLabel());
writer.write(column.getName());
}
writer.write("\n");

View File

@ -1,10 +1,14 @@
package com.metaweb.gridworks.history;
import java.io.Serializable;
import java.io.IOException;
import java.io.Writer;
import java.util.Properties;
import com.metaweb.gridworks.model.Project;
public interface Change extends Serializable {
public interface Change {
public void apply(Project project);
public void revert(Project project);
public void save(Writer writer, Properties options) throws IOException;
}

View File

@ -1,10 +1,13 @@
package com.metaweb.gridworks.history;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.Properties;
import com.metaweb.gridworks.model.Project;
public class ChangeSequence implements Change {
private static final long serialVersionUID = 5029993970500006428L;
final protected Change[] _changes;
public ChangeSequence(Change[] changes) {
@ -27,4 +30,34 @@ public class ChangeSequence implements Change {
}
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("count="); writer.write(Integer.toString(_changes.length)); writer.write('\n');
for (int i = 0; i < _changes.length; i++) {
Change change = _changes[i];
writer.write(change.getClass().getName()); writer.write('\n');
change.save(writer, options);
}
writer.write("/ec/\n"); // end of change marker
}
static public Change load(LineNumberReader reader) throws Exception {
String line = reader.readLine();
int equal = line.indexOf('=');
assert "count".equals(line.substring(0, equal));
int count = Integer.parseInt(line.substring(equal + 1));
Change[] changes = new Change[count];
for (int i = 0; i < count; i++) {
changes[i] = History.readOneChange(reader);
}
line = reader.readLine();
assert "/ec/".equals(line);
return new ChangeSequence(changes);
}
}

View File

@ -1,6 +1,8 @@
package com.metaweb.gridworks.history;
import java.io.LineNumberReader;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@ -16,6 +18,20 @@ import com.metaweb.gridworks.model.Project;
public class History implements Serializable, Jsonizable {
private static final long serialVersionUID = -1529783362243627391L;
static public Change readOneChange(LineNumberReader reader) throws Exception {
String className = reader.readLine();
Class<? extends Change> klass = getChangeClass(className);
Method load = klass.getMethod("load", LineNumberReader.class);
return (Change) load.invoke(null, reader);
}
@SuppressWarnings("unchecked")
static public Class<? extends Change> getChangeClass(String className) throws ClassNotFoundException {
return (Class<? extends Change>) Class.forName(className);
}
protected long _projectID;
protected List<HistoryEntry> _pastEntries;
protected List<HistoryEntry> _futureEntries;
@ -30,11 +46,11 @@ public class History implements Serializable, Jsonizable {
for (HistoryEntry entry2 : _futureEntries) {
entry2.delete();
}
_futureEntries.clear();
_pastEntries.add(entry);
entry.apply(ProjectManager.singleton.getProject(_projectID));
_pastEntries.add(entry);
_futureEntries.clear();
setModified();
}
@ -89,11 +105,13 @@ public class History implements Serializable, Jsonizable {
Project project = ProjectManager.singleton.getProject(_projectID);
while (times > 0 && _pastEntries.size() > 0) {
HistoryEntry entry = _pastEntries.remove(_pastEntries.size() - 1);
times--;
HistoryEntry entry = _pastEntries.get(_pastEntries.size() - 1);
entry.revert(project);
times--;
_pastEntries.remove(_pastEntries.size() - 1);
_futureEntries.add(0, entry);
}
setModified();
@ -103,12 +121,14 @@ public class History implements Serializable, Jsonizable {
Project project = ProjectManager.singleton.getProject(_projectID);
while (times > 0 && _futureEntries.size() > 0) {
HistoryEntry entry = _futureEntries.remove(0);
times--;
HistoryEntry entry = _futureEntries.get(0);
entry.apply(project);
times--;
_pastEntries.add(entry);
_futureEntries.remove(0);
}
setModified();
}

View File

@ -1,15 +1,20 @@
package com.metaweb.gridworks.history;
import java.io.File;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.json.JSONException;
import org.json.JSONWriter;
@ -56,12 +61,23 @@ public class HistoryEntry implements Serializable, Jsonizable {
if (_change == null) {
loadChange();
}
_change.apply(project);
// When a change is applied, it can hang on to old data (in order to be able
// to revert later). Hence, we need to save the change out.
saveChange();
synchronized (project) {
_change.apply(project);
// When a change is applied, it can hang on to old data (in order to be able
// to revert later). Hence, we need to save the change out.
try {
saveChange();
} catch (IOException e) {
e.printStackTrace();
_change.revert(project);
throw new RuntimeException("Failed to apply change", e);
}
}
}
public void revert(Project project) {
@ -72,75 +88,79 @@ public class HistoryEntry implements Serializable, Jsonizable {
}
public void delete() {
File file = getFile();
File file = getChangeFile();
if (file.exists()) {
file.delete();
}
}
protected void loadChange() {
File file = getFile();
File changeFile = getChangeFile();
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(file);
in = new ObjectInputStream(fis);
_change = (Change) 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) {
}
}
loadChange(changeFile);
} catch (Exception e) {
throw new RuntimeException("Failed to load change file " + changeFile.getAbsolutePath(), e);
}
}
protected void saveChange() {
File file = getFile();
FileOutputStream fos = null;
ObjectOutputStream out = null;
protected void loadChange(File file) throws Exception {
ZipInputStream in = new ZipInputStream(new FileInputStream(file));
try {
fos = new FileOutputStream(file);
out = new ObjectOutputStream(fos);
ZipEntry entry = in.getNextEntry();
out.writeObject(_change);
out.flush();
} catch(IOException e) {
e.printStackTrace();
assert "change.txt".equals(entry.getName());
LineNumberReader reader = new LineNumberReader(new InputStreamReader(in));
try {
_change = History.readOneChange(reader);
} finally {
reader.close();
}
} finally {
if (fos != null) {
try {
fos.close();
} catch (Exception e) {
}
}
if (out != null) {
try {
out.close();
} catch (Exception e) {
}
}
in.close();
}
}
protected File getFile() {
File dir = new File(ProjectManager.singleton.getDataDir(), projectID + ".history");
protected void saveChange() throws IOException {
File changeFile = getChangeFile();
if (!(changeFile.exists())) {
saveChange(changeFile);
}
}
protected void saveChange(File file) throws IOException {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file));
try {
out.putNextEntry(new ZipEntry("change.txt"));
try {
Writer writer = new OutputStreamWriter(out);
try {
Properties options = new Properties();
options.setProperty("mode", "save");
writer.write(_change.getClass().getName()); writer.write('\n');
_change.save(writer, options);
} finally {
writer.flush();
}
} finally {
out.closeEntry();
}
} finally {
out.close();
}
}
protected File getChangeFile() {
return new File(getHistoryDir(), id + ".change.zip");
}
protected File getHistoryDir() {
File dir = new File(ProjectManager.singleton.getProjectDir(projectID), "history");
dir.mkdirs();
return new File(dir, id + ".entry");
return dir;
}
}

View File

@ -1,11 +1,13 @@
package com.metaweb.gridworks.model;
import java.io.Serializable;
import java.io.Writer;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
@ -44,8 +46,10 @@ public class Cell implements Serializable, HasFields, Jsonizable {
if (value != null) {
if (value instanceof Calendar) {
writer.value(ParsingUtilities.dateToString(((Calendar) value).getTime()));
writer.key("t"); writer.value("date");
} else if (value instanceof Date) {
writer.value(ParsingUtilities.dateToString((Date) value));
writer.key("t"); writer.value("date");
} else {
writer.value(value);
}
@ -60,4 +64,40 @@ public class Cell implements Serializable, HasFields, Jsonizable {
}
writer.endObject();
}
public void save(Writer writer, Properties options) {
JSONWriter jsonWriter = new JSONWriter(writer);
try {
write(jsonWriter, options);
} catch (JSONException e) {
e.printStackTrace();
}
}
static public Cell load(String s) throws Exception {
return load(ParsingUtilities.evaluateJsonStringToObject(s));
}
static public Cell load(JSONObject obj) throws Exception {
Serializable value = null;
Recon recon = null;
if (obj.has("e")) {
value = new EvalError(obj.getString("e"));
} else if (obj.has("v")) {
value = (Serializable) obj.get("v");
if (obj.has("t")) {
String type = obj.getString("t");
if ("date".equals(type)) {
value = ParsingUtilities.stringToDate((String) value);
}
}
}
if (obj.has("r")) {
recon = Recon.load(obj.getJSONObject("r"));
}
return new Cell(value, recon);
}
}

View File

@ -1,30 +1,33 @@
package com.metaweb.gridworks.model;
import java.io.Serializable;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
import com.metaweb.gridworks.model.recon.ReconConfig;
import com.metaweb.gridworks.util.ParsingUtilities;
public class Column implements Serializable, Jsonizable {
private static final long serialVersionUID = -1063342490951563563L;
final private int _cellIndex;
final private String _originalHeaderLabel;
private String _headerLabel;
final private int _cellIndex;
final private String _originalName;
private String _name;
private ReconConfig _reconConfig;
private ReconStats _reconStats;
private ReconStats _reconStats;
transient protected Map<String, Object> _precomputes;
public Column(int cellIndex, String headerLabel) {
public Column(int cellIndex, String originalName) {
_cellIndex = cellIndex;
_originalHeaderLabel = _headerLabel = headerLabel;
_originalName = _name = originalName;
}
public int getCellIndex() {
@ -32,15 +35,15 @@ public class Column implements Serializable, Jsonizable {
}
public String getOriginalHeaderLabel() {
return _originalHeaderLabel;
return _originalName;
}
public void setHeaderLabel(String headerLabel) {
this._headerLabel = headerLabel;
public void setName(String name) {
this._name = name;
}
public String getHeaderLabel() {
return _headerLabel;
public String getName() {
return _name;
}
public void setReconConfig(ReconConfig config) {
@ -63,8 +66,9 @@ public class Column implements Serializable, Jsonizable {
throws JSONException {
writer.object();
writer.key("cellIndex"); writer.value(getCellIndex());
writer.key("headerLabel"); writer.value(getHeaderLabel());
writer.key("cellIndex"); writer.value(_cellIndex);
writer.key("originalName"); writer.value(_originalName);
writer.key("name"); writer.value(_name);
if (_reconConfig != null) {
writer.key("reconConfig");
_reconConfig.write(writer, options);
@ -95,4 +99,28 @@ public class Column implements Serializable, Jsonizable {
}
_precomputes.put(key, value);
}
public void save(Writer writer) {
JSONWriter jsonWriter = new JSONWriter(writer);
try {
write(jsonWriter, new Properties());
} catch (JSONException e) {
e.printStackTrace();
}
}
static public Column load(String s) throws Exception {
JSONObject obj = ParsingUtilities.evaluateJsonStringToObject(s);
Column column = new Column(obj.getInt("cellIndex"), obj.getString("originalName"));
column._name = obj.getString("name");
if (obj.has("reconConfig")) {
column._reconConfig = ReconConfig.reconstruct(obj.getJSONObject("reconConfig"));
}
if (obj.has("reconStats")) {
column._reconStats = ReconStats.reconstruct(obj.getJSONObject("reconStats"));
}
return column;
}
}

View File

@ -79,7 +79,7 @@ public class ColumnModel implements Serializable, Jsonizable {
writer.endArray();
writer.key("keyCellIndex"); writer.value(getKeyColumnIndex());
writer.key("keyColumnName"); writer.value(columns.get(_keyColumnIndex).getHeaderLabel());
writer.key("keyColumnName"); writer.value(columns.get(_keyColumnIndex).getName());
writer.key("columnGroups");
writer.array();
for (ColumnGroup g : _rootColumnGroups) {
@ -134,7 +134,7 @@ public class ColumnModel implements Serializable, Jsonizable {
_cellIndexToColumn = new HashMap<Integer, Column>();
for (Column column : columns) {
_nameToColumn.put(column.getHeaderLabel(), column);
_nameToColumn.put(column.getName(), column);
_cellIndexToColumn.put(column.getCellIndex(), column);
}
}

View File

@ -7,7 +7,9 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
@ -59,15 +61,19 @@ public class Recon implements Serializable, HasFields, Jsonizable {
}
final public long id;
public Object[] features = new Object[Feature_max];
public List<ReconCandidate> candidates;
public Judgment judgment = Judgment.None;
public Object[] features = new Object[Feature_max];
public List<ReconCandidate> candidates;
public Judgment judgment = Judgment.None;
public ReconCandidate match = null;
public Recon() {
id = System.currentTimeMillis() * 1000000 + Math.round(Math.random() * 1000000);
}
protected Recon(long id) {
this.id = id;
}
public Recon dup() {
Recon r = new Recon();
@ -150,8 +156,8 @@ public class Recon implements Serializable, HasFields, Jsonizable {
throws JSONException {
writer.object();
writer.key("j");
writer.value(judgmentToString());
writer.key("id"); writer.value(id);
writer.key("j"); writer.value(judgmentToString());
if (match != null) {
writer.key("m");
@ -166,6 +172,51 @@ public class Recon implements Serializable, HasFields, Jsonizable {
writer.endArray();
}
if ("save".equals(options.getProperty("mode"))) {
writer.key("f");
writer.array();
for (Object o : features) {
writer.value(o);
}
writer.endArray();
}
writer.endObject();
}
static public Recon load(JSONObject obj) throws Exception {
if (obj == null) {
return null;
}
Recon recon = new Recon(obj.getLong("id"));
if (obj.has("j")) {
recon.judgment = stringToJudgment(obj.getString("j"));
}
if (obj.has("m")) {
recon.match = ReconCandidate.load(obj.getJSONObject("m"));
}
if (obj.has("c")) {
JSONArray a = obj.getJSONArray("c");
int count = a.length();
for (int i = 0; i < count; i++) {
recon.addCandidate(ReconCandidate.load(a.getJSONObject(i)));
}
}
if (obj.has("f")) {
JSONArray a = obj.getJSONArray("f");
int count = a.length();
for (int i = 0; i < count && i < Feature_max; i++) {
if (!a.isNull(i)) {
recon.features[i] = a.get(i);
}
}
}
return recon;
}
}

View File

@ -4,19 +4,21 @@ import java.io.Serializable;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
import com.metaweb.gridworks.expr.HasFields;
import com.metaweb.gridworks.util.JSONUtilities;
public class ReconCandidate implements Serializable, HasFields, Jsonizable {
private static final long serialVersionUID = -8013997214978715606L;
final public String topicID;
final public String topicGUID;
final public String topicName;
final public String[] typeIDs;
final public double score;
final public String topicName;
final public String[] typeIDs;
final public double score;
public ReconCandidate(String topicID, String topicGUID, String topicName, String[] typeIDs, double score) {
this.topicID = topicID;
@ -57,4 +59,19 @@ public class ReconCandidate implements Serializable, HasFields, Jsonizable {
writer.endObject();
}
}
static public ReconCandidate load(JSONObject obj) throws Exception {
if (obj == null) {
return null;
}
ReconCandidate candidate = new ReconCandidate(
obj.getString("id"),
obj.getString("guid"),
obj.getString("name"),
JSONUtilities.getStringArray(obj, "types"),
obj.getDouble("score")
);
return candidate;
}
}

View File

@ -1,9 +1,11 @@
package com.metaweb.gridworks.model;
import java.io.Serializable;
import java.io.Writer;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
@ -13,6 +15,14 @@ import com.metaweb.gridworks.model.Recon.Judgment;
public class ReconStats implements Serializable, Jsonizable {
private static final long serialVersionUID = -4831409797104437854L;
static public ReconStats reconstruct(JSONObject obj) throws Exception {
return new ReconStats(
obj.getInt("nonBlanks"),
obj.getInt("newTopics"),
obj.getInt("matchedTopics")
);
}
final public int nonBlanks;
final public int newTopics;
final public int matchedTopics;
@ -55,4 +65,13 @@ public class ReconStats implements Serializable, Jsonizable {
return new ReconStats(nonBlanks, newTopics, matchedTopics);
}
public void save(Writer writer) {
JSONWriter jsonWriter = new JSONWriter(writer);
try {
write(jsonWriter, new Properties());
} catch (JSONException e) {
e.printStackTrace();
}
}
}

View File

@ -1,27 +1,31 @@
package com.metaweb.gridworks.model;
import java.io.Serializable;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
import com.metaweb.gridworks.expr.HasFields;
import com.metaweb.gridworks.util.ParsingUtilities;
public class Row implements Serializable, HasFields, Jsonizable {
private static final long serialVersionUID = -689264211730915507L;
public boolean flagged;
public boolean starred;
public boolean flagged;
public boolean starred;
final public List<Cell> cells;
transient public int recordIndex; // -1 for rows that are not main record rows
transient public List<Integer> contextRows;
transient public int[] contextRowSlots;
transient public int[] contextCellSlots;
transient public int recordIndex = -1; // -1 for rows that are not main record rows
transient public List<Integer> contextRows;
transient public int[] contextRowSlots;
transient public int[] contextCellSlots;
public Row(int cellCount) {
cells = new ArrayList<Cell>(cellCount);
@ -126,23 +130,59 @@ public class Row implements Serializable, HasFields, Jsonizable {
}
writer.endArray();
if (recordIndex >= 0) {
writer.key("j"); writer.value(recordIndex);
}
if (options.containsKey("rowIndex")) {
writer.key("i"); writer.value(options.get("rowIndex"));
}
if (options.containsKey("extra")) {
Properties extra = (Properties) options.get("extra");
if (extra != null) {
for (Object key : extra.keySet()) {
writer.key((String) key);
writer.value(extra.get(key));
if (!"save".equals(options.getProperty("mode"))) {
if (recordIndex >= 0) {
writer.key("j"); writer.value(recordIndex);
}
if (options.containsKey("rowIndex")) {
writer.key("i"); writer.value(options.get("rowIndex"));
}
if (options.containsKey("extra")) {
Properties extra = (Properties) options.get("extra");
if (extra != null) {
for (Object key : extra.keySet()) {
writer.key((String) key);
writer.value(extra.get(key));
}
}
}
}
writer.endObject();
}
public void save(Writer writer) {
JSONWriter jsonWriter = new JSONWriter(writer);
try {
write(jsonWriter, new Properties());
} catch (JSONException e) {
e.printStackTrace();
}
}
static public Row load(String s) throws Exception {
JSONObject obj = ParsingUtilities.evaluateJsonStringToObject(s);
JSONArray a = obj.getJSONArray("cells");
int count = a.length();
Row row = new Row(count);
for (int i = 0; i < count; i++) {
if (!a.isNull(i)) {
JSONObject o = a.getJSONObject(i);
row.setCell(i, Cell.load(o));
}
}
if (obj.has("starred")) {
row.starred = obj.getBoolean("starred");
}
if (obj.has("flagged")) {
row.flagged = obj.getBoolean("flagged");
}
return row;
}
}

View File

@ -1,6 +1,9 @@
package com.metaweb.gridworks.model.changes;
import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.util.Properties;
import com.metaweb.gridworks.model.Cell;
@ -14,4 +17,20 @@ public class CellAtRow implements Serializable {
this.row = row;
this.cell = cell;
}
public void save(Writer writer, Properties options) throws IOException {
writer.write(Integer.toString(row));
writer.write(';');
if (cell != null) {
cell.save(writer, options);
}
}
static public CellAtRow load(String s) throws Exception {
int semicolon = s.indexOf(';');
int row = Integer.parseInt(s.substring(0, semicolon));
Cell cell = semicolon < s.length() - 1 ? Cell.load(s.substring(semicolon + 1)) : null;
return new CellAtRow(row, cell);
}
}

View File

@ -1,20 +1,23 @@
package com.metaweb.gridworks.model.changes;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.Properties;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.model.Cell;
import com.metaweb.gridworks.model.Project;
public class CellChange implements Change {
private static final long serialVersionUID = -2637405780084390883L;
final public int row;
final public int cellIndex;
final public Cell oldCell;
final public Cell newCell;
final public Cell newCell;
public CellChange(int row, int column, Cell oldCell, Cell newCell) {
public CellChange(int row, int cellIndex, Cell oldCell, Cell newCell) {
this.row = row;
this.cellIndex = column;
this.cellIndex = cellIndex;
this.oldCell = oldCell;
this.newCell = newCell;
}
@ -26,4 +29,49 @@ public class CellChange implements Change {
public void revert(Project project) {
project.rows.get(row).setCell(cellIndex, oldCell);
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("row="); writer.write(Integer.toString(row)); writer.write('\n');
writer.write("cell="); writer.write(Integer.toString(cellIndex)); writer.write('\n');
writer.write("old=");
if (oldCell != null) {
oldCell.save(writer, options); // one liner
}
writer.write('\n');
writer.write("new=");
if (newCell != null) {
newCell.save(writer, options); // one liner
}
writer.write('\n');
writer.write("/ec/\n"); // end of change marker
}
static public CellChange load(LineNumberReader reader) throws Exception {
int row = -1;
int cellIndex = -1;
Cell oldCell = null;
Cell newCell = null;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
String value = line.substring(equal + 1);
if ("row".equals(field)) {
row = Integer.parseInt(value);
} else if ("cell".equals(field)) {
cellIndex = Integer.parseInt(value);
} else if ("new".equals(field)) {
newCell = Cell.load(value);
} else if ("old".equals(field)) {
oldCell = Cell.load(value);
}
}
return new CellChange(row, cellIndex, oldCell, newCell);
}
}

View File

@ -1,21 +1,25 @@
package com.metaweb.gridworks.model.changes;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.model.Column;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.Row;
public class ColumnAdditionChange extends ColumnChange {
private static final long serialVersionUID = -3938837464064526052L;
final protected String _headerLabel;
final protected String _columnName;
final protected int _columnIndex;
final protected CellAtRow[] _newCells;
protected int _newCellIndex = -1;
public ColumnAdditionChange(String headerLabel, int columnIndex, List<CellAtRow> newCells) {
_headerLabel = headerLabel;
public ColumnAdditionChange(String columnName, int columnIndex, List<CellAtRow> newCells) {
_columnName = columnName;
_columnIndex = columnIndex;
_newCells = new CellAtRow[newCells.size()];
newCells.toArray(_newCells);
@ -27,7 +31,7 @@ public class ColumnAdditionChange extends ColumnChange {
_newCellIndex = project.columnModel.allocateNewCellIndex();
}
Column column = new Column(_newCellIndex, _headerLabel);
Column column = new Column(_newCellIndex, _columnName);
project.columnModel.columns.add(_columnIndex, column);
try {
@ -56,4 +60,48 @@ public class ColumnAdditionChange extends ColumnChange {
}
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("columnName="); writer.write(_columnName); writer.write('\n');
writer.write("columnIndex="); writer.write(Integer.toString(_columnIndex)); writer.write('\n');
writer.write("newCellIndex="); writer.write(Integer.toString(_newCellIndex)); writer.write('\n');
writer.write("newCellCount="); writer.write(Integer.toString(_newCells.length)); writer.write('\n');
for (CellAtRow c : _newCells) {
c.save(writer, options);
writer.write('\n');
}
writer.write("/ec/\n"); // end of change marker
}
static public Change load(LineNumberReader reader) throws Exception {
String columnName = null;
int columnIndex = -1;
int newCellIndex = -1;
List<CellAtRow> newCells = null;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
if ("columnName".equals(field)) {
columnName = line.substring(equal + 1);
} else if ("columnIndex".equals(field)) {
columnIndex = Integer.parseInt(line.substring(equal + 1));
} else if ("newCellIndex".equals(field)) {
newCellIndex = Integer.parseInt(line.substring(equal + 1));
} else if ("newCellCount".equals(field)) {
int newCellCount = Integer.parseInt(line.substring(equal + 1));
newCells = new ArrayList<CellAtRow>(newCellCount);
for (int i = 0; i < newCellCount; i++) {
newCells.add(CellAtRow.load(line = reader.readLine()));
}
}
}
ColumnAdditionChange change = new ColumnAdditionChange(columnName, columnIndex, newCells);
change._newCellIndex = newCellIndex;
return change;
}
}

View File

@ -3,5 +3,4 @@ package com.metaweb.gridworks.model.changes;
import com.metaweb.gridworks.history.Change;
abstract public class ColumnChange implements Change {
private static final long serialVersionUID = 2725529838777790586L;
}

View File

@ -1,13 +1,17 @@
package com.metaweb.gridworks.model.changes;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.Properties;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.model.Cell;
import com.metaweb.gridworks.model.Column;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.Row;
public class ColumnRemovalChange extends ColumnChange {
private static final long serialVersionUID = -3587865920553490108L;
final protected int _oldColumnIndex;
protected Column _oldColumn;
protected CellAtRow[] _oldCells;
@ -53,4 +57,45 @@ public class ColumnRemovalChange extends ColumnChange {
}
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("oldColumnIndex="); writer.write(Integer.toString(_oldColumnIndex)); writer.write('\n');
writer.write("oldColumn="); _oldColumn.save(writer); writer.write('\n');
writer.write("oldCellCount="); writer.write(Integer.toString(_oldCells.length)); writer.write('\n');
for (CellAtRow c : _oldCells) {
c.save(writer, options);
writer.write('\n');
}
writer.write("/ec/\n"); // end of change marker
}
static public Change load(LineNumberReader reader) throws Exception {
int oldColumnIndex = -1;
Column oldColumn = null;
CellAtRow[] oldCells = null;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
if ("oldColumnIndex".equals(field)) {
oldColumnIndex = Integer.parseInt(line.substring(equal + 1));
} else if ("oldColumn".equals(field)) {
oldColumn = Column.load(line.substring(equal + 1));
} else if ("oldCellCount".equals(field)) {
int oldCellCount = Integer.parseInt(line.substring(equal + 1));
oldCells = new CellAtRow[oldCellCount];
for (int i = 0; i < oldCellCount; i++) {
oldCells[i] = CellAtRow.load(line = reader.readLine());
}
}
}
ColumnRemovalChange change = new ColumnRemovalChange(oldColumnIndex);
change._oldColumn = oldColumn;
change._oldCells = oldCells;
return change;
}
}

View File

@ -1,6 +1,10 @@
package com.metaweb.gridworks.model.changes;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.List;
import java.util.Properties;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.model.Column;
@ -8,13 +12,25 @@ import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.Row;
public class MassCellChange implements Change {
private static final long serialVersionUID = -933571199802688027L;
final protected CellChange[] _cellChanges;
final protected String _commonColumnName;
final protected String _commonColumnName;
final protected boolean _updateRowContextDependencies;
public MassCellChange(List<CellChange> cellChanges, String commonColumnName, boolean updateRowContextDependencies) {
public MassCellChange(
CellChange[] cellChanges,
String commonColumnName,
boolean updateRowContextDependencies) {
_cellChanges = cellChanges;
_commonColumnName = commonColumnName;
_updateRowContextDependencies = updateRowContextDependencies;
}
public MassCellChange(
List<CellChange> cellChanges,
String commonColumnName,
boolean updateRowContextDependencies) {
_cellChanges = new CellChange[cellChanges.size()];
_commonColumnName = commonColumnName;
cellChanges.toArray(_cellChanges);
@ -68,4 +84,43 @@ public class MassCellChange implements Change {
}
}
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("commonColumnName="); writer.write(_commonColumnName); writer.write('\n');
writer.write("updateRowContextDependencies="); writer.write(Boolean.toString(_updateRowContextDependencies)); writer.write('\n');
writer.write("cellChangeCount="); writer.write(Integer.toString(_cellChanges.length)); writer.write('\n');
for (CellChange c : _cellChanges) {
c.save(writer, options);
}
writer.write("/ec/\n"); // end of change marker
}
static public Change load(LineNumberReader reader) throws Exception {
String commonColumnName = null;
boolean updateRowContextDependencies = false;
CellChange[] cellChanges = null;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
if ("commonColumnName".equals(field)) {
commonColumnName = line.substring(equal + 1);
} else if ("updateRowContextDependencies".equals(field)) {
updateRowContextDependencies = Boolean.parseBoolean(line.substring(equal + 1));
} else if ("cellChangeCount".equals(field)) {
int cellChangeCount = Integer.parseInt(line.substring(equal + 1));
cellChanges = new CellChange[cellChangeCount];
for (int i = 0; i < cellChangeCount; i++) {
cellChanges[i] = CellChange.load(reader);
}
}
}
MassCellChange change = new MassCellChange(cellChanges, commonColumnName, updateRowContextDependencies);
return change;
}
}

View File

@ -1,13 +1,17 @@
package com.metaweb.gridworks.model.changes;
import java.util.List;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.History;
import com.metaweb.gridworks.model.Project;
public class MassChange implements Change {
private static final long serialVersionUID = -3926239320561407450L;
final protected List<? extends Change> _changes;
final protected boolean _updateRowContextDependencies;
@ -39,4 +43,39 @@ public class MassChange implements Change {
}
}
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("updateRowContextDependencies="); writer.write(Boolean.toString(_updateRowContextDependencies)); writer.write('\n');
writer.write("changeCount="); writer.write(Integer.toString(_changes.size())); writer.write('\n');
for (Change c : _changes) {
c.save(writer, options);
}
writer.write("/ec/\n"); // end of change marker
}
static public Change load(LineNumberReader reader) throws Exception {
boolean updateRowContextDependencies = false;
List<Change> changes = null;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
if ("updateRowContextDependencies".equals(field)) {
updateRowContextDependencies = Boolean.parseBoolean(line.substring(equal + 1));
} else if ("changeCount".equals(field)) {
int changeCount = Integer.parseInt(line.substring(equal + 1));
changes = new ArrayList<Change>(changeCount);
for (int i = 0; i < changeCount; i++) {
changes.add(History.readOneChange(reader));
}
}
}
MassChange change = new MassChange(changes, updateRowContextDependencies);
return change;
}
}

View File

@ -1,15 +1,17 @@
package com.metaweb.gridworks.model.changes;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.Row;
public class MassRowChange implements Change {
private static final long serialVersionUID = 5640738656190790569L;
final protected List<Row> _newRows;
protected List<Row> _oldRows;
@ -36,4 +38,52 @@ public class MassRowChange implements Change {
}
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("newRowCount="); writer.write(Integer.toString(_newRows.size())); writer.write('\n');
for (Row row : _newRows) {
row.save(writer);
writer.write('\n');
}
writer.write("oldRowCount="); writer.write(Integer.toString(_oldRows.size())); writer.write('\n');
for (Row row : _oldRows) {
row.save(writer);
writer.write('\n');
}
writer.write("/ec/\n"); // end of change marker
}
static public Change load(LineNumberReader reader) throws Exception {
List<Row> oldRows = null;
List<Row> newRows = null;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
if ("oldRowCount".equals(field)) {
int count = Integer.parseInt(line.substring(equal + 1));
oldRows = new ArrayList<Row>(count);
for (int i = 0; i < count; i++) {
line = reader.readLine();
oldRows.add(Row.load(line));
}
} else if ("newRowCount".equals(field)) {
int count = Integer.parseInt(line.substring(equal + 1));
newRows = new ArrayList<Row>(count);
for (int i = 0; i < count; i++) {
line = reader.readLine();
newRows.add(Row.load(line));
}
}
}
MassRowChange change = new MassRowChange(newRows);
change._oldRows = oldRows;
return change;
}
}

View File

@ -3,16 +3,20 @@
*/
package com.metaweb.gridworks.model.changes;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.List;
import java.util.Properties;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.model.Column;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.ReconStats;
import com.metaweb.gridworks.model.recon.ReconConfig;
import com.metaweb.gridworks.util.ParsingUtilities;
public class ReconChange extends MassCellChange {
private static final long serialVersionUID = 7048806528587330543L;
final protected ReconConfig _newReconConfig;
protected ReconStats _newReconStats;
@ -20,10 +24,21 @@ public class ReconChange extends MassCellChange {
protected ReconStats _oldReconStats;
public ReconChange(
List<CellChange> cellChanges,
String commonColumnName,
List<CellChange> cellChanges,
String commonColumnName,
ReconConfig newReconConfig,
ReconStats newReconStats // can be null
ReconStats newReconStats // can be null
) {
super(cellChanges, commonColumnName, false);
_newReconConfig = newReconConfig;
_newReconStats = newReconStats;
}
public ReconChange(
CellChange[] cellChanges,
String commonColumnName,
ReconConfig newReconConfig,
ReconStats newReconStats // can be null
) {
super(cellChanges, commonColumnName, false);
_newReconConfig = newReconConfig;
@ -70,4 +85,57 @@ public class ReconChange extends MassCellChange {
column.setReconStats(_oldReconStats);
}
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("newReconConfig="); _newReconConfig.save(writer); writer.write('\n');
writer.write("newReconStats="); _newReconStats.save(writer); writer.write('\n');
writer.write("oldReconConfig="); _oldReconConfig.save(writer); writer.write('\n');
writer.write("oldReconStats="); _oldReconStats.save(writer); writer.write('\n');
super.save(writer, options);
}
static public Change load(LineNumberReader reader) throws Exception {
ReconConfig newReconConfig = null;
ReconStats newReconStats = null;
ReconConfig oldReconConfig = null;
ReconStats oldReconStats = null;
String commonColumnName = null;
CellChange[] cellChanges = null;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
String value = line.substring(equal + 1);
if ("newReconConfig".equals(field)) {
newReconConfig = ReconConfig.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value));
} else if ("newReconStats".equals(field)) {
newReconStats = ReconStats.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value));
} else if ("oldReconConfig".equals(field)) {
oldReconConfig = ReconConfig.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value));
} else if ("oldReconStats".equals(field)) {
oldReconStats = ReconStats.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value));
} else if ("commonColumnName".equals(field)) {
commonColumnName = value;
} else if ("cellChangeCount".equals(field)) {
int cellChangeCount = Integer.parseInt(value);
cellChanges = new CellChange[cellChangeCount];
for (int i = 0; i < cellChangeCount; i++) {
cellChanges[i] = CellChange.load(reader);
}
}
}
ReconChange change = new ReconChange(
cellChanges, commonColumnName, newReconConfig, newReconStats);
change._oldReconConfig = oldReconConfig;
change._oldReconStats = oldReconStats;
return change;
}
}

View File

@ -1,12 +1,15 @@
package com.metaweb.gridworks.model.changes;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.Properties;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.Row;
public class RowStarChange implements Change {
private static final long serialVersionUID = 7343472491567342093L;
final int rowIndex;
final boolean newStarred;
boolean oldStarred;
@ -28,4 +31,37 @@ public class RowStarChange implements Change {
row.starred = oldStarred;
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("row="); writer.write(Integer.toString(rowIndex)); writer.write('\n');
writer.write("newStarred="); writer.write(Boolean.toString(newStarred)); writer.write('\n');
writer.write("oldStarred="); writer.write(Boolean.toString(oldStarred)); writer.write('\n');
writer.write("/ec/\n"); // end of change marker
}
static public RowStarChange load(LineNumberReader reader) throws Exception {
int row = -1;
boolean oldStarred = false;
boolean newStarred = false;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
String value = line.substring(equal + 1);
if ("row".equals(field)) {
row = Integer.parseInt(value);
} else if ("oldStarred".equals(field)) {
oldStarred = Boolean.parseBoolean(value);
} else if ("newStarred".equals(field)) {
oldStarred = Boolean.parseBoolean(value);
}
}
RowStarChange change = new RowStarChange(row, newStarred);
change.oldStarred = oldStarred;
return change;
}
}

View File

@ -170,5 +170,4 @@ public class GuidBasedReconConfig extends StrictReconConfig {
return recons;
}
}

View File

@ -1,9 +1,13 @@
package com.metaweb.gridworks.model.recon;
import java.io.Serializable;
import java.io.Writer;
import java.util.List;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
import com.metaweb.gridworks.model.Cell;
@ -37,4 +41,13 @@ abstract public class ReconConfig implements Serializable, Jsonizable {
);
abstract public List<Recon> batchRecon(List<ReconJob> jobs);
public void save(Writer writer) {
JSONWriter jsonWriter = new JSONWriter(writer);
try {
write(jsonWriter, new Properties());
} catch (JSONException e) {
e.printStackTrace();
}
}
}

View File

@ -32,7 +32,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
final protected String _expression;
final protected OnError _onError;
final protected String _headerLabel;
final protected String _newColumnName;
final protected int _columnInsertIndex;
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
@ -43,7 +43,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
obj.getString("baseColumnName"),
obj.getString("expression"),
TextTransformOperation.stringToOnError(obj.getString("onError")),
obj.getString("headerLabel"),
obj.getString("newColumnName"),
obj.getInt("columnInsertIndex")
);
}
@ -53,7 +53,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
String baseColumnName,
String expression,
OnError onError,
String headerLabel,
String newColumnName,
int columnInsertIndex
) {
super(engineConfig);
@ -62,7 +62,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
_expression = expression;
_onError = onError;
_headerLabel = headerLabel;
_newColumnName = newColumnName;
_columnInsertIndex = columnInsertIndex;
}
@ -73,7 +73,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("headerLabel"); writer.value(_headerLabel);
writer.key("newColumnName"); writer.value(_newColumnName);
writer.key("columnInsertIndex"); writer.value(_columnInsertIndex);
writer.key("baseColumnName"); writer.value(_baseColumnName);
writer.key("expression"); writer.value(_expression);
@ -82,15 +82,15 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
}
protected String getBriefDescription(Project project) {
return "Create column " + _headerLabel +
return "Create column " + _newColumnName +
" at index " + _columnInsertIndex +
" based on column " + _baseColumnName +
" using expression " + _expression;
}
protected String createDescription(Column column, List<CellAtRow> cellsAtRows) {
return "Create new column " + _headerLabel +
" based on column " + column.getHeaderLabel() +
return "Create new column " + _newColumnName +
" based on column " + column.getName() +
" by filling " + cellsAtRows.size() +
" rows with " + _expression;
}
@ -110,7 +110,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
String description = createDescription(column, cellsAtRows);
Change change = new ColumnAdditionChange(_headerLabel, _columnInsertIndex, cellsAtRows);
Change change = new ColumnAdditionChange(_newColumnName, _columnInsertIndex, cellsAtRows);
return new HistoryEntry(
project, description, this, change);

View File

@ -51,7 +51,7 @@ public class ColumnRemovalOperation extends AbstractOperation {
throw new Exception("No column named " + _columnName);
}
String description = "Remove column " + column.getHeaderLabel();
String description = "Remove column " + column.getName();
Change change = new ColumnRemovalChange(project.columnModel.columns.indexOf(column));

View File

@ -49,7 +49,7 @@ abstract public class EngineDependentMassCellOperation extends EngineDependentOp
protected Change createChange(Project project, Column column, List<CellChange> cellChanges) {
return new MassCellChange(
cellChanges, column.getHeaderLabel(), _updateRowContextDependencies);
cellChanges, column.getName(), _updateRowContextDependencies);
}
abstract protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception;

View File

@ -120,7 +120,7 @@ public class FacetBasedEditOperation extends EngineDependentMassCellOperation {
List<CellChange> cellChanges) {
return "Facet-based edit " + cellChanges.size() +
" cells in column " + column.getHeaderLabel();
" cells in column " + column.getName();
}
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception {

View File

@ -55,7 +55,7 @@ public class ReconDiscardJudgmentsOperation extends EngineDependentMassCellOpera
List<CellChange> cellChanges) {
return "Discard recon judgments for " + cellChanges.size() +
" cells in column " + column.getHeaderLabel();
" cells in column " + column.getName();
}
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception {

View File

@ -64,7 +64,7 @@ public class ReconMarkNewTopicsOperation extends EngineDependentMassCellOperatio
List<CellChange> cellChanges) {
return "Mark to create new topics for " + cellChanges.size() +
" cells in column " + column.getHeaderLabel() +
" cells in column " + column.getName() +
(_shareNewTopics ?
", one topic for each group of similar cells" :
", one topic for each cell");

View File

@ -55,7 +55,7 @@ public class ReconMatchBestCandidatesOperation extends EngineDependentMassCellOp
List<CellChange> cellChanges) {
return "Match each of " + cellChanges.size() +
" cells to its best candidate in column " + column.getHeaderLabel();
" cells to its best candidate in column " + column.getName();
}
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception {

View File

@ -89,7 +89,7 @@ public class ReconMatchSpecificTopicOperation extends EngineDependentMassCellOpe
return "Match specific topic " +
match.topicName + " (" +
match.topicID + ") to " + cellChanges.size() +
" cells in column " + column.getHeaderLabel();
" cells in column " + column.getName();
}
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception {

View File

@ -1,5 +1,8 @@
package com.metaweb.gridworks.operations;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.Properties;
import org.json.JSONException;
@ -11,6 +14,7 @@ import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.protograph.Protograph;
import com.metaweb.gridworks.util.ParsingUtilities;
public class SaveProtographOperation extends AbstractOperation {
private static final long serialVersionUID = 3134524625206033285L;
@ -53,8 +57,6 @@ public class SaveProtographOperation extends AbstractOperation {
}
static public class ProtographChange implements Change {
private static final long serialVersionUID = -564820111174473901L;
final protected Protograph _newProtograph;
protected Protograph _oldProtograph;
@ -74,5 +76,50 @@ public class SaveProtographOperation extends AbstractOperation {
project.protograph = _oldProtograph;
}
}
public void save(Writer writer, Properties options) throws IOException {
writer.write("newProtograph="); writeProtograph(_newProtograph, writer); writer.write('\n');
writer.write("oldProtograph="); writeProtograph(_oldProtograph, writer); writer.write('\n');
writer.write("/ec/\n"); // end of change marker
}
static public Change load(LineNumberReader reader) throws Exception {
Protograph oldProtograph = null;
Protograph newProtograph = null;
String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
String value = line.substring(equal + 1);
if ("oldProtograph".equals(field)) {
if (value.length() > 0) {
oldProtograph = Protograph.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value));
}
} else if ("newProtograph".equals(field)) {
if (value.length() > 0) {
newProtograph = Protograph.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value));
}
}
}
ProtographChange change = new ProtographChange(newProtograph);
change._oldProtograph = oldProtograph;
return change;
}
static protected void writeProtograph(Protograph p, Writer writer) throws IOException {
if (p != null) {
JSONWriter jsonWriter = new JSONWriter(writer);
try {
p.write(jsonWriter, new Properties());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}

View File

@ -97,7 +97,7 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
List<CellChange> cellChanges) {
return "Text transform on " + cellChanges.size() +
" cells in column " + column.getHeaderLabel() + ": " + _expression;
" cells in column " + column.getName() + ": " + _expression;
}
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception {

View File

@ -28,7 +28,7 @@ ReconDialog.prototype._createDialog = function() {
var frame = DialogSystem.createDialog();
frame.width("800px");
var header = $('<div></div>').addClass("dialog-header").text("Reconcile column " + this._column.headerLabel).appendTo(frame);
var header = $('<div></div>').addClass("dialog-header").text("Reconcile column " + this._column.name).appendTo(frame);
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
@ -156,9 +156,9 @@ ReconDialog.prototype._populateDialog = function() {
var td0 = tr.insertCell(0);
var td1 = tr.insertCell(1);
$(td0).html(column.headerLabel);
$(td0).html(column.name);
$('<input size="15" name="recon-dialog-heuristic-property" />')
.attr("columnName", column.headerLabel)
.attr("columnName", column.name)
.appendTo(td1);
}
var columns = theProject.columnModel.columns;
@ -246,7 +246,7 @@ ReconDialog.prototype._onDoHeuristic = function() {
"reconcile",
{},
{
columnName: this._column.headerLabel,
columnName: this._column.name,
config: JSON.stringify({
mode: "heuristic",
service: $('input[name="recon-dialog-heuristic-service"]:checked')[0].value,
@ -291,7 +291,7 @@ ReconDialog.prototype._onDoStrict = function() {
}
bodyParams = {
columnName: this._column.headerLabel,
columnName: this._column.name,
config: JSON.stringify({
mode: "strict",
match: "key",
@ -300,7 +300,7 @@ ReconDialog.prototype._onDoStrict = function() {
};
} else if (match == "id") {
bodyParams = {
columnName: this._column.headerLabel,
columnName: this._column.name,
config: JSON.stringify({
mode: "strict",
match: "id"
@ -308,7 +308,7 @@ ReconDialog.prototype._onDoStrict = function() {
};
} else if (match == "guid") {
bodyParams = {
columnName: this._column.headerLabel,
columnName: this._column.name,
config: JSON.stringify({
mode: "strict",
match: "guid"

View File

@ -226,10 +226,10 @@ SchemaAlignmentDialog.UINode.prototype._showColumnPopupMenu = function(elmt) {
var columns = theProject.columnModel.columns;
var createColumnMenuItem = function(index) {
menu.push({
label: columns[index].headerLabel,
label: columns[index].name,
click: function() {
self._node.nodeType = "cell-as-topic";
self._node.columnName = columns[index].headerLabel;
self._node.columnName = columns[index].name;
self._showExpandable();
self._renderMain();
}
@ -403,7 +403,7 @@ SchemaAlignmentDialog.UINode.prototype._showNodeConfigDialog = function() {
var radio = $('<input />')
.attr("type", "radio")
.attr("value", column.headerLabel)
.attr("value", column.name)
.attr("name", "schema-align-node-dialog-column")
.appendTo(tr.insertCell(0))
.click(function() {
@ -422,11 +422,11 @@ SchemaAlignmentDialog.UINode.prototype._showNodeConfigDialog = function() {
if ((!("columnName" in self._node) || self._node.columnName == null) && columnIndex == 0) {
radio.attr("checked", "true");
} else if (column.headerLabel == self._node.columnName) {
} else if (column.name == self._node.columnName) {
radio.attr("checked", "true");
}
$('<span></span>').text(column.headerLabel).appendTo(tr.insertCell(1));
$('<span></span>').text(column.name).appendTo(tr.insertCell(1));
};
var columns = theProject.columnModel.columns;
for (var i = 0; i < columns.length; i++) {

View File

@ -30,7 +30,7 @@ SchemaAlignment.autoAlign = function() {
var queries = {};
for (var i = 0; i < candidates.length; i++) {
var candidate = candidates[i];
var name = SchemaAlignment._cleanName(candidate.column.headerLabel);
var name = SchemaAlignment._cleanName(candidate.column.name);
var key = "t" + i + ":search";
queries[key] = {
"query" : name,
@ -98,7 +98,7 @@ SchemaAlignment.createNewRootNode = function() {
var column = columns[i];
var target = {
nodeType: "cell-as-topic",
columnName: column.headerLabel,
columnName: column.name,
createForNoReconMatch: true
};
if ("reconConfig" in column && column.reconConfig != null) {
@ -108,7 +108,7 @@ SchemaAlignment.createNewRootNode = function() {
};
}
if (column.headerLabel == theProject.columnModel.keyColumnName) {
if (column.name == theProject.columnModel.keyColumnName) {
rootNode = target;
} else {
links.push({

View File

@ -176,7 +176,7 @@ DataTableCellUI.prototype._doJudgment = function(judgment, params) {
DataTableCellUI.prototype._doJudgmentForSimilarCells = function(judgment, params) {
params = params || {};
params.columnName = Gridworks.cellIndexToColumn(this._cellIndex).headerLabel;
params.columnName = Gridworks.cellIndexToColumn(this._cellIndex).name;
params.similarValue = this._cell.v;
params.judgment = judgment;
@ -215,7 +215,7 @@ DataTableCellUI.prototype._searchForMatch = function() {
};
if (checkSimilar[0].checked) {
params.similarValue = self._cell.v;
params.columnName = Gridworks.cellIndexToColumn(self._cellIndex).headerLabel;
params.columnName = Gridworks.cellIndexToColumn(self._cellIndex).name;
self._postProcessSeveralCells("recon-judge-similar-cells", params, true);
} else {

View File

@ -18,7 +18,7 @@ DataTableColumnHeaderUI.prototype._render = function() {
var headerLeft = headerTableRow.insertCell(0);
var headerRight = headerTableRow.insertCell(1);
$('<span></span>').html(this._column.headerLabel).appendTo(headerLeft);
$('<span></span>').html(this._column.name).appendTo(headerLeft);
$(headerRight).attr("width", "1%");
$('<img src="/images/menu-dropdown.png" />').addClass("column-header-menu").appendTo(headerRight).click(function() {
@ -108,8 +108,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"list",
{
"name" : self._column.headerLabel,
"columnName" : self._column.headerLabel,
"name" : self._column.name,
"columnName" : self._column.name,
"expression" : "value"
}
);
@ -126,8 +126,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"range",
{
"name" : self._column.headerLabel,
"columnName" : self._column.headerLabel,
"name" : self._column.name,
"columnName" : self._column.name,
"expression" : "value",
"mode" : "range",
"min" : 0,
@ -149,8 +149,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"text",
{
"name" : self._column.headerLabel,
"columnName" : self._column.headerLabel,
"name" : self._column.name,
"columnName" : self._column.name,
"mode" : "text",
"caseSensitive" : false
}
@ -163,8 +163,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"text",
{
"name" : self._column.headerLabel + " (regex)",
"columnName" : self._column.headerLabel,
"name" : self._column.name + " (regex)",
"columnName" : self._column.name,
"mode" : "regex",
"caseSensitive" : true
}
@ -178,8 +178,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"list",
{
"name" : self._column.headerLabel + ": Error?",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": Error?",
"columnName" : self._column.name,
"expression" : "isError(value)"
}
);
@ -191,8 +191,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"list",
{
"name" : self._column.headerLabel + ": Blank?",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": Blank?",
"columnName" : self._column.name,
"expression" : "isBlank(value)"
}
);
@ -294,8 +294,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"list",
{
"name" : self._column.headerLabel + ": judgment",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": judgment",
"columnName" : self._column.name,
"expression" : "cell.recon.judgment"
},
{
@ -311,8 +311,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"range",
{
"name" : self._column.headerLabel + ": best candidate's score",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": best candidate's score",
"columnName" : self._column.name,
"expression" : "cell.recon.best.score",
"mode" : "range"
},
@ -327,8 +327,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"list",
{
"name" : self._column.headerLabel + ": best candidate's type match",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": best candidate's type match",
"columnName" : self._column.name,
"expression" : "cell.recon.features.typeMatch"
},
{
@ -343,8 +343,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"list",
{
"name" : self._column.headerLabel + ": best candidate's name match",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": best candidate's name match",
"columnName" : self._column.name,
"expression" : "cell.recon.features.nameMatch"
},
{
@ -360,8 +360,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"range",
{
"name" : self._column.headerLabel + ": best candidate's name edit distance",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": best candidate's name edit distance",
"columnName" : self._column.name,
"expression" : "cell.recon.features.nameLevenshtein",
"mode" : "range"
},
@ -376,8 +376,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"range",
{
"name" : self._column.headerLabel + ": best candidate's name word similarity",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": best candidate's name word similarity",
"columnName" : self._column.name,
"expression" : "cell.recon.features.nameWordDistance",
"mode" : "range"
},
@ -393,8 +393,8 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
ui.browsingEngine.addFacet(
"list",
{
"name" : self._column.headerLabel + ": best candidate's types",
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": best candidate's types",
"columnName" : self._column.name,
"expression" : "cell.recon.best.type"
}
);
@ -409,12 +409,12 @@ DataTableColumnHeaderUI.prototype._doFilterByExpressionPrompt = function(express
var self = this;
DataTableView.promptExpressionOnVisibleRows(
this._column,
(type == "list" ? "Custom Facet on column " : "Custom Numeric Facet on column") + this._column.headerLabel,
(type == "list" ? "Custom Facet on column " : "Custom Numeric Facet on column") + this._column.name,
expression,
function(expression) {
var config = {
"name" : self._column.headerLabel + ": " + expression,
"columnName" : self._column.headerLabel,
"name" : self._column.name + ": " + expression,
"columnName" : self._column.name,
"expression" : expression
};
if (type == "range") {
@ -430,7 +430,7 @@ DataTableColumnHeaderUI.prototype._doTextTransform = function(expression, onErro
Gridworks.postProcess(
"do-text-transform",
{
columnName: this._column.headerLabel,
columnName: this._column.name,
expression: expression,
onError: onError,
repeat: repeat,
@ -446,7 +446,7 @@ DataTableColumnHeaderUI.prototype._doTextTransformPrompt = function() {
var frame = DialogSystem.createDialog();
frame.width("700px");
var header = $('<div></div>').addClass("dialog-header").text("Custom text transform on column " + this._column.headerLabel).appendTo(frame);
var header = $('<div></div>').addClass("dialog-header").text("Custom text transform on column " + this._column.name).appendTo(frame);
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
@ -519,7 +519,7 @@ DataTableColumnHeaderUI.prototype._doReconcile = function() {
var self = this;
var dismissBusy = DialogSystem.showBusy();
$.post(
"/command/guess-types-of-column?" + $.param({ project: theProject.id, columnName: this._column.headerLabel }),
"/command/guess-types-of-column?" + $.param({ project: theProject.id, columnName: this._column.name }),
null,
function(data) {
if (data.code != "ok") {
@ -575,7 +575,7 @@ DataTableColumnHeaderUI.prototype._doReconcile = function() {
DataTableColumnHeaderUI.prototype._doReconDiscardJudgments = function() {
Gridworks.postProcess(
"recon-discard-judgments",
{ columnName: this._column.headerLabel },
{ columnName: this._column.name },
null,
{ cellsChanged: true, columnStatsChanged: true }
);
@ -584,7 +584,7 @@ DataTableColumnHeaderUI.prototype._doReconDiscardJudgments = function() {
DataTableColumnHeaderUI.prototype._doReconMatchBestCandidates = function() {
Gridworks.postProcess(
"recon-match-best-candidates",
{ columnName: this._column.headerLabel },
{ columnName: this._column.name },
null,
{ cellsChanged: true, columnStatsChanged: true }
);
@ -593,7 +593,7 @@ DataTableColumnHeaderUI.prototype._doReconMatchBestCandidates = function() {
DataTableColumnHeaderUI.prototype._doReconMarkNewTopics = function(shareNewTopics) {
Gridworks.postProcess(
"recon-mark-new-topics",
{ columnName: this._column.headerLabel, shareNewTopics: shareNewTopics },
{ columnName: this._column.name, shareNewTopics: shareNewTopics },
null,
{ cellsChanged: true, columnStatsChanged: true }
);
@ -616,7 +616,7 @@ DataTableColumnHeaderUI.prototype._doSearchToMatch = function() {
Gridworks.postProcess(
"recon-match-specific-topic-to-cells",
{
columnName: self._column.headerLabel,
columnName: self._column.name,
topicID: data.id,
topicGUID: data.guid,
topicName: data.name,
@ -642,7 +642,7 @@ DataTableColumnHeaderUI.prototype._doAddColumn = function(initialExpression) {
var frame = DialogSystem.createDialog();
frame.width("700px");
var header = $('<div></div>').addClass("dialog-header").text("Add Column Based on Column " + this._column.headerLabel).appendTo(frame);
var header = $('<div></div>').addClass("dialog-header").text("Add Column Based on Column " + this._column.name).appendTo(frame);
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
@ -694,9 +694,9 @@ DataTableColumnHeaderUI.prototype._doAddColumn = function(initialExpression) {
Gridworks.postProcess(
"add-column",
{
baseColumnName: self._column.headerLabel,
baseColumnName: self._column.name,
expression: previewWidget.getExpression(true),
headerLabel: columnName,
newColumnName: columnName,
columnInsertIndex: self._columnIndex + 1,
onError: $('input[name="create-column-dialog-onerror-choice"]:checked')[0].value
},
@ -721,7 +721,7 @@ DataTableColumnHeaderUI.prototype._doRemoveColumn = function() {
Gridworks.postProcess(
"remove-column",
{
columnName: this._column.headerLabel
columnName: this._column.name
},
null,
{ modelsChanged: true }
@ -734,7 +734,7 @@ DataTableColumnHeaderUI.prototype._doJoinMultiValueCells = function() {
Gridworks.postProcess(
"join-multi-value-cells",
{
columnName: this._column.headerLabel,
columnName: this._column.name,
keyColumnName: theProject.columnModel.keyColumnName,
separator: separator
},
@ -750,7 +750,7 @@ DataTableColumnHeaderUI.prototype._doSplitMultiValueCells = function() {
Gridworks.postProcess(
"split-multi-value-cells",
{
columnName: this._column.headerLabel,
columnName: this._column.name,
keyColumnName: theProject.columnModel.keyColumnName,
separator: separator,
mode: "plain"

View File

@ -179,7 +179,7 @@ DataTableView.prototype.render = function() {
$(td).addClass("column-header");
if (column.collapsed) {
$(td).html("&nbsp;").attr("title", column.headerLabel).click(function(evt) {
$(td).html("&nbsp;").attr("title", column.name).click(function(evt) {
column.collapsed = false;
self.render();
});