Internal refactor for IO - HistoryEntry is now a concrete class, so can be instantiated (reverting Operations classes back to r972 which were changed as a result of HistoryEntry being abstract).

HistoryEntry now deals with backend (filesystem etc.) through classes which implement HistoryEntryManager.  This HistoryEntryManager is held by ProjectManager, which allows for FileProjectManager to create FileHistoryEntryManager as appropriate.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@982 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
Iain Sproat 2010-06-16 12:35:37 +00:00
parent 280daad2f6
commit f92fc2d056
23 changed files with 447 additions and 466 deletions

View File

@ -2,7 +2,6 @@ package com.metaweb.gridworks;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -11,9 +10,7 @@ import org.apache.tools.tar.TarOutputStream;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.metaweb.gridworks.history.Change; import com.metaweb.gridworks.history.HistoryEntryManager;
import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation;
import com.metaweb.gridworks.model.Project; import com.metaweb.gridworks.model.Project;
@ -44,6 +41,8 @@ public abstract class ProjectManager {
*/ */
transient protected Map<Long, Project> _projects; transient protected Map<Long, Project> _projects;
protected HistoryEntryManager _historyEntryManager;
static public ProjectManager singleton; static public ProjectManager singleton;
public InterProjectModel getInterProjectModel() { public InterProjectModel getInterProjectModel() {
@ -126,6 +125,9 @@ public abstract class ProjectManager {
public abstract void deleteProject(long projectID) ; public abstract void deleteProject(long projectID) ;
public abstract HistoryEntry createHistoryEntry(long id, long projectID, String description, AbstractOperation operation, Date time); //public abstract HistoryEntry createHistoryEntry(long id, long projectID, String description, AbstractOperation operation, Date time);
public abstract HistoryEntry createHistoryEntry(long id, Project project, String description, AbstractOperation operation, Change change); //public abstract HistoryEntry createHistoryEntry(long id, Project project, String description, AbstractOperation operation, Change change);
public HistoryEntryManager getHistoryEntryManager(){
return this._historyEntryManager;
}
} }

View File

@ -10,7 +10,6 @@ import javax.servlet.http.HttpServletResponse;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.commands.Command; import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.history.Change; import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
@ -122,7 +121,7 @@ public class EditOneCellCommand extends Command {
Change change = new CellChange(rowIndex, cellIndex, cell, newCell); Change change = new CellChange(rowIndex, cellIndex, cell, newCell);
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, _project, description, null, change); historyEntryID, _project, description, null, change);
} }
} }

View File

@ -9,7 +9,6 @@ import javax.servlet.http.HttpServletResponse;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.commands.Command; import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.expr.ExpressionUtils; import com.metaweb.gridworks.expr.ExpressionUtils;
import com.metaweb.gridworks.history.Change; import com.metaweb.gridworks.history.Change;
@ -199,7 +198,7 @@ public class ReconJudgeOneCellCommand extends Command {
stats stats
); );
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, _project, description, null, change); historyEntryID, _project, description, null, change);
} }
} }

View File

@ -6,7 +6,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.commands.Command; import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.Project; import com.metaweb.gridworks.model.Project;
@ -83,7 +82,7 @@ public class AnnotateOneRowCommand extends Command {
} }
protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception {
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
_project, _project,
(starred ? "Star row " : "Unstar row ") + (rowIndex + 1), (starred ? "Star row " : "Unstar row ") + (rowIndex + 1),
@ -109,7 +108,7 @@ public class AnnotateOneRowCommand extends Command {
} }
protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception {
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
_project, _project,
(flagged ? "Flag row " : "Unflag row ") + (rowIndex + 1), (flagged ? "Flag row " : "Unflag row ") + (rowIndex + 1),

View File

@ -38,18 +38,18 @@ public class History implements Jsonizable {
reader.close(); reader.close();
} }
} }
static public Change readOneChange(LineNumberReader reader, Pool pool) throws Exception { static public Change readOneChange(LineNumberReader reader, Pool pool) throws Exception {
/* String version = */ reader.readLine(); /* String version = */ reader.readLine();
String className = reader.readLine(); String className = reader.readLine();
Class<? extends Change> klass = getChangeClass(className); Class<? extends Change> klass = getChangeClass(className);
Method load = klass.getMethod("load", LineNumberReader.class, Pool.class); Method load = klass.getMethod("load", LineNumberReader.class, Pool.class);
return (Change) load.invoke(null, reader, pool); return (Change) load.invoke(null, reader, pool);
} }
static public void writeOneChange(OutputStream out, Change change, Pool pool) throws IOException { static public void writeOneChange(OutputStream out, Change change, Pool pool) throws IOException {
Writer writer = new OutputStreamWriter(out); Writer writer = new OutputStreamWriter(out);
try { try {
@ -58,47 +58,47 @@ public class History implements Jsonizable {
writer.flush(); writer.flush();
} }
} }
static public void writeOneChange(Writer writer, Change change, Pool pool) throws IOException { static public void writeOneChange(Writer writer, Change change, Pool pool) throws IOException {
Properties options = new Properties(); Properties options = new Properties();
options.setProperty("mode", "save"); options.setProperty("mode", "save");
options.put("pool", pool); options.put("pool", pool);
writeOneChange(writer, change, options); writeOneChange(writer, change, options);
} }
static public void writeOneChange(Writer writer, Change change, Properties options) throws IOException { static public void writeOneChange(Writer writer, Change change, Properties options) throws IOException {
writer.write(GridworksServlet.getVersion()); writer.write('\n'); writer.write(GridworksServlet.getVersion()); writer.write('\n');
writer.write(change.getClass().getName()); writer.write('\n'); writer.write(change.getClass().getName()); writer.write('\n');
change.save(writer, options); change.save(writer, options);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
static public Class<? extends Change> getChangeClass(String className) throws ClassNotFoundException { static public Class<? extends Change> getChangeClass(String className) throws ClassNotFoundException {
return (Class<? extends Change>) Class.forName(className); return (Class<? extends Change>) Class.forName(className);
} }
protected long _projectID; protected long _projectID;
protected List<HistoryEntry> _pastEntries; // done changes, can be undone protected List<HistoryEntry> _pastEntries; // done changes, can be undone
protected List<HistoryEntry> _futureEntries; // undone changes, can be redone protected List<HistoryEntry> _futureEntries; // undone changes, can be redone
public History(Project project) { public History(Project project) {
_projectID = project.id; _projectID = project.id;
_pastEntries = new ArrayList<HistoryEntry>(); _pastEntries = new ArrayList<HistoryEntry>();
_futureEntries = new ArrayList<HistoryEntry>(); _futureEntries = new ArrayList<HistoryEntry>();
} }
synchronized public void addEntry(HistoryEntry entry) { synchronized public void addEntry(HistoryEntry entry) {
entry.apply(ProjectManager.singleton.getProject(_projectID)); entry.apply(ProjectManager.singleton.getProject(_projectID));
_pastEntries.add(entry); _pastEntries.add(entry);
setModified(); setModified();
// Any new change will clear all future entries. // Any new change will clear all future entries.
List<HistoryEntry> futureEntries = _futureEntries; List<HistoryEntry> futureEntries = _futureEntries;
_futureEntries = new ArrayList<HistoryEntry>(); _futureEntries = new ArrayList<HistoryEntry>();
for (HistoryEntry entry2 : futureEntries) { for (HistoryEntry entry2 : futureEntries) {
try { try {
// remove residual data on disk // remove residual data on disk
@ -108,11 +108,11 @@ public class History implements Jsonizable {
} }
} }
} }
protected void setModified() { protected void setModified() {
ProjectManager.singleton.getProjectMetadata(_projectID).updateModified(); ProjectManager.singleton.getProjectMetadata(_projectID).updateModified();
} }
synchronized public List<HistoryEntry> getLastPastEntries(int count) { synchronized public List<HistoryEntry> getLastPastEntries(int count) {
if (count <= 0) { if (count <= 0) {
return new LinkedList<HistoryEntry>(_pastEntries); return new LinkedList<HistoryEntry>(_pastEntries);
@ -120,7 +120,7 @@ public class History implements Jsonizable {
return _pastEntries.subList(Math.max(_pastEntries.size() - count, 0), _pastEntries.size()); return _pastEntries.subList(Math.max(_pastEntries.size() - count, 0), _pastEntries.size());
} }
} }
synchronized public void undoRedo(long lastDoneEntryID) { synchronized public void undoRedo(long lastDoneEntryID) {
if (lastDoneEntryID == 0) { if (lastDoneEntryID == 0) {
// undo all the way back to the start of the project // undo all the way back to the start of the project
@ -132,7 +132,7 @@ public class History implements Jsonizable {
return; return;
} }
} }
for (int i = 0; i < _futureEntries.size(); i++) { for (int i = 0; i < _futureEntries.size(); i++) {
if (_futureEntries.get(i).id == lastDoneEntryID) { if (_futureEntries.get(i).id == lastDoneEntryID) {
redo(i + 1); redo(i + 1);
@ -141,7 +141,7 @@ public class History implements Jsonizable {
} }
} }
} }
synchronized public long getPrecedingEntryID(long entryID) { synchronized public long getPrecedingEntryID(long entryID) {
if (entryID == 0) { if (entryID == 0) {
return -1; return -1;
@ -151,7 +151,7 @@ public class History implements Jsonizable {
return i == 0 ? 0 : _pastEntries.get(i - 1).id; return i == 0 ? 0 : _pastEntries.get(i - 1).id;
} }
} }
for (int i = 0; i < _futureEntries.size(); i++) { for (int i = 0; i < _futureEntries.size(); i++) {
if (_futureEntries.get(i).id == entryID) { if (_futureEntries.get(i).id == entryID) {
if (i > 0) { if (i > 0) {
@ -166,14 +166,14 @@ public class History implements Jsonizable {
} }
return -1; return -1;
} }
protected HistoryEntry getEntry(long entryID) { protected HistoryEntry getEntry(long entryID) {
for (int i = 0; i < _pastEntries.size(); i++) { for (int i = 0; i < _pastEntries.size(); i++) {
if (_pastEntries.get(i).id == entryID) { if (_pastEntries.get(i).id == entryID) {
return _pastEntries.get(i); return _pastEntries.get(i);
} }
} }
for (int i = 0; i < _futureEntries.size(); i++) { for (int i = 0; i < _futureEntries.size(); i++) {
if (_futureEntries.get(i).id == entryID) { if (_futureEntries.get(i).id == entryID) {
return _futureEntries.get(i); return _futureEntries.get(i);
@ -181,89 +181,89 @@ public class History implements Jsonizable {
} }
return null; return null;
} }
protected void undo(int times) { protected void undo(int times) {
Project project = ProjectManager.singleton.getProject(_projectID); Project project = ProjectManager.singleton.getProject(_projectID);
while (times > 0 && _pastEntries.size() > 0) { while (times > 0 && _pastEntries.size() > 0) {
HistoryEntry entry = _pastEntries.get(_pastEntries.size() - 1); HistoryEntry entry = _pastEntries.get(_pastEntries.size() - 1);
entry.revert(project); entry.revert(project);
setModified(); setModified();
times--; times--;
_pastEntries.remove(_pastEntries.size() - 1); _pastEntries.remove(_pastEntries.size() - 1);
_futureEntries.add(0, entry); _futureEntries.add(0, entry);
} }
} }
protected void redo(int times) { protected void redo(int times) {
Project project = ProjectManager.singleton.getProject(_projectID); Project project = ProjectManager.singleton.getProject(_projectID);
while (times > 0 && _futureEntries.size() > 0) { while (times > 0 && _futureEntries.size() > 0) {
HistoryEntry entry = _futureEntries.get(0); HistoryEntry entry = _futureEntries.get(0);
entry.apply(project); entry.apply(project);
setModified(); setModified();
times--; times--;
_pastEntries.add(entry); _pastEntries.add(entry);
_futureEntries.remove(0); _futureEntries.remove(0);
} }
} }
synchronized public void write(JSONWriter writer, Properties options) synchronized public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("past"); writer.array(); writer.key("past"); writer.array();
for (HistoryEntry entry : _pastEntries) { for (HistoryEntry entry : _pastEntries) {
entry.write(writer, options); entry.write(writer, options);
} }
writer.endArray(); writer.endArray();
writer.key("future"); writer.array(); writer.key("future"); writer.array();
for (HistoryEntry entry : _futureEntries) { for (HistoryEntry entry : _futureEntries) {
entry.write(writer, options); entry.write(writer, options);
} }
writer.endArray(); writer.endArray();
writer.endObject(); writer.endObject();
} }
synchronized public void save(Writer writer, Properties options) throws IOException { synchronized public void save(Writer writer, Properties options) throws IOException {
writer.write("pastEntryCount="); writer.write(Integer.toString(_pastEntries.size())); writer.write('\n'); writer.write("pastEntryCount="); writer.write(Integer.toString(_pastEntries.size())); writer.write('\n');
for (HistoryEntry entry : _pastEntries) { for (HistoryEntry entry : _pastEntries) {
entry.save(writer, options); writer.write('\n'); entry.save(writer, options); writer.write('\n');
} }
writer.write("futureEntryCount="); writer.write(Integer.toString(_futureEntries.size())); writer.write('\n'); writer.write("futureEntryCount="); writer.write(Integer.toString(_futureEntries.size())); writer.write('\n');
for (HistoryEntry entry : _futureEntries) { for (HistoryEntry entry : _futureEntries) {
entry.save(writer, options); writer.write('\n'); entry.save(writer, options); writer.write('\n');
} }
writer.write("/e/\n"); writer.write("/e/\n");
} }
synchronized public void load(Project project, LineNumberReader reader) throws Exception { synchronized public void load(Project project, LineNumberReader reader) throws Exception {
String line; String line;
while ((line = reader.readLine()) != null && !"/e/".equals(line)) { while ((line = reader.readLine()) != null && !"/e/".equals(line)) {
int equal = line.indexOf('='); int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal); CharSequence field = line.subSequence(0, equal);
String value = line.substring(equal + 1); String value = line.substring(equal + 1);
if ("pastEntryCount".equals(field)) { if ("pastEntryCount".equals(field)) {
int count = Integer.parseInt(value); int count = Integer.parseInt(value);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
_pastEntries.add(HistoryEntry.load(project, reader.readLine())); _pastEntries.add(HistoryEntry.load(project, reader.readLine()));
} }
} else if ("futureEntryCount".equals(field)) { } else if ("futureEntryCount".equals(field)) {
int count = Integer.parseInt(value); int count = Integer.parseInt(value);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
_futureEntries.add(HistoryEntry.load(project, reader.readLine())); _futureEntries.add(HistoryEntry.load(project, reader.readLine()));
} }

View File

@ -19,20 +19,31 @@ import com.metaweb.gridworks.util.ParsingUtilities;
* This is the metadata of a Change. It's small, so we can load it in order to * This is the metadata of a Change. It's small, so we can load it in order to
* obtain information about a change without actually loading the change. * obtain information about a change without actually loading the change.
*/ */
public abstract class HistoryEntry implements Jsonizable { public class HistoryEntry implements Jsonizable {
final public long id; final public long id;
final public long projectID; final public long projectID;
final public String description; final public String description;
final public Date time; final public Date time;
// the manager (deals with IO systems or databases etc.)
final public HistoryEntryManager _manager;
// the abstract operation, if any, that results in the change // the abstract operation, if any, that results in the change
final public AbstractOperation operation; final public AbstractOperation operation;
// the actual change, loaded on demand // the actual change, loaded on demand
transient protected Change _change; private transient Change _change;
private final static String OPERATION = "operation"; private final static String OPERATION = "operation";
public void setChange(Change _change) {
this._change = _change;
}
public Change getChange() {
return _change;
}
static public long allocateID() { static public long allocateID() {
return Math.round(Math.random() * 1000000) + System.currentTimeMillis(); return Math.round(Math.random() * 1000000) + System.currentTimeMillis();
} }
@ -44,7 +55,8 @@ public abstract class HistoryEntry implements Jsonizable {
this.operation = operation; this.operation = operation;
this.time = new Date(); this.time = new Date();
_change = change; this._manager = ProjectManager.singleton.getHistoryEntryManager();
setChange(change);
} }
protected HistoryEntry(long id, long projectID, String description, AbstractOperation operation, Date time) { protected HistoryEntry(long id, long projectID, String description, AbstractOperation operation, Date time) {
@ -53,6 +65,7 @@ public abstract class HistoryEntry implements Jsonizable {
this.description = description; this.description = description;
this.operation = operation; this.operation = operation;
this.time = time; this.time = time;
this._manager = ProjectManager.singleton.getHistoryEntryManager();
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
@ -68,23 +81,27 @@ public abstract class HistoryEntry implements Jsonizable {
writer.endObject(); writer.endObject();
} }
public void save(Writer writer, Properties options){
_manager.save(this, writer, options);
}
public void apply(Project project) { public void apply(Project project) {
if (_change == null) { if (getChange() == null) {
loadChange(); ProjectManager.singleton.getHistoryEntryManager().loadChange(this);
} }
synchronized (project) { synchronized (project) {
_change.apply(project); getChange().apply(project);
// When a change is applied, it can hang on to old data (in order to be able // 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. // to revert later). Hence, we need to save the change out.
try { try {
saveChange(); _manager.saveChange(this);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
_change.revert(project); getChange().revert(project);
throw new RuntimeException("Failed to apply change", e); throw new RuntimeException("Failed to apply change", e);
} }
@ -92,20 +109,12 @@ public abstract class HistoryEntry implements Jsonizable {
} }
public void revert(Project project) { public void revert(Project project) {
if (_change == null) { if (getChange() == null) {
loadChange(); _manager.loadChange(this);
} }
_change.revert(project); getChange().revert(project);
} }
public abstract void loadChange();
protected abstract void saveChange() throws Exception;
public abstract void save(Writer writer, Properties options);
protected abstract void delete();
static public HistoryEntry load(Project project, String s) throws Exception { static public HistoryEntry load(Project project, String s) throws Exception {
JSONObject obj = ParsingUtilities.evaluateJsonStringToObject(s); JSONObject obj = ParsingUtilities.evaluateJsonStringToObject(s);
@ -114,7 +123,7 @@ public abstract class HistoryEntry implements Jsonizable {
operation = OperationRegistry.reconstruct(project, obj.getJSONObject(OPERATION)); operation = OperationRegistry.reconstruct(project, obj.getJSONObject(OPERATION));
} }
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
obj.getLong("id"), obj.getLong("id"),
project.id, project.id,
obj.getString("description"), obj.getString("description"),
@ -123,6 +132,8 @@ public abstract class HistoryEntry implements Jsonizable {
); );
} }
public void delete(){
_manager.delete(this);
}
} }

View File

@ -8,55 +8,46 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import java.io.Writer; import java.io.Writer;
import java.util.Date;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager; import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.History; import com.metaweb.gridworks.history.History;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation; import com.metaweb.gridworks.history.HistoryEntryManager;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.util.Pool; import com.metaweb.gridworks.util.Pool;
public class FileHistoryEntry extends HistoryEntry{ public class FileHistoryEntry implements HistoryEntryManager{
protected FileHistoryEntry(long id, long projectID, String description, AbstractOperation operation, Date time) {
super(id, projectID, description, operation, time);
}
protected FileHistoryEntry(long id, Project project, String description, AbstractOperation operation, Change change){
super(id, project, description, operation, change);
}
protected void delete() { public void delete(HistoryEntry historyEntry) {
File file = getChangeFile(); File file = getChangeFile(historyEntry);
if (file.exists()) { if (file.exists()) {
file.delete(); file.delete();
} }
} }
public void save(Writer writer, Properties options) { public void save(HistoryEntry historyEntry, Writer writer, Properties options) {
JSONWriter jsonWriter = new JSONWriter(writer); JSONWriter jsonWriter = new JSONWriter(writer);
try { try {
write(jsonWriter, options); historyEntry.write(jsonWriter, options);
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void loadChange() { public void loadChange(HistoryEntry historyEntry) {
File changeFile = getChangeFile(); File changeFile = getChangeFile(historyEntry);
try { try {
loadChange(changeFile); loadChange(historyEntry, changeFile);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Failed to load change file " + changeFile.getAbsolutePath(), e); throw new RuntimeException("Failed to load change file " + changeFile.getAbsolutePath(), e);
} }
} }
protected void loadChange(File file) throws Exception { protected void loadChange(HistoryEntry historyEntry, File file) throws Exception {
ZipFile zipFile = new ZipFile(file); ZipFile zipFile = new ZipFile(file);
try { try {
Pool pool = new Pool(); Pool pool = new Pool();
@ -66,28 +57,28 @@ public class FileHistoryEntry extends HistoryEntry{
zipFile.getInputStream(poolEntry))); zipFile.getInputStream(poolEntry)));
} // else, it's a legacy project file } // else, it's a legacy project file
_change = History.readOneChange( historyEntry.setChange(History.readOneChange(
zipFile.getInputStream(zipFile.getEntry("change.txt")), pool); zipFile.getInputStream(zipFile.getEntry("change.txt")), pool));
} finally { } finally {
zipFile.close(); zipFile.close();
} }
} }
protected void saveChange() throws Exception { public void saveChange(HistoryEntry historyEntry) throws Exception {
File changeFile = getChangeFile(); File changeFile = getChangeFile(historyEntry);
if (!(changeFile.exists())) { if (!(changeFile.exists())) {
saveChange(changeFile); saveChange(historyEntry, changeFile);
} }
} }
protected void saveChange(File file) throws Exception { protected void saveChange(HistoryEntry historyEntry, File file) throws Exception {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file)); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file));
try { try {
Pool pool = new Pool(); Pool pool = new Pool();
out.putNextEntry(new ZipEntry("change.txt")); out.putNextEntry(new ZipEntry("change.txt"));
try { try {
History.writeOneChange(out, _change, pool); History.writeOneChange(out, historyEntry.getChange(), pool);
} finally { } finally {
out.closeEntry(); out.closeEntry();
} }
@ -103,12 +94,14 @@ public class FileHistoryEntry extends HistoryEntry{
} }
} }
protected File getChangeFile() { protected File getChangeFile(HistoryEntry historyEntry) {
return new File(getHistoryDir(), id + ".change.zip"); return new File(getHistoryDir(historyEntry), historyEntry.id + ".change.zip");
} }
protected File getHistoryDir() {//FIXME relies on FileProjectManager protected File getHistoryDir(HistoryEntry historyEntry) {
File dir = new File(((FileProjectManager)ProjectManager.singleton).getProjectDir(projectID), "history"); File dir = new File(((FileProjectManager)ProjectManager.singleton)
.getProjectDir(historyEntry.projectID),
"history");
dir.mkdirs(); dir.mkdirs();
return dir; return dir;

View File

@ -30,9 +30,6 @@ import org.slf4j.LoggerFactory;
import com.metaweb.gridworks.ProjectManager; import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.ProjectMetadata; import com.metaweb.gridworks.ProjectMetadata;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation;
import com.metaweb.gridworks.model.Project; import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.util.JSONUtilities; import com.metaweb.gridworks.util.JSONUtilities;
@ -47,6 +44,7 @@ public class FileProjectManager extends ProjectManager{
logger.info("Using workspace directory: {}", dir.getAbsolutePath()); logger.info("Using workspace directory: {}", dir.getAbsolutePath());
singleton = new FileProjectManager(dir); singleton = new FileProjectManager(dir);
} }
} }
private FileProjectManager(File dir) { private FileProjectManager(File dir) {
@ -57,6 +55,8 @@ public class FileProjectManager extends ProjectManager{
_expressions = new LinkedList<String>(); _expressions = new LinkedList<String>();
_projects = new HashMap<Long, Project>(); _projects = new HashMap<Long, Project>();
_historyEntryManager = new FileHistoryEntry();
load(); load();
} }
@ -445,11 +445,4 @@ public class FileProjectManager extends ProjectManager{
return found; return found;
} }
public HistoryEntry createHistoryEntry(long id, long projectID, String description, AbstractOperation operation, Date time){
return new FileHistoryEntry(id, projectID, description, operation, time);
}
public HistoryEntry createHistoryEntry(long id, Project project, String description, AbstractOperation operation, Change change){
return new FileHistoryEntry(id, project, description, operation, change);
}
} }

View File

@ -5,7 +5,6 @@ import java.util.List;
import org.json.JSONObject; import org.json.JSONObject;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.FilteredRows;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -19,7 +18,7 @@ import com.metaweb.gridworks.model.changes.MassCellChange;
abstract public class EngineDependentMassCellOperation extends EngineDependentOperation { abstract public class EngineDependentMassCellOperation extends EngineDependentOperation {
final protected String _columnName; final protected String _columnName;
final protected boolean _updateRowContextDependencies; final protected boolean _updateRowContextDependencies;
protected EngineDependentMassCellOperation( protected EngineDependentMassCellOperation(
JSONObject engineConfig, String columnName, boolean updateRowContextDependencies) { JSONObject engineConfig, String columnName, boolean updateRowContextDependencies) {
super(engineConfig); super(engineConfig);
@ -29,32 +28,32 @@ abstract public class EngineDependentMassCellOperation extends EngineDependentOp
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
Engine engine = createEngine(project); Engine engine = createEngine(project);
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
if (column == null) { if (column == null) {
throw new Exception("No column named " + _columnName); throw new Exception("No column named " + _columnName);
} }
List<CellChange> cellChanges = new ArrayList<CellChange>(project.rows.size()); List<CellChange> cellChanges = new ArrayList<CellChange>(project.rows.size());
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
try { try {
filteredRows.accept(project, createRowVisitor(project, cellChanges, historyEntryID)); filteredRows.accept(project, createRowVisitor(project, cellChanges, historyEntryID));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
String description = createDescription(column, cellChanges); String description = createDescription(column, cellChanges);
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, project, description, this, createChange(project, column, cellChanges)); historyEntryID, project, description, this, createChange(project, column, cellChanges));
} }
protected Change createChange(Project project, Column column, List<CellChange> cellChanges) { protected Change createChange(Project project, Column column, List<CellChange> cellChanges) {
return new MassCellChange( return new MassCellChange(
cellChanges, column.getName(), _updateRowContextDependencies); cellChanges, column.getName(), _updateRowContextDependencies);
} }
abstract protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception; abstract protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception;
abstract protected String createDescription(Column column, List<CellChange> cellChanges); abstract protected String createDescription(Column column, List<CellChange> cellChanges);
} }

View File

@ -9,7 +9,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.history.Change; import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation; import com.metaweb.gridworks.model.AbstractOperation;
@ -20,20 +19,20 @@ import com.metaweb.gridworks.util.Pool;
public class SaveProtographOperation extends AbstractOperation { public class SaveProtographOperation extends AbstractOperation {
final protected Protograph _protograph; final protected Protograph _protograph;
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
return new SaveProtographOperation( return new SaveProtographOperation(
Protograph.reconstruct(obj.getJSONObject("protograph")) Protograph.reconstruct(obj.getJSONObject("protograph"))
); );
} }
public SaveProtographOperation(Protograph protograph) { public SaveProtographOperation(Protograph protograph) {
_protograph = protograph; _protograph = protograph;
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value("Save protograph"); writer.key("description"); writer.value("Save protograph");
@ -48,20 +47,20 @@ public class SaveProtographOperation extends AbstractOperation {
@Override @Override
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
String description = "Save schema-alignment protograph"; String description = "Save schema-alignment protograph";
Change change = new ProtographChange(_protograph); Change change = new ProtographChange(_protograph);
return ProjectManager.singleton.createHistoryEntry(historyEntryID, project, description, SaveProtographOperation.this, change); return new HistoryEntry(historyEntryID, project, description, SaveProtographOperation.this, change);
} }
static public class ProtographChange implements Change { static public class ProtographChange implements Change {
final protected Protograph _newProtograph; final protected Protograph _newProtograph;
protected Protograph _oldProtograph; protected Protograph _oldProtograph;
public ProtographChange(Protograph protograph) { public ProtographChange(Protograph protograph) {
_newProtograph = protograph; _newProtograph = protograph;
} }
public void apply(Project project) { public void apply(Project project) {
synchronized (project) { synchronized (project) {
_oldProtograph = project.protograph; _oldProtograph = project.protograph;
@ -74,36 +73,36 @@ public class SaveProtographOperation extends AbstractOperation {
project.protograph = _oldProtograph; project.protograph = _oldProtograph;
} }
} }
public void save(Writer writer, Properties options) throws IOException { public void save(Writer writer, Properties options) throws IOException {
writer.write("newProtograph="); writeProtograph(_newProtograph, writer); writer.write('\n'); writer.write("newProtograph="); writeProtograph(_newProtograph, writer); writer.write('\n');
writer.write("oldProtograph="); writeProtograph(_oldProtograph, writer); writer.write('\n'); writer.write("oldProtograph="); writeProtograph(_oldProtograph, writer); writer.write('\n');
writer.write("/ec/\n"); // end of change marker writer.write("/ec/\n"); // end of change marker
} }
static public Change load(LineNumberReader reader, Pool pool) throws Exception { static public Change load(LineNumberReader reader, Pool pool) throws Exception {
Protograph oldProtograph = null; Protograph oldProtograph = null;
Protograph newProtograph = null; Protograph newProtograph = null;
String line; String line;
while ((line = reader.readLine()) != null && !"/ec/".equals(line)) { while ((line = reader.readLine()) != null && !"/ec/".equals(line)) {
int equal = line.indexOf('='); int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal); CharSequence field = line.subSequence(0, equal);
String value = line.substring(equal + 1); String value = line.substring(equal + 1);
if ("oldProtograph".equals(field) && value.length() > 0) { if ("oldProtograph".equals(field) && value.length() > 0) {
oldProtograph = Protograph.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value)); oldProtograph = Protograph.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value));
} else if ("newProtograph".equals(field) && value.length() > 0) { } else if ("newProtograph".equals(field) && value.length() > 0) {
newProtograph = Protograph.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value)); newProtograph = Protograph.reconstruct(ParsingUtilities.evaluateJsonStringToObject(value));
} }
} }
ProtographChange change = new ProtographChange(newProtograph); ProtographChange change = new ProtographChange(newProtograph);
change._oldProtograph = oldProtograph; change._oldProtograph = oldProtograph;
return change; return change;
} }
static protected void writeProtograph(Protograph p, Writer writer) throws IOException { static protected void writeProtograph(Protograph p, Writer writer) throws IOException {
if (p != null) { if (p != null) {
JSONWriter jsonWriter = new JSONWriter(writer); JSONWriter jsonWriter = new JSONWriter(writer);
@ -114,5 +113,5 @@ public class SaveProtographOperation extends AbstractOperation {
} }
} }
} }
} }
} }

View File

@ -8,7 +8,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.expr.ExpressionUtils; import com.metaweb.gridworks.expr.ExpressionUtils;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation; import com.metaweb.gridworks.model.AbstractOperation;
@ -31,7 +30,7 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
obj.getString("separator") obj.getString("separator")
); );
} }
public MultiValuedCellJoinOperation( public MultiValuedCellJoinOperation(
String columnName, String columnName,
String keyColumnName, String keyColumnName,
@ -44,7 +43,7 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -53,7 +52,7 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
writer.key("separator"); writer.value(_separator); writer.key("separator"); writer.value(_separator);
writer.endObject(); writer.endObject();
} }
protected String getBriefDescription(Project project) { protected String getBriefDescription(Project project) {
return "Join multi-valued cells in column " + _columnName; return "Join multi-valued cells in column " + _columnName;
} }
@ -64,34 +63,34 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
throw new Exception("No column named " + _columnName); throw new Exception("No column named " + _columnName);
} }
int cellIndex = column.getCellIndex(); int cellIndex = column.getCellIndex();
Column keyColumn = project.columnModel.getColumnByName(_keyColumnName); Column keyColumn = project.columnModel.getColumnByName(_keyColumnName);
if (keyColumn == null) { if (keyColumn == null) {
throw new Exception("No key column named " + _keyColumnName); throw new Exception("No key column named " + _keyColumnName);
} }
int keyCellIndex = keyColumn.getCellIndex(); int keyCellIndex = keyColumn.getCellIndex();
List<Row> newRows = new ArrayList<Row>(); List<Row> newRows = new ArrayList<Row>();
int oldRowCount = project.rows.size(); int oldRowCount = project.rows.size();
for (int r = 0; r < oldRowCount; r++) { for (int r = 0; r < oldRowCount; r++) {
Row oldRow = project.rows.get(r); Row oldRow = project.rows.get(r);
if (oldRow.isCellBlank(keyCellIndex)) { if (oldRow.isCellBlank(keyCellIndex)) {
newRows.add(oldRow.dup()); newRows.add(oldRow.dup());
continue; continue;
} }
int r2 = r + 1; int r2 = r + 1;
while (r2 < oldRowCount && project.rows.get(r2).isCellBlank(keyCellIndex)) { while (r2 < oldRowCount && project.rows.get(r2).isCellBlank(keyCellIndex)) {
r2++; r2++;
} }
if (r2 == r + 1) { if (r2 == r + 1) {
newRows.add(oldRow.dup()); newRows.add(oldRow.dup());
continue; continue;
} }
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
for (int r3 = r; r3 < r2; r3++) { for (int r3 = r; r3 < r2; r3++) {
Object value = project.rows.get(r3).getCellValue(cellIndex); Object value = project.rows.get(r3).getCellValue(cellIndex);
@ -102,7 +101,7 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
sb.append(value.toString()); sb.append(value.toString());
} }
} }
for (int r3 = r; r3 < r2; r3++) { for (int r3 = r; r3 < r2; r3++) {
Row newRow = project.rows.get(r3).dup(); Row newRow = project.rows.get(r3).dup();
if (r3 == r) { if (r3 == r) {
@ -110,20 +109,20 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
} else { } else {
newRow.setCell(cellIndex, null); newRow.setCell(cellIndex, null);
} }
if (!newRow.isEmpty()) { if (!newRow.isEmpty()) {
newRows.add(newRow); newRows.add(newRow);
} }
} }
r = r2 - 1; // r will be incremented by the for loop anyway r = r2 - 1; // r will be incremented by the for loop anyway
} }
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
project, project,
getBriefDescription(null), getBriefDescription(null),
this, this,
new MassRowChange(newRows) new MassRowChange(newRows)
); );
} }

View File

@ -9,7 +9,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation; import com.metaweb.gridworks.model.AbstractOperation;
import com.metaweb.gridworks.model.Cell; import com.metaweb.gridworks.model.Cell;
@ -33,7 +32,7 @@ public class MultiValuedCellSplitOperation extends AbstractOperation {
obj.getString("mode") obj.getString("mode")
); );
} }
public MultiValuedCellSplitOperation( public MultiValuedCellSplitOperation(
String columnName, String columnName,
String keyColumnName, String keyColumnName,
@ -48,7 +47,7 @@ public class MultiValuedCellSplitOperation extends AbstractOperation {
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value("Split multi-valued cells in column " + _columnName); writer.key("description"); writer.value("Split multi-valued cells in column " + _columnName);
@ -70,15 +69,15 @@ public class MultiValuedCellSplitOperation extends AbstractOperation {
throw new Exception("No column named " + _columnName); throw new Exception("No column named " + _columnName);
} }
int cellIndex = column.getCellIndex(); int cellIndex = column.getCellIndex();
Column keyColumn = project.columnModel.getColumnByName(_keyColumnName); Column keyColumn = project.columnModel.getColumnByName(_keyColumnName);
if (keyColumn == null) { if (keyColumn == null) {
throw new Exception("No key column named " + _keyColumnName); throw new Exception("No key column named " + _keyColumnName);
} }
int keyCellIndex = keyColumn.getCellIndex(); int keyCellIndex = keyColumn.getCellIndex();
List<Row> newRows = new ArrayList<Row>(); List<Row> newRows = new ArrayList<Row>();
int oldRowCount = project.rows.size(); int oldRowCount = project.rows.size();
for (int r = 0; r < oldRowCount; r++) { for (int r = 0; r < oldRowCount; r++) {
Row oldRow = project.rows.get(r); Row oldRow = project.rows.get(r);
@ -86,7 +85,7 @@ public class MultiValuedCellSplitOperation extends AbstractOperation {
newRows.add(oldRow.dup()); newRows.add(oldRow.dup());
continue; continue;
} }
Object value = oldRow.getCellValue(cellIndex); Object value = oldRow.getCellValue(cellIndex);
String s = value instanceof String ? ((String) value) : value.toString(); String s = value instanceof String ? ((String) value) : value.toString();
String[] values = null; String[] values = null;
@ -95,53 +94,53 @@ public class MultiValuedCellSplitOperation extends AbstractOperation {
} else { } else {
values = StringUtils.splitByWholeSeparator(s, _separator); values = StringUtils.splitByWholeSeparator(s, _separator);
} }
if (values.length < 2) { if (values.length < 2) {
newRows.add(oldRow.dup()); newRows.add(oldRow.dup());
continue; continue;
} }
// First value goes into the same row // First value goes into the same row
{ {
Row firstNewRow = oldRow.dup(); Row firstNewRow = oldRow.dup();
firstNewRow.setCell(cellIndex, new Cell(values[0].trim(), null)); firstNewRow.setCell(cellIndex, new Cell(values[0].trim(), null));
newRows.add(firstNewRow); newRows.add(firstNewRow);
} }
int r2 = r + 1; int r2 = r + 1;
for (int v = 1; v < values.length; v++) { for (int v = 1; v < values.length; v++) {
Cell newCell = new Cell(values[v].trim(), null); Cell newCell = new Cell(values[v].trim(), null);
if (r2 < project.rows.size()) { if (r2 < project.rows.size()) {
Row oldRow2 = project.rows.get(r2); Row oldRow2 = project.rows.get(r2);
if (oldRow2.isCellBlank(cellIndex) && if (oldRow2.isCellBlank(cellIndex) &&
oldRow2.isCellBlank(keyCellIndex)) { oldRow2.isCellBlank(keyCellIndex)) {
Row newRow = oldRow2.dup(); Row newRow = oldRow2.dup();
newRow.setCell(cellIndex, newCell); newRow.setCell(cellIndex, newCell);
newRows.add(newRow); newRows.add(newRow);
r2++; r2++;
continue; continue;
} }
} }
Row newRow = new Row(cellIndex + 1); Row newRow = new Row(cellIndex + 1);
newRow.setCell(cellIndex, newCell); newRow.setCell(cellIndex, newCell);
newRows.add(newRow); newRows.add(newRow);
} }
r = r2 - 1; // r will be incremented by the for loop anyway r = r2 - 1; // r will be incremented by the for loop anyway
} }
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
project, project,
getBriefDescription(null), getBriefDescription(null),
this, this,
new MassRowChange(newRows) new MassRowChange(newRows)
); );
} }

View File

@ -9,7 +9,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.FilteredRows;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -35,13 +34,13 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
final protected String _baseColumnName; final protected String _baseColumnName;
final protected String _expression; final protected String _expression;
final protected OnError _onError; final protected OnError _onError;
final protected String _newColumnName; final protected String _newColumnName;
final protected int _columnInsertIndex; final protected int _columnInsertIndex;
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig"); JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ColumnAdditionOperation( return new ColumnAdditionOperation(
engineConfig, engineConfig,
obj.getString("baseColumnName"), obj.getString("baseColumnName"),
@ -51,28 +50,28 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
obj.getInt("columnInsertIndex") obj.getInt("columnInsertIndex")
); );
} }
public ColumnAdditionOperation( public ColumnAdditionOperation(
JSONObject engineConfig, JSONObject engineConfig,
String baseColumnName, String baseColumnName,
String expression, String expression,
OnError onError, OnError onError,
String newColumnName, String newColumnName,
int columnInsertIndex int columnInsertIndex
) { ) {
super(engineConfig); super(engineConfig);
_baseColumnName = baseColumnName; _baseColumnName = baseColumnName;
_expression = expression; _expression = expression;
_onError = onError; _onError = onError;
_newColumnName = newColumnName; _newColumnName = newColumnName;
_columnInsertIndex = columnInsertIndex; _columnInsertIndex = columnInsertIndex;
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -86,52 +85,52 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
} }
protected String getBriefDescription(Project project) { protected String getBriefDescription(Project project) {
return "Create column " + _newColumnName + return "Create column " + _newColumnName +
" at index " + _columnInsertIndex + " at index " + _columnInsertIndex +
" based on column " + _baseColumnName + " based on column " + _baseColumnName +
" using expression " + _expression; " using expression " + _expression;
} }
protected String createDescription(Column column, List<CellAtRow> cellsAtRows) { protected String createDescription(Column column, List<CellAtRow> cellsAtRows) {
return "Create new column " + _newColumnName + return "Create new column " + _newColumnName +
" based on column " + column.getName() + " based on column " + column.getName() +
" by filling " + cellsAtRows.size() + " by filling " + cellsAtRows.size() +
" rows with " + _expression; " rows with " + _expression;
} }
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
Engine engine = createEngine(project); Engine engine = createEngine(project);
Column column = project.columnModel.getColumnByName(_baseColumnName); Column column = project.columnModel.getColumnByName(_baseColumnName);
if (column == null) { if (column == null) {
throw new Exception("No column named " + _baseColumnName); throw new Exception("No column named " + _baseColumnName);
} }
List<CellAtRow> cellsAtRows = new ArrayList<CellAtRow>(project.rows.size()); List<CellAtRow> cellsAtRows = new ArrayList<CellAtRow>(project.rows.size());
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
filteredRows.accept(project, createRowVisitor(project, cellsAtRows)); filteredRows.accept(project, createRowVisitor(project, cellsAtRows));
String description = createDescription(column, cellsAtRows); String description = createDescription(column, cellsAtRows);
Change change = new ColumnAdditionChange(_newColumnName, _columnInsertIndex, cellsAtRows); Change change = new ColumnAdditionChange(_newColumnName, _columnInsertIndex, cellsAtRows);
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, project, description, this, change); historyEntryID, project, description, this, change);
} }
protected RowVisitor createRowVisitor(Project project, List<CellAtRow> cellsAtRows) throws Exception { protected RowVisitor createRowVisitor(Project project, List<CellAtRow> cellsAtRows) throws Exception {
Column column = project.columnModel.getColumnByName(_baseColumnName); Column column = project.columnModel.getColumnByName(_baseColumnName);
Evaluable eval = MetaParser.parse(_expression); Evaluable eval = MetaParser.parse(_expression);
Properties bindings = ExpressionUtils.createBindings(project); Properties bindings = ExpressionUtils.createBindings(project);
return new RowVisitor() { return new RowVisitor() {
int cellIndex; int cellIndex;
Properties bindings; Properties bindings;
List<CellAtRow> cellsAtRows; List<CellAtRow> cellsAtRows;
Evaluable eval; Evaluable eval;
public RowVisitor init(int cellIndex, Properties bindings, List<CellAtRow> cellsAtRows, Evaluable eval) { public RowVisitor init(int cellIndex, Properties bindings, List<CellAtRow> cellsAtRows, Evaluable eval) {
this.cellIndex = cellIndex; this.cellIndex = cellIndex;
this.bindings = bindings; this.bindings = bindings;
@ -139,23 +138,23 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
this.eval = eval; this.eval = eval;
return this; return this;
} }
@Override @Override
public void start(Project project) { public void start(Project project) {
// nothing to do // nothing to do
} }
@Override @Override
public void end(Project project) { public void end(Project project) {
// nothing to do // nothing to do
} }
public boolean visit(Project project, int rowIndex, Row row) { public boolean visit(Project project, int rowIndex, Row row) {
Cell cell = row.getCell(cellIndex); Cell cell = row.getCell(cellIndex);
Cell newCell = null; Cell newCell = null;
ExpressionUtils.bind(bindings, row, rowIndex, _baseColumnName, cell); ExpressionUtils.bind(bindings, row, rowIndex, _baseColumnName, cell);
Object o = eval.evaluate(bindings); Object o = eval.evaluate(bindings);
if (o != null) { if (o != null) {
if (o instanceof Cell) { if (o instanceof Cell) {
@ -171,17 +170,17 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
v = cell != null ? cell.value : null; v = cell != null ? cell.value : null;
} }
} }
if (v != null) { if (v != null) {
newCell = new Cell(v, null); newCell = new Cell(v, null);
} }
} }
} }
if (newCell != null) { if (newCell != null) {
cellsAtRows.add(new CellAtRow(rowIndex, newCell)); cellsAtRows.add(new CellAtRow(rowIndex, newCell));
} }
return false; return false;
} }
}.init(column.getCellIndex(), bindings, cellsAtRows, eval); }.init(column.getCellIndex(), bindings, cellsAtRows, eval);

View File

@ -6,7 +6,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.history.Change; import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation; import com.metaweb.gridworks.model.AbstractOperation;
@ -23,16 +22,16 @@ public class ColumnRemovalOperation extends AbstractOperation {
obj.getString("columnName") obj.getString("columnName")
); );
} }
public ColumnRemovalOperation( public ColumnRemovalOperation(
String columnName String columnName
) { ) {
_columnName = columnName; _columnName = columnName;
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value("Remove column " + _columnName); writer.key("description"); writer.value("Remove column " + _columnName);
@ -50,11 +49,11 @@ public class ColumnRemovalOperation extends AbstractOperation {
if (column == null) { if (column == null) {
throw new Exception("No column named " + _columnName); throw new Exception("No column named " + _columnName);
} }
String description = "Remove column " + column.getName(); String description = "Remove column " + column.getName();
Change change = new ColumnRemovalChange(project.columnModel.columns.indexOf(column)); Change change = new ColumnRemovalChange(project.columnModel.columns.indexOf(column));
return ProjectManager.singleton.createHistoryEntry(historyEntryID, project, description, ColumnRemovalOperation.this, change); return new HistoryEntry(historyEntryID, project, description, ColumnRemovalOperation.this, change);
} }
} }

View File

@ -6,7 +6,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.history.Change; import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation; import com.metaweb.gridworks.model.AbstractOperation;
@ -24,7 +23,7 @@ public class ColumnRenameOperation extends AbstractOperation {
obj.getString("newColumnName") obj.getString("newColumnName")
); );
} }
public ColumnRenameOperation( public ColumnRenameOperation(
String oldColumnName, String oldColumnName,
String newColumnName String newColumnName
@ -32,10 +31,10 @@ public class ColumnRenameOperation extends AbstractOperation {
_oldColumnName = oldColumnName; _oldColumnName = oldColumnName;
_newColumnName = newColumnName; _newColumnName = newColumnName;
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value("Rename column " + _oldColumnName + " to " + _newColumnName); writer.key("description"); writer.value("Rename column " + _oldColumnName + " to " + _newColumnName);
@ -56,9 +55,9 @@ public class ColumnRenameOperation extends AbstractOperation {
if (project.columnModel.getColumnByName(_newColumnName) != null) { if (project.columnModel.getColumnByName(_newColumnName) != null) {
throw new Exception("Another column already named " + _newColumnName); throw new Exception("Another column already named " + _newColumnName);
} }
Change change = new ColumnRenameChange(_oldColumnName, _newColumnName); Change change = new ColumnRenameChange(_oldColumnName, _newColumnName);
return ProjectManager.singleton.createHistoryEntry(historyEntryID, project, getBriefDescription(null), ColumnRenameOperation.this, change); return new HistoryEntry(historyEntryID, project, getBriefDescription(null), ColumnRenameOperation.this, change);
} }
} }

View File

@ -11,7 +11,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.FilteredRows;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -33,17 +32,17 @@ public class ColumnSplitOperation extends EngineDependentOperation {
final protected boolean _guessCellType; final protected boolean _guessCellType;
final protected boolean _removeOriginalColumn; final protected boolean _removeOriginalColumn;
final protected String _mode; final protected String _mode;
final protected String _separator; final protected String _separator;
final protected boolean _regex; final protected boolean _regex;
final protected int _maxColumns; final protected int _maxColumns;
final protected int[] _fieldLengths; final protected int[] _fieldLengths;
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig"); JSONObject engineConfig = obj.getJSONObject("engineConfig");
String mode = obj.getString("mode"); String mode = obj.getString("mode");
if ("separator".equals(mode)) { if ("separator".equals(mode)) {
return new ColumnSplitOperation( return new ColumnSplitOperation(
engineConfig, engineConfig,
@ -64,7 +63,7 @@ public class ColumnSplitOperation extends EngineDependentOperation {
); );
} }
} }
public ColumnSplitOperation( public ColumnSplitOperation(
JSONObject engineConfig, JSONObject engineConfig,
String columnName, String columnName,
@ -75,19 +74,19 @@ public class ColumnSplitOperation extends EngineDependentOperation {
int maxColumns int maxColumns
) { ) {
super(engineConfig); super(engineConfig);
_columnName = columnName; _columnName = columnName;
_guessCellType = guessCellType; _guessCellType = guessCellType;
_removeOriginalColumn = removeOriginalColumn; _removeOriginalColumn = removeOriginalColumn;
_mode = "separator"; _mode = "separator";
_separator = separator; _separator = separator;
_regex = regex; _regex = regex;
_maxColumns = maxColumns; _maxColumns = maxColumns;
_fieldLengths = null; _fieldLengths = null;
} }
public ColumnSplitOperation( public ColumnSplitOperation(
JSONObject engineConfig, JSONObject engineConfig,
String columnName, String columnName,
@ -96,22 +95,22 @@ public class ColumnSplitOperation extends EngineDependentOperation {
int[] fieldLengths int[] fieldLengths
) { ) {
super(engineConfig); super(engineConfig);
_columnName = columnName; _columnName = columnName;
_guessCellType = guessCellType; _guessCellType = guessCellType;
_removeOriginalColumn = removeOriginalColumn; _removeOriginalColumn = removeOriginalColumn;
_mode = "lengths"; _mode = "lengths";
_separator = null; _separator = null;
_regex = false; _regex = false;
_maxColumns = -1; _maxColumns = -1;
_fieldLengths = fieldLengths; _fieldLengths = fieldLengths;
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -135,53 +134,53 @@ public class ColumnSplitOperation extends EngineDependentOperation {
} }
protected String getBriefDescription(Project project) { protected String getBriefDescription(Project project) {
return "Split column " + _columnName + return "Split column " + _columnName +
("separator".equals(_mode) ? " by separator" : " by field lengths"); ("separator".equals(_mode) ? " by separator" : " by field lengths");
} }
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
Engine engine = createEngine(project); Engine engine = createEngine(project);
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
if (column == null) { if (column == null) {
throw new Exception("No column named " + _columnName); throw new Exception("No column named " + _columnName);
} }
List<String> columnNames = new ArrayList<String>(); List<String> columnNames = new ArrayList<String>();
List<Integer> rowIndices = new ArrayList<Integer>(project.rows.size()); List<Integer> rowIndices = new ArrayList<Integer>(project.rows.size());
List<List<Serializable>> tuples = new ArrayList<List<Serializable>>(project.rows.size()); List<List<Serializable>> tuples = new ArrayList<List<Serializable>>(project.rows.size());
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
RowVisitor rowVisitor; RowVisitor rowVisitor;
if ("lengths".equals(_mode)) { if ("lengths".equals(_mode)) {
rowVisitor = new ColumnSplitRowVisitor(column.getCellIndex(), columnNames, rowIndices, tuples) { rowVisitor = new ColumnSplitRowVisitor(column.getCellIndex(), columnNames, rowIndices, tuples) {
protected java.util.List<Serializable> split(String s) { protected java.util.List<Serializable> split(String s) {
List<Serializable> results = new ArrayList<Serializable>(_fieldLengths.length + 1); List<Serializable> results = new ArrayList<Serializable>(_fieldLengths.length + 1);
int lastIndex = 0; int lastIndex = 0;
for (int i = 0; i < _fieldLengths.length; i++) { for (int i = 0; i < _fieldLengths.length; i++) {
int from = lastIndex; int from = lastIndex;
int length = _fieldLengths[i]; int length = _fieldLengths[i];
int to = Math.min(from + length, s.length()); int to = Math.min(from + length, s.length());
results.add(stringToValue(s.substring(from, to))); results.add(stringToValue(s.substring(from, to)));
lastIndex = to; lastIndex = to;
} }
return results; return results;
}; };
}; };
} else if (_regex) { } else if (_regex) {
Pattern pattern = Pattern.compile(_separator); Pattern pattern = Pattern.compile(_separator);
rowVisitor = new ColumnSplitRowVisitor(column.getCellIndex(), columnNames, rowIndices, tuples) { rowVisitor = new ColumnSplitRowVisitor(column.getCellIndex(), columnNames, rowIndices, tuples) {
Pattern _pattern; Pattern _pattern;
protected java.util.List<Serializable> split(String s) { protected java.util.List<Serializable> split(String s) {
return stringArrayToValueList(_pattern.split(s, _maxColumns)); return stringArrayToValueList(_pattern.split(s, _maxColumns));
}; };
public RowVisitor init(Pattern pattern) { public RowVisitor init(Pattern pattern) {
_pattern = pattern; _pattern = pattern;
return this; return this;
@ -195,13 +194,13 @@ public class ColumnSplitOperation extends EngineDependentOperation {
}; };
}; };
} }
filteredRows.accept(project, rowVisitor); filteredRows.accept(project, rowVisitor);
String description = String description =
"Split " + rowIndices.size() + "Split " + rowIndices.size() +
" cell(s) in column " + _columnName + " cell(s) in column " + _columnName +
" into several columns" + " into several columns" +
("separator".equals(_mode) ? " by separator" : " by field lengths"); ("separator".equals(_mode) ? " by separator" : " by field lengths");
Change change = new ColumnSplitChange( Change change = new ColumnSplitChange(
@ -211,8 +210,8 @@ public class ColumnSplitOperation extends EngineDependentOperation {
tuples, tuples,
_removeOriginalColumn _removeOriginalColumn
); );
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, project, description, this, change); historyEntryID, project, description, this, change);
} }
@ -222,9 +221,9 @@ public class ColumnSplitOperation extends EngineDependentOperation {
List<String> columnNames; List<String> columnNames;
List<Integer> rowIndices; List<Integer> rowIndices;
List<List<Serializable>> tuples; List<List<Serializable>> tuples;
int columnNameIndex = 1; int columnNameIndex = 1;
ColumnSplitRowVisitor( ColumnSplitRowVisitor(
int cellIndex, int cellIndex,
List<String> columnNames, List<String> columnNames,
@ -236,27 +235,27 @@ public class ColumnSplitOperation extends EngineDependentOperation {
this.rowIndices = rowIndices; this.rowIndices = rowIndices;
this.tuples = tuples; this.tuples = tuples;
} }
@Override @Override
public void start(Project project) { public void start(Project project) {
// nothing to do // nothing to do
} }
@Override @Override
public void end(Project project) { public void end(Project project) {
// nothing to do // nothing to do
} }
public boolean visit(Project project, int rowIndex, Row row) { public boolean visit(Project project, int rowIndex, Row row) {
Object value = row.getCellValue(cellIndex); Object value = row.getCellValue(cellIndex);
if (ExpressionUtils.isNonBlankData(value)) { if (ExpressionUtils.isNonBlankData(value)) {
String s = value instanceof String ? ((String) value) : value.toString(); String s = value instanceof String ? ((String) value) : value.toString();
List<Serializable> tuple = split(s); List<Serializable> tuple = split(s);
rowIndices.add(rowIndex); rowIndices.add(rowIndex);
tuples.add(tuple); tuples.add(tuple);
for (int i = columnNames.size(); i < tuple.size(); i++) { for (int i = columnNames.size(); i < tuple.size(); i++) {
while (true) { while (true) {
String newColumnName = _columnName + " " + columnNameIndex++; String newColumnName = _columnName + " " + columnNameIndex++;
@ -269,21 +268,21 @@ public class ColumnSplitOperation extends EngineDependentOperation {
} }
return false; return false;
} }
protected List<Serializable> split(String s) { protected List<Serializable> split(String s) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
protected Serializable stringToValue(String s) { protected Serializable stringToValue(String s) {
return _guessCellType ? ImporterUtilities.parseCellValue(s) : s; return _guessCellType ? ImporterUtilities.parseCellValue(s) : s;
} }
protected List<Serializable> stringArrayToValueList(String[] cells) { protected List<Serializable> stringArrayToValueList(String[] cells) {
List<Serializable> results = new ArrayList<Serializable>(cells.length); List<Serializable> results = new ArrayList<Serializable>(cells.length);
for (String cell : cells) { for (String cell : cells) {
results.add(stringToValue(cell)); results.add(stringToValue(cell));
} }
return results; return results;
} }
} }

View File

@ -13,7 +13,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.FilteredRows;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -39,10 +38,10 @@ public class ExtendDataOperation extends EngineDependentOperation {
final protected String _baseColumnName; final protected String _baseColumnName;
final protected JSONObject _extension; final protected JSONObject _extension;
final protected int _columnInsertIndex; final protected int _columnInsertIndex;
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig"); JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ExtendDataOperation( return new ExtendDataOperation(
engineConfig, engineConfig,
obj.getString("baseColumnName"), obj.getString("baseColumnName"),
@ -50,15 +49,15 @@ public class ExtendDataOperation extends EngineDependentOperation {
obj.getInt("columnInsertIndex") obj.getInt("columnInsertIndex")
); );
} }
public ExtendDataOperation( public ExtendDataOperation(
JSONObject engineConfig, JSONObject engineConfig,
String baseColumnName, String baseColumnName,
JSONObject extension, JSONObject extension,
int columnInsertIndex int columnInsertIndex
) { ) {
super(engineConfig); super(engineConfig);
_baseColumnName = baseColumnName; _baseColumnName = baseColumnName;
_extension = extension; _extension = extension;
_columnInsertIndex = columnInsertIndex; _columnInsertIndex = columnInsertIndex;
@ -66,7 +65,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -78,24 +77,24 @@ public class ExtendDataOperation extends EngineDependentOperation {
} }
protected String getBriefDescription(Project project) { protected String getBriefDescription(Project project) {
return "Extend data at index " + _columnInsertIndex + return "Extend data at index " + _columnInsertIndex +
" based on column " + _baseColumnName; " based on column " + _baseColumnName;
} }
protected String createDescription(Column column, List<CellAtRow> cellsAtRows) { protected String createDescription(Column column, List<CellAtRow> cellsAtRows) {
return "Extend data at index " + _columnInsertIndex + return "Extend data at index " + _columnInsertIndex +
" based on column " + column.getName() + " based on column " + column.getName() +
" by filling " + cellsAtRows.size(); " by filling " + cellsAtRows.size();
} }
public Process createProcess(Project project, Properties options) throws Exception { public Process createProcess(Project project, Properties options) throws Exception {
return new ExtendDataProcess( return new ExtendDataProcess(
project, project,
getEngineConfig(), getEngineConfig(),
getBriefDescription(null) getBriefDescription(null)
); );
} }
public class ExtendDataProcess extends LongRunningProcess implements Runnable { public class ExtendDataProcess extends LongRunningProcess implements Runnable {
final protected Project _project; final protected Project _project;
final protected JSONObject _engineConfig; final protected JSONObject _engineConfig;
@ -104,21 +103,21 @@ public class ExtendDataOperation extends EngineDependentOperation {
protected FreebaseDataExtensionJob _job; protected FreebaseDataExtensionJob _job;
public ExtendDataProcess( public ExtendDataProcess(
Project project, Project project,
JSONObject engineConfig, JSONObject engineConfig,
String description String description
) throws JSONException { ) throws JSONException {
super(description); super(description);
_project = project; _project = project;
_engineConfig = engineConfig; _engineConfig = engineConfig;
_historyEntryID = HistoryEntry.allocateID(); _historyEntryID = HistoryEntry.allocateID();
_job = new FreebaseDataExtensionJob(_extension); _job = new FreebaseDataExtensionJob(_extension);
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("id"); writer.value(hashCode()); writer.key("id"); writer.value(hashCode());
writer.key("description"); writer.value(_description); writer.key("description"); writer.value(_description);
@ -127,111 +126,111 @@ public class ExtendDataOperation extends EngineDependentOperation {
writer.key("progress"); writer.value(_progress); writer.key("progress"); writer.value(_progress);
writer.endObject(); writer.endObject();
} }
protected Runnable getRunnable() { protected Runnable getRunnable() {
return this; return this;
} }
protected void populateRowsWithMatches(List<Integer> rowIndices) throws Exception { protected void populateRowsWithMatches(List<Integer> rowIndices) throws Exception {
Engine engine = new Engine(_project); Engine engine = new Engine(_project);
engine.initializeFromJSON(_engineConfig); engine.initializeFromJSON(_engineConfig);
Column column = _project.columnModel.getColumnByName(_baseColumnName); Column column = _project.columnModel.getColumnByName(_baseColumnName);
if (column == null) { if (column == null) {
throw new Exception("No column named " + _baseColumnName); throw new Exception("No column named " + _baseColumnName);
} }
_cellIndex = column.getCellIndex(); _cellIndex = column.getCellIndex();
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
filteredRows.accept(_project, new RowVisitor() { filteredRows.accept(_project, new RowVisitor() {
List<Integer> _rowIndices; List<Integer> _rowIndices;
public RowVisitor init(List<Integer> rowIndices) { public RowVisitor init(List<Integer> rowIndices) {
_rowIndices = rowIndices; _rowIndices = rowIndices;
return this; return this;
} }
@Override @Override
public void start(Project project) { public void start(Project project) {
// nothing to do // nothing to do
} }
@Override @Override
public void end(Project project) { public void end(Project project) {
// nothing to do // nothing to do
} }
public boolean visit(Project project, int rowIndex, Row row) { public boolean visit(Project project, int rowIndex, Row row) {
Cell cell = row.getCell(_cellIndex); Cell cell = row.getCell(_cellIndex);
if (cell != null && cell.recon != null && cell.recon.match != null) { if (cell != null && cell.recon != null && cell.recon.match != null) {
_rowIndices.add(rowIndex); _rowIndices.add(rowIndex);
} }
return false; return false;
} }
}.init(rowIndices)); }.init(rowIndices));
} }
protected int extendRows( protected int extendRows(
List<Integer> rowIndices, List<Integer> rowIndices,
List<DataExtension> dataExtensions, List<DataExtension> dataExtensions,
int from, int from,
int limit, int limit,
Map<String, ReconCandidate> reconCandidateMap Map<String, ReconCandidate> reconCandidateMap
) { ) {
Set<String> guids = new HashSet<String>(); Set<String> guids = new HashSet<String>();
int end; int end;
for (end = from; end < limit && guids.size() < 10; end++) { for (end = from; end < limit && guids.size() < 10; end++) {
int index = rowIndices.get(end); int index = rowIndices.get(end);
Row row = _project.rows.get(index); Row row = _project.rows.get(index);
Cell cell = row.getCell(_cellIndex); Cell cell = row.getCell(_cellIndex);
guids.add(cell.recon.match.topicGUID); guids.add(cell.recon.match.topicGUID);
} }
Map<String, DataExtension> map = null; Map<String, DataExtension> map = null;
try { try {
map = _job.extend(guids, reconCandidateMap); map = _job.extend(guids, reconCandidateMap);
} catch (Exception e) { } catch (Exception e) {
map = new HashMap<String, DataExtension>(); map = new HashMap<String, DataExtension>();
} }
for (int i = from; i < end; i++) { for (int i = from; i < end; i++) {
int index = rowIndices.get(i); int index = rowIndices.get(i);
Row row = _project.rows.get(index); Row row = _project.rows.get(index);
Cell cell = row.getCell(_cellIndex); Cell cell = row.getCell(_cellIndex);
String guid = cell.recon.match.topicGUID; String guid = cell.recon.match.topicGUID;
if (map.containsKey(guid)) { if (map.containsKey(guid)) {
dataExtensions.add(map.get(guid)); dataExtensions.add(map.get(guid));
} else { } else {
dataExtensions.add(null); dataExtensions.add(null);
} }
} }
return end; return end;
} }
public void run() { public void run() {
List<Integer> rowIndices = new ArrayList<Integer>(); List<Integer> rowIndices = new ArrayList<Integer>();
List<DataExtension> dataExtensions = new ArrayList<DataExtension>(); List<DataExtension> dataExtensions = new ArrayList<DataExtension>();
try { try {
populateRowsWithMatches(rowIndices); populateRowsWithMatches(rowIndices);
} catch (Exception e2) { } catch (Exception e2) {
// TODO : Not sure what to do here? // TODO : Not sure what to do here?
e2.printStackTrace(); e2.printStackTrace();
} }
int start = 0; int start = 0;
Map<String, ReconCandidate> reconCandidateMap = new HashMap<String, ReconCandidate>(); Map<String, ReconCandidate> reconCandidateMap = new HashMap<String, ReconCandidate>();
while (start < rowIndices.size()) { while (start < rowIndices.size()) {
int end = extendRows(rowIndices, dataExtensions, start, rowIndices.size(), reconCandidateMap); int end = extendRows(rowIndices, dataExtensions, start, rowIndices.size(), reconCandidateMap);
start = end; start = end;
_progress = end * 100 / rowIndices.size(); _progress = end * 100 / rowIndices.size();
try { try {
Thread.sleep(200); Thread.sleep(200);
@ -241,23 +240,23 @@ public class ExtendDataOperation extends EngineDependentOperation {
} }
} }
} }
if (!_canceled) { if (!_canceled) {
List<String> columnNames = new ArrayList<String>(); List<String> columnNames = new ArrayList<String>();
for (ColumnInfo info : _job.columns) { for (ColumnInfo info : _job.columns) {
columnNames.add(StringUtils.join(info.names, " - ")); columnNames.add(StringUtils.join(info.names, " - "));
} }
List<FreebaseType> columnTypes = new ArrayList<FreebaseType>(); List<FreebaseType> columnTypes = new ArrayList<FreebaseType>();
for (ColumnInfo info : _job.columns) { for (ColumnInfo info : _job.columns) {
columnTypes.add(info.expectedType); columnTypes.add(info.expectedType);
} }
HistoryEntry historyEntry = ProjectManager.singleton.createHistoryEntry( HistoryEntry historyEntry = new HistoryEntry(
_historyEntryID, _historyEntryID,
_project, _project,
_description, _description,
ExtendDataOperation.this, ExtendDataOperation.this,
new DataExtensionChange( new DataExtensionChange(
_baseColumnName, _baseColumnName,
_columnInsertIndex, _columnInsertIndex,
@ -267,7 +266,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
dataExtensions, dataExtensions,
_historyEntryID) _historyEntryID)
); );
_project.history.addEntry(historyEntry); _project.history.addEntry(historyEntry);
_project.processManager.onDoneProcess(this); _project.processManager.onDoneProcess(this);
} }

View File

@ -10,7 +10,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.FilteredRows;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -36,20 +35,20 @@ import com.metaweb.gridworks.process.Process;
public class ReconOperation extends EngineDependentOperation { public class ReconOperation extends EngineDependentOperation {
final protected String _columnName; final protected String _columnName;
final protected ReconConfig _reconConfig; final protected ReconConfig _reconConfig;
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig"); JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ReconOperation( return new ReconOperation(
engineConfig, engineConfig,
obj.getString("columnName"), obj.getString("columnName"),
ReconConfig.reconstruct(obj.getJSONObject("config")) ReconConfig.reconstruct(obj.getJSONObject("config"))
); );
} }
public ReconOperation( public ReconOperation(
JSONObject engineConfig, JSONObject engineConfig,
String columnName, String columnName,
ReconConfig reconConfig ReconConfig reconConfig
) { ) {
super(engineConfig); super(engineConfig);
@ -59,19 +58,19 @@ public class ReconOperation extends EngineDependentOperation {
public Process createProcess(Project project, Properties options) throws Exception { public Process createProcess(Project project, Properties options) throws Exception {
return new ReconProcess( return new ReconProcess(
project, project,
getEngineConfig(), getEngineConfig(),
getBriefDescription(null) getBriefDescription(null)
); );
} }
protected String getBriefDescription(Project project) { protected String getBriefDescription(Project project) {
return _reconConfig.getBriefDescription(project, _columnName); return _reconConfig.getBriefDescription(project, _columnName);
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -84,7 +83,7 @@ public class ReconOperation extends EngineDependentOperation {
static protected class ReconEntry { static protected class ReconEntry {
final public int rowIndex; final public int rowIndex;
final public Cell cell; final public Cell cell;
public ReconEntry(int rowIndex, Cell cell) { public ReconEntry(int rowIndex, Cell cell) {
this.rowIndex = rowIndex; this.rowIndex = rowIndex;
this.cell = cell; this.cell = cell;
@ -93,22 +92,22 @@ public class ReconOperation extends EngineDependentOperation {
static protected class JobGroup { static protected class JobGroup {
final public ReconJob job; final public ReconJob job;
final public List<ReconEntry> entries = new ArrayList<ReconEntry>(); final public List<ReconEntry> entries = new ArrayList<ReconEntry>();
public JobGroup(ReconJob job) { public JobGroup(ReconJob job) {
this.job = job; this.job = job;
} }
} }
public class ReconProcess extends LongRunningProcess implements Runnable { public class ReconProcess extends LongRunningProcess implements Runnable {
final protected Project _project; final protected Project _project;
final protected JSONObject _engineConfig; final protected JSONObject _engineConfig;
final protected long _historyEntryID; final protected long _historyEntryID;
protected List<ReconEntry> _entries; protected List<ReconEntry> _entries;
protected int _cellIndex; protected int _cellIndex;
public ReconProcess( public ReconProcess(
Project project, Project project,
JSONObject engineConfig, JSONObject engineConfig,
String description String description
) { ) {
super(description); super(description);
@ -116,10 +115,10 @@ public class ReconOperation extends EngineDependentOperation {
_engineConfig = engineConfig; _engineConfig = engineConfig;
_historyEntryID = HistoryEntry.allocateID(); _historyEntryID = HistoryEntry.allocateID();
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("id"); writer.value(hashCode()); writer.key("id"); writer.value(hashCode());
writer.key("description"); writer.value(_description); writer.key("description"); writer.value(_description);
@ -160,35 +159,35 @@ public class ReconOperation extends EngineDependentOperation {
writer.endArray(); writer.endArray();
writer.endObject(); writer.endObject();
} }
protected Runnable getRunnable() { protected Runnable getRunnable() {
return this; return this;
} }
protected void populateEntries() throws Exception { protected void populateEntries() throws Exception {
Engine engine = new Engine(_project); Engine engine = new Engine(_project);
engine.initializeFromJSON(_engineConfig); engine.initializeFromJSON(_engineConfig);
Column column = _project.columnModel.getColumnByName(_columnName); Column column = _project.columnModel.getColumnByName(_columnName);
if (column == null) { if (column == null) {
throw new Exception("No column named " + _columnName); throw new Exception("No column named " + _columnName);
} }
_entries = new ArrayList<ReconEntry>(_project.rows.size()); _entries = new ArrayList<ReconEntry>(_project.rows.size());
_cellIndex = column.getCellIndex(); _cellIndex = column.getCellIndex();
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
filteredRows.accept(_project, new RowVisitor() { filteredRows.accept(_project, new RowVisitor() {
@Override @Override
public void start(Project project) { public void start(Project project) {
// nothing to do // nothing to do
} }
@Override @Override
public void end(Project project) { public void end(Project project) {
// nothing to do // nothing to do
} }
public boolean visit(Project project, int rowIndex, Row row) { public boolean visit(Project project, int rowIndex, Row row) {
if (_cellIndex < row.cells.size()) { if (_cellIndex < row.cells.size()) {
Cell cell = row.cells.get(_cellIndex); Cell cell = row.cells.get(_cellIndex);
@ -200,7 +199,7 @@ public class ReconOperation extends EngineDependentOperation {
} }
}); });
} }
public void run() { public void run() {
try { try {
populateEntries(); populateEntries();
@ -208,18 +207,18 @@ public class ReconOperation extends EngineDependentOperation {
// TODO : Not sure what to do here? // TODO : Not sure what to do here?
e2.printStackTrace(); e2.printStackTrace();
} }
Map<Integer, JobGroup> jobKeyToGroup = new HashMap<Integer, JobGroup>(); Map<Integer, JobGroup> jobKeyToGroup = new HashMap<Integer, JobGroup>();
for (ReconEntry entry : _entries) { for (ReconEntry entry : _entries) {
ReconJob job = _reconConfig.createJob( ReconJob job = _reconConfig.createJob(
_project, _project,
entry.rowIndex, entry.rowIndex,
_project.rows.get(entry.rowIndex), _project.rows.get(entry.rowIndex),
_columnName, _columnName,
entry.cell entry.cell
); );
int key = job.getKey(); int key = job.getKey();
JobGroup group = jobKeyToGroup.get(key); JobGroup group = jobKeyToGroup.get(key);
if (group == null) { if (group == null) {
@ -228,42 +227,42 @@ public class ReconOperation extends EngineDependentOperation {
} }
group.entries.add(entry); group.entries.add(entry);
} }
List<CellChange> cellChanges = new ArrayList<CellChange>(_entries.size()); List<CellChange> cellChanges = new ArrayList<CellChange>(_entries.size());
List<JobGroup> groups = new ArrayList<JobGroup>(jobKeyToGroup.values()); List<JobGroup> groups = new ArrayList<JobGroup>(jobKeyToGroup.values());
int batchSize = _reconConfig.getBatchSize(); int batchSize = _reconConfig.getBatchSize();
for (int i = 0; i < groups.size(); i += batchSize) { for (int i = 0; i < groups.size(); i += batchSize) {
int to = Math.min(i + batchSize, groups.size()); int to = Math.min(i + batchSize, groups.size());
List<ReconJob> jobs = new ArrayList<ReconJob>(to - i); List<ReconJob> jobs = new ArrayList<ReconJob>(to - i);
for (int j = i; j < to; j++) { for (int j = i; j < to; j++) {
jobs.add(groups.get(j).job); jobs.add(groups.get(j).job);
} }
List<Recon> recons = _reconConfig.batchRecon(jobs, _historyEntryID); List<Recon> recons = _reconConfig.batchRecon(jobs, _historyEntryID);
for (int j = i; j < to; j++) { for (int j = i; j < to; j++) {
Recon recon = recons.get(j - i); Recon recon = recons.get(j - i);
List<ReconEntry> entries = groups.get(j).entries; List<ReconEntry> entries = groups.get(j).entries;
if (recon != null) { if (recon != null) {
recon.judgmentBatchSize = entries.size(); recon.judgmentBatchSize = entries.size();
} }
for (ReconEntry entry : entries) { for (ReconEntry entry : entries) {
Cell oldCell = entry.cell; Cell oldCell = entry.cell;
Cell newCell = new Cell(oldCell.value, recon); Cell newCell = new Cell(oldCell.value, recon);
CellChange cellChange = new CellChange( CellChange cellChange = new CellChange(
entry.rowIndex, entry.rowIndex,
_cellIndex, _cellIndex,
oldCell, oldCell,
newCell newCell
); );
cellChanges.add(cellChange); cellChanges.add(cellChange);
} }
} }
_progress = i * 100 / groups.size(); _progress = i * 100 / groups.size();
try { try {
Thread.sleep(50); Thread.sleep(50);
@ -273,23 +272,23 @@ public class ReconOperation extends EngineDependentOperation {
} }
} }
} }
if (!_canceled) { if (!_canceled) {
Change reconChange = new ReconChange( Change reconChange = new ReconChange(
cellChanges, cellChanges,
_columnName, _columnName,
_reconConfig, _reconConfig,
null null
); );
HistoryEntry historyEntry = ProjectManager.singleton.createHistoryEntry( HistoryEntry historyEntry = new HistoryEntry(
_historyEntryID, _historyEntryID,
_project, _project,
_description, _description,
ReconOperation.this, ReconOperation.this,
reconChange reconChange
); );
_project.history.addEntry(historyEntry); _project.history.addEntry(historyEntry);
_project.processManager.onDoneProcess(this); _project.processManager.onDoneProcess(this);
} }

View File

@ -8,7 +8,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation; import com.metaweb.gridworks.model.AbstractOperation;
import com.metaweb.gridworks.model.Cell; import com.metaweb.gridworks.model.Cell;
@ -23,13 +22,13 @@ public class DenormalizeOperation extends AbstractOperation {
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
return new DenormalizeOperation(); return new DenormalizeOperation();
} }
public DenormalizeOperation() { public DenormalizeOperation() {
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value("Denormalize"); writer.key("description"); writer.value("Denormalize");
@ -43,37 +42,37 @@ public class DenormalizeOperation extends AbstractOperation {
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
List<Row> newRows = new ArrayList<Row>(); List<Row> newRows = new ArrayList<Row>();
List<Row> oldRows = project.rows; List<Row> oldRows = project.rows;
for (int r = 0; r < oldRows.size(); r++) { for (int r = 0; r < oldRows.size(); r++) {
Row oldRow = oldRows.get(r); Row oldRow = oldRows.get(r);
Row newRow = null; Row newRow = null;
RowDependency rd = project.recordModel.getRowDependency(r); RowDependency rd = project.recordModel.getRowDependency(r);
if (rd.cellDependencies != null) { if (rd.cellDependencies != null) {
newRow = oldRow.dup(); newRow = oldRow.dup();
for (int c = 0; c < rd.cellDependencies.length; c++) { for (int c = 0; c < rd.cellDependencies.length; c++) {
CellDependency cd = rd.cellDependencies[c]; CellDependency cd = rd.cellDependencies[c];
if (cd != null) { if (cd != null) {
int contextRowIndex = cd.rowIndex; int contextRowIndex = cd.rowIndex;
int contextCellIndex = cd.cellIndex; int contextCellIndex = cd.cellIndex;
if (contextRowIndex >= 0 && contextRowIndex < oldRows.size()) { if (contextRowIndex >= 0 && contextRowIndex < oldRows.size()) {
Row contextRow = oldRows.get(contextRowIndex); Row contextRow = oldRows.get(contextRowIndex);
Cell contextCell = contextRow.getCell(contextCellIndex); Cell contextCell = contextRow.getCell(contextCellIndex);
newRow.setCell(contextCellIndex, contextCell); newRow.setCell(contextCellIndex, contextCell);
} }
} }
} }
} }
newRows.add(newRow != null ? newRow : oldRow); newRows.add(newRow != null ? newRow : oldRow);
} }
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
project, project,
getBriefDescription(project), getBriefDescription(project),
DenormalizeOperation.this, DenormalizeOperation.this,

View File

@ -8,7 +8,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.FilteredRows;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -28,13 +27,13 @@ public class RowFlagOperation extends EngineDependentOperation {
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig"); JSONObject engineConfig = obj.getJSONObject("engineConfig");
boolean flagged = obj.getBoolean("flagged"); boolean flagged = obj.getBoolean("flagged");
return new RowFlagOperation( return new RowFlagOperation(
engineConfig, engineConfig,
flagged flagged
); );
} }
public RowFlagOperation(JSONObject engineConfig, boolean flagged) { public RowFlagOperation(JSONObject engineConfig, boolean flagged) {
super(engineConfig); super(engineConfig);
_flagged = flagged; _flagged = flagged;
@ -42,7 +41,7 @@ public class RowFlagOperation extends EngineDependentOperation {
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -57,17 +56,17 @@ public class RowFlagOperation extends EngineDependentOperation {
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
Engine engine = createEngine(project); Engine engine = createEngine(project);
List<Change> changes = new ArrayList<Change>(project.rows.size()); List<Change> changes = new ArrayList<Change>(project.rows.size());
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
filteredRows.accept(project, createRowVisitor(project, changes)); filteredRows.accept(project, createRowVisitor(project, changes));
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
project, project,
(_flagged ? "Flag" : "Unflag") + " " + changes.size() + " rows", (_flagged ? "Flag" : "Unflag") + " " + changes.size() + " rows",
this, this,
new MassChange(changes, false) new MassChange(changes, false)
); );
} }
@ -75,26 +74,26 @@ public class RowFlagOperation extends EngineDependentOperation {
protected RowVisitor createRowVisitor(Project project, List<Change> changes) throws Exception { protected RowVisitor createRowVisitor(Project project, List<Change> changes) throws Exception {
return new RowVisitor() { return new RowVisitor() {
List<Change> changes; List<Change> changes;
public RowVisitor init(List<Change> changes) { public RowVisitor init(List<Change> changes) {
this.changes = changes; this.changes = changes;
return this; return this;
} }
@Override @Override
public void start(Project project) { public void start(Project project) {
// nothing to do // nothing to do
} }
@Override @Override
public void end(Project project) { public void end(Project project) {
// nothing to do // nothing to do
} }
public boolean visit(Project project, int rowIndex, Row row) { public boolean visit(Project project, int rowIndex, Row row) {
if (row.flagged != _flagged) { if (row.flagged != _flagged) {
RowFlagChange change = new RowFlagChange(rowIndex, _flagged); RowFlagChange change = new RowFlagChange(rowIndex, _flagged);
changes.add(change); changes.add(change);
} }
return false; return false;

View File

@ -8,7 +8,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.FilteredRows;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -23,19 +22,19 @@ import com.metaweb.gridworks.operations.OperationRegistry;
public class RowRemovalOperation extends EngineDependentOperation { public class RowRemovalOperation extends EngineDependentOperation {
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig"); JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new RowRemovalOperation( return new RowRemovalOperation(
engineConfig engineConfig
); );
} }
public RowRemovalOperation(JSONObject engineConfig) { public RowRemovalOperation(JSONObject engineConfig) {
super(engineConfig); super(engineConfig);
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -49,17 +48,17 @@ public class RowRemovalOperation extends EngineDependentOperation {
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
Engine engine = createEngine(project); Engine engine = createEngine(project);
List<Integer> rowIndices = new ArrayList<Integer>(); List<Integer> rowIndices = new ArrayList<Integer>();
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
filteredRows.accept(project, createRowVisitor(project, rowIndices)); filteredRows.accept(project, createRowVisitor(project, rowIndices));
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
project, project,
"Remove " + rowIndices.size() + " rows", "Remove " + rowIndices.size() + " rows",
this, this,
new RowRemovalChange(rowIndices) new RowRemovalChange(rowIndices)
); );
} }
@ -67,25 +66,25 @@ public class RowRemovalOperation extends EngineDependentOperation {
protected RowVisitor createRowVisitor(Project project, List<Integer> rowIndices) throws Exception { protected RowVisitor createRowVisitor(Project project, List<Integer> rowIndices) throws Exception {
return new RowVisitor() { return new RowVisitor() {
List<Integer> rowIndices; List<Integer> rowIndices;
public RowVisitor init(List<Integer> rowIndices) { public RowVisitor init(List<Integer> rowIndices) {
this.rowIndices = rowIndices; this.rowIndices = rowIndices;
return this; return this;
} }
@Override @Override
public void start(Project project) { public void start(Project project) {
// nothing to do // nothing to do
} }
@Override @Override
public void end(Project project) { public void end(Project project) {
// nothing to do // nothing to do
} }
public boolean visit(Project project, int rowIndex, Row row) { public boolean visit(Project project, int rowIndex, Row row) {
rowIndices.add(rowIndex); rowIndices.add(rowIndex);
return false; return false;
} }
}.init(rowIndices); }.init(rowIndices);

View File

@ -8,7 +8,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.RecordVisitor; import com.metaweb.gridworks.browsing.RecordVisitor;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -28,13 +27,13 @@ public class RowReorderOperation extends AbstractOperation {
String mode = obj.getString("mode"); String mode = obj.getString("mode");
JSONObject sorting = obj.has("sorting") && !obj.isNull("sorting") ? JSONObject sorting = obj.has("sorting") && !obj.isNull("sorting") ?
obj.getJSONObject("sorting") : null; obj.getJSONObject("sorting") : null;
return new RowReorderOperation(Engine.stringToMode(mode), sorting); return new RowReorderOperation(Engine.stringToMode(mode), sorting);
} }
final protected Mode _mode; final protected Mode _mode;
final protected JSONObject _sorting; final protected JSONObject _sorting;
public RowReorderOperation(Mode mode, JSONObject sorting) { public RowReorderOperation(Mode mode, JSONObject sorting) {
_mode = mode; _mode = mode;
_sorting = sorting; _sorting = sorting;
@ -42,7 +41,7 @@ public class RowReorderOperation extends AbstractOperation {
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -58,50 +57,50 @@ public class RowReorderOperation extends AbstractOperation {
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
Engine engine = new Engine(project); Engine engine = new Engine(project);
engine.setMode(_mode); engine.setMode(_mode);
List<Integer> rowIndices = new ArrayList<Integer>(); List<Integer> rowIndices = new ArrayList<Integer>();
if (_mode == Mode.RowBased) { if (_mode == Mode.RowBased) {
RowVisitor visitor = new IndexingVisitor(rowIndices); RowVisitor visitor = new IndexingVisitor(rowIndices);
if (_sorting != null) { if (_sorting != null) {
SortingRowVisitor srv = new SortingRowVisitor(visitor); SortingRowVisitor srv = new SortingRowVisitor(visitor);
srv.initializeFromJSON(project, _sorting); srv.initializeFromJSON(project, _sorting);
if (srv.hasCriteria()) { if (srv.hasCriteria()) {
visitor = srv; visitor = srv;
} }
} }
engine.getAllRows().accept(project, visitor); engine.getAllRows().accept(project, visitor);
} else { } else {
RecordVisitor visitor = new IndexingVisitor(rowIndices); RecordVisitor visitor = new IndexingVisitor(rowIndices);
if (_sorting != null) { if (_sorting != null) {
SortingRecordVisitor srv = new SortingRecordVisitor(visitor); SortingRecordVisitor srv = new SortingRecordVisitor(visitor);
srv.initializeFromJSON(project, _sorting); srv.initializeFromJSON(project, _sorting);
if (srv.hasCriteria()) { if (srv.hasCriteria()) {
visitor = srv; visitor = srv;
} }
} }
engine.getAllRecords().accept(project, visitor); engine.getAllRecords().accept(project, visitor);
} }
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
project, project,
"Reorder rows", "Reorder rows",
this, this,
new RowReorderChange(rowIndices) new RowReorderChange(rowIndices)
); );
} }
static protected class IndexingVisitor implements RowVisitor, RecordVisitor { static protected class IndexingVisitor implements RowVisitor, RecordVisitor {
List<Integer> _indices; List<Integer> _indices;
IndexingVisitor(List<Integer> indices) { IndexingVisitor(List<Integer> indices) {
_indices = indices; _indices = indices;
} }
@Override @Override
public void start(Project project) { public void start(Project project) {
} }

View File

@ -8,7 +8,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter; import org.json.JSONWriter;
import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.FilteredRows;
import com.metaweb.gridworks.browsing.RowVisitor; import com.metaweb.gridworks.browsing.RowVisitor;
@ -28,13 +27,13 @@ public class RowStarOperation extends EngineDependentOperation {
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception { static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig"); JSONObject engineConfig = obj.getJSONObject("engineConfig");
boolean starred = obj.getBoolean("starred"); boolean starred = obj.getBoolean("starred");
return new RowStarOperation( return new RowStarOperation(
engineConfig, engineConfig,
starred starred
); );
} }
public RowStarOperation(JSONObject engineConfig, boolean starred) { public RowStarOperation(JSONObject engineConfig, boolean starred) {
super(engineConfig); super(engineConfig);
_starred = starred; _starred = starred;
@ -42,7 +41,7 @@ public class RowStarOperation extends EngineDependentOperation {
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass())); writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null)); writer.key("description"); writer.value(getBriefDescription(null));
@ -57,17 +56,17 @@ public class RowStarOperation extends EngineDependentOperation {
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
Engine engine = createEngine(project); Engine engine = createEngine(project);
List<Change> changes = new ArrayList<Change>(project.rows.size()); List<Change> changes = new ArrayList<Change>(project.rows.size());
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
filteredRows.accept(project, createRowVisitor(project, changes)); filteredRows.accept(project, createRowVisitor(project, changes));
return ProjectManager.singleton.createHistoryEntry( return new HistoryEntry(
historyEntryID, historyEntryID,
project, project,
(_starred ? "Star" : "Unstar") + " " + changes.size() + " rows", (_starred ? "Star" : "Unstar") + " " + changes.size() + " rows",
this, this,
new MassChange(changes, false) new MassChange(changes, false)
); );
} }
@ -75,26 +74,26 @@ public class RowStarOperation extends EngineDependentOperation {
protected RowVisitor createRowVisitor(Project project, List<Change> changes) throws Exception { protected RowVisitor createRowVisitor(Project project, List<Change> changes) throws Exception {
return new RowVisitor() { return new RowVisitor() {
List<Change> changes; List<Change> changes;
public RowVisitor init(List<Change> changes) { public RowVisitor init(List<Change> changes) {
this.changes = changes; this.changes = changes;
return this; return this;
} }
@Override @Override
public void start(Project project) { public void start(Project project) {
// nothing to do // nothing to do
} }
@Override @Override
public void end(Project project) { public void end(Project project) {
// nothing to do // nothing to do
} }
public boolean visit(Project project, int rowIndex, Row row) { public boolean visit(Project project, int rowIndex, Row row) {
if (row.starred != _starred) { if (row.starred != _starred) {
RowStarChange change = new RowStarChange(rowIndex, _starred); RowStarChange change = new RowStarChange(rowIndex, _starred);
changes.add(change); changes.add(change);
} }
return false; return false;