Got history entries' IDs into Recon objects so we can track from a Recon object to all others created by the same operation.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@562 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-04-28 17:18:44 +00:00
parent 4f1aaff486
commit 89e1d8b5ac
35 changed files with 187 additions and 143 deletions

View File

@ -81,8 +81,9 @@ public class AnnotateOneRowCommand extends Command {
this.starred = starred; this.starred = starred;
} }
protected HistoryEntry createHistoryEntry() throws Exception { protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception {
return new HistoryEntry( return new HistoryEntry(
historyEntryID,
_project, _project,
(starred ? "Star row " : "Unstar row ") + (rowIndex + 1), (starred ? "Star row " : "Unstar row ") + (rowIndex + 1),
null, null,
@ -106,8 +107,9 @@ public class AnnotateOneRowCommand extends Command {
this.flagged = flagged; this.flagged = flagged;
} }
protected HistoryEntry createHistoryEntry() throws Exception { protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception {
return new HistoryEntry( return new HistoryEntry(
historyEntryID,
_project, _project,
(flagged ? "Flag row " : "Unflag row ") + (rowIndex + 1), (flagged ? "Flag row " : "Unflag row ") + (rowIndex + 1),
null, null,

View File

@ -100,7 +100,7 @@ public class EditOneCellCommand extends Command {
this.value = value; this.value = value;
} }
protected HistoryEntry createHistoryEntry() throws Exception { protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception {
Cell cell = _project.rows.get(rowIndex).getCell(cellIndex); Cell cell = _project.rows.get(rowIndex).getCell(cellIndex);
Column column = _project.columnModel.getColumnByCellIndex(cellIndex); Column column = _project.columnModel.getColumnByCellIndex(cellIndex);
if (column == null) { if (column == null) {
@ -119,7 +119,7 @@ public class EditOneCellCommand extends Command {
Change change = new CellChange(rowIndex, cellIndex, cell, newCell); Change change = new CellChange(rowIndex, cellIndex, cell, newCell);
return new HistoryEntry( return new HistoryEntry(
_project, description, null, change); historyEntryID, _project, description, null, change);
} }
} }
} }

View File

@ -110,7 +110,7 @@ public class ReconJudgeOneCellCommand extends Command {
this.match = match; this.match = match;
} }
protected HistoryEntry createHistoryEntry() throws Exception { protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception {
Cell cell = _project.rows.get(rowIndex).getCell(cellIndex); Cell cell = _project.rows.get(rowIndex).getCell(cellIndex);
if (cell == null || !ExpressionUtils.isNonBlankData(cell.value)) { if (cell == null || !ExpressionUtils.isNonBlankData(cell.value)) {
throw new Exception("Cell is blank or error"); throw new Exception("Cell is blank or error");
@ -125,7 +125,7 @@ public class ReconJudgeOneCellCommand extends Command {
newCell = new Cell( newCell = new Cell(
cell.value, cell.value,
cell.recon == null ? new Recon() : cell.recon.dup() cell.recon == null ? new Recon(historyEntryID) : cell.recon.dup(historyEntryID)
); );
String cellDescription = String cellDescription =
@ -199,7 +199,7 @@ public class ReconJudgeOneCellCommand extends Command {
); );
return new HistoryEntry( return new HistoryEntry(
_project, description, null, change); historyEntryID, _project, description, null, change);
} }
} }
} }

View File

@ -40,8 +40,12 @@ public class HistoryEntry implements Jsonizable {
private final static String OPERATION = "operation"; private final static String OPERATION = "operation";
public HistoryEntry(Project project, String description, AbstractOperation operation, Change change) { static public long allocateID() {
this.id = Math.round(Math.random() * 1000000) + System.currentTimeMillis(); return Math.round(Math.random() * 1000000) + System.currentTimeMillis();
}
public HistoryEntry(long id, Project project, String description, AbstractOperation operation, Change change) {
this.id = id;
this.projectID = project.id; this.projectID = project.id;
this.description = description; this.description = description;
this.operation = operation; this.operation = operation;

View File

@ -212,7 +212,7 @@ public class ExcelImporter implements Importer {
recon = reconMap.get(id); recon = reconMap.get(id);
recon.judgmentBatchSize++; recon.judgmentBatchSize++;
} else { } else {
recon = new Recon(); recon = new Recon(0);
recon.service = "import"; recon.service = "import";
recon.match = new ReconCandidate(id, "", value.toString(), new String[0], 100); recon.match = new ReconCandidate(id, "", value.toString(), new String[0], 100);
recon.matchRank = 0; recon.matchRank = 0;

View File

@ -17,13 +17,13 @@ abstract public class AbstractOperation implements Jsonizable {
public Process createProcess(Project project, Properties options) throws Exception { public Process createProcess(Project project, Properties options) throws Exception {
return new QuickHistoryEntryProcess(project, getBriefDescription(null)) { return new QuickHistoryEntryProcess(project, getBriefDescription(null)) {
@Override @Override
protected HistoryEntry createHistoryEntry() throws Exception { protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception {
return AbstractOperation.this.createHistoryEntry(_project); return AbstractOperation.this.createHistoryEntry(_project, historyEntryID);
} }
}; };
} }
protected HistoryEntry createHistoryEntry(Project project) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -65,22 +65,24 @@ public class Recon implements HasFields, Jsonizable {
public Judgment judgment = Judgment.None; public Judgment judgment = Judgment.None;
public String judgmentAction = "unknown"; public String judgmentAction = "unknown";
public long judgmentHistoryEntry = -1; public long judgmentHistoryEntry;
public int judgmentBatchSize = 0; public int judgmentBatchSize = 0;
public ReconCandidate match = null; public ReconCandidate match = null;
public int matchRank = -1; public int matchRank = -1;
public Recon() { public Recon(long judgmentHistoryEntry) {
id = System.currentTimeMillis() * 1000000 + Math.round(Math.random() * 1000000); id = System.currentTimeMillis() * 1000000 + Math.round(Math.random() * 1000000);
this.judgmentHistoryEntry = judgmentHistoryEntry;
} }
protected Recon(long id) { protected Recon(long id, long judgmentHistoryEntry) {
this.id = id; this.id = id;
this.judgmentHistoryEntry = judgmentHistoryEntry;
} }
public Recon dup() { public Recon dup(long judgmentHistoryEntry) {
Recon r = new Recon(); Recon r = new Recon(judgmentHistoryEntry);
System.arraycopy(features, 0, r.features, 0, features.length); System.arraycopy(features, 0, r.features, 0, features.length);
@ -93,7 +95,6 @@ public class Recon implements HasFields, Jsonizable {
r.judgment = judgment; r.judgment = judgment;
r.judgmentAction = judgmentAction; r.judgmentAction = judgmentAction;
r.judgmentHistoryEntry = judgmentHistoryEntry;
r.judgmentBatchSize = judgmentBatchSize; r.judgmentBatchSize = judgmentBatchSize;
r.match = match; r.match = match;
@ -146,6 +147,8 @@ public class Recon implements HasFields, Jsonizable {
return judgmentToString(); return judgmentToString();
} else if ("judgmentAction".equals(name) || "judgementAction".equals(name)) { } else if ("judgmentAction".equals(name) || "judgementAction".equals(name)) {
return judgmentAction; return judgmentAction;
} else if ("judgmentHistoryEntry".equals(name) || "judgementHistoryEntry".equals(name)) {
return judgmentHistoryEntry;
} else if ("judgmentBatchSize".equals(name) || "judgementBatchSize".equals(name)) { } else if ("judgmentBatchSize".equals(name) || "judgementBatchSize".equals(name)) {
return judgmentBatchSize; return judgmentBatchSize;
} else if ("matched".equals(name)) { } else if ("matched".equals(name)) {
@ -188,8 +191,11 @@ public class Recon implements HasFields, Jsonizable {
writer.object(); writer.object();
writer.key("id"); writer.value(id); writer.key("id"); writer.value(id);
writer.key("j"); writer.value(judgmentToString()); if (saveMode) {
writer.key("judgmentHistoryEntry"); writer.value(judgmentHistoryEntry);
}
writer.key("j"); writer.value(judgmentToString());
if (match != null) { if (match != null) {
writer.key("m"); writer.key("m");
writer.value(match.topicID); writer.value(match.topicID);
@ -214,7 +220,6 @@ public class Recon implements HasFields, Jsonizable {
writer.key("service"); writer.value(service); writer.key("service"); writer.value(service);
writer.key("judgmentAction"); writer.value(judgmentAction); writer.key("judgmentAction"); writer.value(judgmentAction);
writer.key("judgmentHistoryEntry"); writer.value(judgmentHistoryEntry);
writer.key("judgmentBatchSize"); writer.value(judgmentBatchSize); writer.key("judgmentBatchSize"); writer.value(judgmentBatchSize);
if (match != null) { if (match != null) {
@ -242,72 +247,79 @@ public class Recon implements HasFields, Jsonizable {
} }
Recon recon = null; Recon recon = null;
long id = -1;
long judgmentHistoryEntry = -1;
while (jp.nextToken() != JsonToken.END_OBJECT) { while (jp.nextToken() != JsonToken.END_OBJECT) {
String fieldName = jp.getCurrentName(); String fieldName = jp.getCurrentName();
jp.nextToken(); jp.nextToken();
if ("id".equals(fieldName)) { if ("id".equals(fieldName)) {
long id = jp.getLongValue(); id = jp.getLongValue();
recon = new Recon(id); } else if ("judgmentHistoryEntry".equals(fieldName)) {
} else if ("j".equals(fieldName)) { judgmentHistoryEntry = jp.getLongValue();
recon.judgment = stringToJudgment(jp.getText()); } else {
} else if ("m".equals(fieldName)) { if (recon == null) {
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { recon = new Recon(id, judgmentHistoryEntry);
String candidateID = jp.getText();
recon.match = pool.getReconCandidate(candidateID);
} else {
// legacy
recon.match = ReconCandidate.loadStreaming(jp);
}
} else if ("f".equals(fieldName)) {
if (jp.getCurrentToken() != JsonToken.START_ARRAY) {
return null;
} }
int feature = 0; if ("j".equals(fieldName)) {
while (jp.nextToken() != JsonToken.END_ARRAY) { recon.judgment = stringToJudgment(jp.getText());
if (feature < recon.features.length) { } else if ("m".equals(fieldName)) {
JsonToken token = jp.getCurrentToken();
if (token == JsonToken.VALUE_STRING) {
recon.features[feature++] = jp.getText();
} else if (token == JsonToken.VALUE_NUMBER_INT) {
recon.features[feature++] = jp.getLongValue();
} else if (token == JsonToken.VALUE_NUMBER_FLOAT) {
recon.features[feature++] = jp.getDoubleValue();
} else if (token == JsonToken.VALUE_FALSE) {
recon.features[feature++] = false;
} else if (token == JsonToken.VALUE_TRUE) {
recon.features[feature++] = true;
}
}
}
} else if ("c".equals(fieldName)) {
if (jp.getCurrentToken() != JsonToken.START_ARRAY) {
return null;
}
while (jp.nextToken() != JsonToken.END_ARRAY) {
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
String candidateID = jp.getText(); String candidateID = jp.getText();
recon.addCandidate(pool.getReconCandidate(candidateID)); recon.match = pool.getReconCandidate(candidateID);
} else { } else {
// legacy // legacy
recon.addCandidate(ReconCandidate.loadStreaming(jp)); recon.match = ReconCandidate.loadStreaming(jp);
} }
} else if ("f".equals(fieldName)) {
if (jp.getCurrentToken() != JsonToken.START_ARRAY) {
return null;
}
int feature = 0;
while (jp.nextToken() != JsonToken.END_ARRAY) {
if (feature < recon.features.length) {
JsonToken token = jp.getCurrentToken();
if (token == JsonToken.VALUE_STRING) {
recon.features[feature++] = jp.getText();
} else if (token == JsonToken.VALUE_NUMBER_INT) {
recon.features[feature++] = jp.getLongValue();
} else if (token == JsonToken.VALUE_NUMBER_FLOAT) {
recon.features[feature++] = jp.getDoubleValue();
} else if (token == JsonToken.VALUE_FALSE) {
recon.features[feature++] = false;
} else if (token == JsonToken.VALUE_TRUE) {
recon.features[feature++] = true;
}
}
}
} else if ("c".equals(fieldName)) {
if (jp.getCurrentToken() != JsonToken.START_ARRAY) {
return null;
}
while (jp.nextToken() != JsonToken.END_ARRAY) {
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
String candidateID = jp.getText();
recon.addCandidate(pool.getReconCandidate(candidateID));
} else {
// legacy
recon.addCandidate(ReconCandidate.loadStreaming(jp));
}
}
} else if ("service".equals(fieldName)) {
recon.service = jp.getText();
} else if ("judgmentAction".equals(fieldName)) {
recon.judgmentAction = jp.getText();
} else if ("judgmentBatchSize".equals(fieldName)) {
recon.judgmentBatchSize = jp.getIntValue();
} else if ("matchRank".equals(fieldName)) {
recon.matchRank = jp.getIntValue();
} }
} else if ("service".equals(fieldName)) {
recon.service = jp.getText();
} else if ("judgmentAction".equals(fieldName)) {
recon.judgmentAction = jp.getText();
} else if ("judgmentHistoryEntry".equals(fieldName)) {
recon.judgmentHistoryEntry = jp.getLongValue();
} else if ("judgmentBatchSize".equals(fieldName)) {
recon.judgmentBatchSize = jp.getIntValue();
} else if ("matchRank".equals(fieldName)) {
recon.matchRank = jp.getIntValue();
} }
} }

View File

@ -37,6 +37,7 @@ public class DataExtensionChange implements Change {
final protected List<Integer> _rowIndices; final protected List<Integer> _rowIndices;
final protected List<DataExtension> _dataExtensions; final protected List<DataExtension> _dataExtensions;
protected long _historyEntryID;
protected int _firstNewCellIndex = -1; protected int _firstNewCellIndex = -1;
protected List<Row> _oldRows; protected List<Row> _oldRows;
protected List<Row> _newRows; protected List<Row> _newRows;
@ -47,7 +48,8 @@ public class DataExtensionChange implements Change {
List<String> columnNames, List<String> columnNames,
List<FreebaseType> columnTypes, List<FreebaseType> columnTypes,
List<Integer> rowIndices, List<Integer> rowIndices,
List<DataExtension> dataExtensions List<DataExtension> dataExtensions,
long historyEntryID
) { ) {
_baseColumnName = baseColumnName; _baseColumnName = baseColumnName;
_columnInsertIndex = columnInsertIndex; _columnInsertIndex = columnInsertIndex;
@ -57,6 +59,8 @@ public class DataExtensionChange implements Change {
_rowIndices = rowIndices; _rowIndices = rowIndices;
_dataExtensions = dataExtensions; _dataExtensions = dataExtensions;
_historyEntryID = historyEntryID;
} }
protected DataExtensionChange( protected DataExtensionChange(
@ -179,7 +183,7 @@ public class DataExtensionChange implements Change {
if (value instanceof ReconCandidate) { if (value instanceof ReconCandidate) {
ReconCandidate rc = (ReconCandidate) value; ReconCandidate rc = (ReconCandidate) value;
Recon recon = new Recon(); Recon recon = new Recon(_historyEntryID);
recon.addCandidate(rc); recon.addCandidate(rc);
recon.service = "mql"; recon.service = "mql";
recon.match = rc; recon.match = rc;

View File

@ -52,7 +52,7 @@ public class DataExtensionReconConfig extends StrictReconConfig {
} }
@Override @Override
public List<Recon> batchRecon(List<ReconJob> jobs) { public List<Recon> batchRecon(List<ReconJob> jobs, long historyEntryID) {
throw new RuntimeException(WARN); throw new RuntimeException(WARN);
} }

View File

@ -77,7 +77,7 @@ public class GuidBasedReconConfig extends StrictReconConfig {
} }
@Override @Override
public List<Recon> batchRecon(List<ReconJob> jobs) { public List<Recon> batchRecon(List<ReconJob> jobs, long historyEntryID) {
List<Recon> recons = new ArrayList<Recon>(jobs.size()); List<Recon> recons = new ArrayList<Recon>(jobs.size());
Map<String, Recon> guidToRecon = new HashMap<String, Recon>(); Map<String, Recon> guidToRecon = new HashMap<String, Recon>();
@ -147,7 +147,7 @@ public class GuidBasedReconConfig extends StrictReconConfig {
100 100
); );
Recon recon = new Recon(); Recon recon = new Recon(historyEntryID);
recon.addCandidate(candidate); recon.addCandidate(candidate);
recon.service = "mql"; recon.service = "mql";
recon.judgment = Judgment.Matched; recon.judgment = Judgment.Matched;

View File

@ -190,15 +190,15 @@ public class HeuristicReconConfig extends ReconConfig {
} }
@Override @Override
public List<Recon> batchRecon(List<ReconJob> jobs) { public List<Recon> batchRecon(List<ReconJob> jobs, long historyEntryID) {
if ("relevance".equals(service)) { if ("relevance".equals(service)) {
return batchReconUsingRelevance(jobs); return batchReconUsingRelevance(jobs, historyEntryID);
} else { } else {
return batchReconUsingReconService(jobs); return batchReconUsingReconService(jobs, historyEntryID);
} }
} }
protected List<Recon> batchReconUsingRelevance(List<ReconJob> jobs) { protected List<Recon> batchReconUsingRelevance(List<ReconJob> jobs, long historyEntryID) {
List<Recon> recons = new ArrayList<Recon>(jobs.size()); List<Recon> recons = new ArrayList<Recon>(jobs.size());
try { try {
@ -251,9 +251,9 @@ public class HeuristicReconConfig extends ReconConfig {
if (o2.has("result")) { if (o2.has("result")) {
JSONArray results = o2.getJSONArray("result"); JSONArray results = o2.getJSONArray("result");
recon = createReconFromRelevanceResults(text, results); recon = createReconFromRelevanceResults(text, results, historyEntryID);
} else { } else {
recon = new Recon(); recon = new Recon(historyEntryID);
} }
recon.service = "recon"; recon.service = "recon";
@ -269,8 +269,8 @@ public class HeuristicReconConfig extends ReconConfig {
return recons; return recons;
} }
protected Recon createReconFromRelevanceResults(String text, JSONArray results) { protected Recon createReconFromRelevanceResults(String text, JSONArray results, long historyEntryID) {
Recon recon = new Recon(); Recon recon = new Recon(historyEntryID);
try { try {
int length = results.length(); int length = results.length();
int count = 0; int count = 0;
@ -332,7 +332,7 @@ public class HeuristicReconConfig extends ReconConfig {
static final String s_reconService = "http://data.labs.freebase.com/recon/query"; static final String s_reconService = "http://data.labs.freebase.com/recon/query";
protected List<Recon> batchReconUsingReconService(List<ReconJob> jobs) { protected List<Recon> batchReconUsingReconService(List<ReconJob> jobs, long historyEntryID) {
List<Recon> recons = new ArrayList<Recon>(jobs.size()); List<Recon> recons = new ArrayList<Recon>(jobs.size());
for (int i = 0; i < jobs.size(); i++) { for (int i = 0; i < jobs.size(); i++) {
@ -353,7 +353,7 @@ public class HeuristicReconConfig extends ReconConfig {
String s = ParsingUtilities.inputStreamToString(is); String s = ParsingUtilities.inputStreamToString(is);
JSONArray a = ParsingUtilities.evaluateJsonStringToArray(s); JSONArray a = ParsingUtilities.evaluateJsonStringToArray(s);
recon = createReconFromReconResults(job.text, a); recon = createReconFromReconResults(job.text, a, historyEntryID);
} finally { } finally {
is.close(); is.close();
} }
@ -362,7 +362,7 @@ public class HeuristicReconConfig extends ReconConfig {
} }
if (recon == null) { if (recon == null) {
recon = new Recon(); recon = new Recon(historyEntryID);
} }
recon.service = "recon"; recon.service = "recon";
recons.add(recon); recons.add(recon);
@ -371,8 +371,8 @@ public class HeuristicReconConfig extends ReconConfig {
return recons; return recons;
} }
protected Recon createReconFromReconResults(String text, JSONArray results) { protected Recon createReconFromReconResults(String text, JSONArray results, long historyEntryID) {
Recon recon = new Recon(); Recon recon = new Recon(historyEntryID);
try { try {
int length = results.length(); int length = results.length();
int count = 0; int count = 0;

View File

@ -81,7 +81,7 @@ public class IdBasedReconConfig extends StrictReconConfig {
} }
@Override @Override
public List<Recon> batchRecon(List<ReconJob> jobs) { public List<Recon> batchRecon(List<ReconJob> jobs, long historyEntryID) {
List<Recon> recons = new ArrayList<Recon>(jobs.size()); List<Recon> recons = new ArrayList<Recon>(jobs.size());
Map<String, Recon> idToRecon = new HashMap<String, Recon>(); Map<String, Recon> idToRecon = new HashMap<String, Recon>();
@ -151,7 +151,7 @@ public class IdBasedReconConfig extends StrictReconConfig {
100 100
); );
Recon recon = new Recon(); Recon recon = new Recon(historyEntryID);
recon.addCandidate(candidate); recon.addCandidate(candidate);
recon.service = "mql"; recon.service = "mql";
recon.judgment = Judgment.Matched; recon.judgment = Judgment.Matched;

View File

@ -82,7 +82,7 @@ public class KeyBasedReconConfig extends StrictReconConfig {
} }
@Override @Override
public List<Recon> batchRecon(List<ReconJob> jobs) { public List<Recon> batchRecon(List<ReconJob> jobs, long historyEntryID) {
List<Recon> recons = new ArrayList<Recon>(jobs.size()); List<Recon> recons = new ArrayList<Recon>(jobs.size());
Map<String, Recon> keyToRecon = new HashMap<String, Recon>(); Map<String, Recon> keyToRecon = new HashMap<String, Recon>();
@ -165,7 +165,7 @@ public class KeyBasedReconConfig extends StrictReconConfig {
100 100
); );
Recon recon = new Recon(); Recon recon = new Recon(historyEntryID);
recon.addCandidate(candidate); recon.addCandidate(candidate);
recon.service = "mql"; recon.service = "mql";
recon.judgment = Judgment.Matched; recon.judgment = Judgment.Matched;

View File

@ -39,7 +39,7 @@ abstract public class ReconConfig implements Jsonizable {
Cell cell Cell cell
); );
abstract public List<Recon> batchRecon(List<ReconJob> jobs); abstract public List<Recon> batchRecon(List<ReconJob> jobs, long historyEntryID);
public void save(Writer writer) { public void save(Writer writer) {
JSONWriter jsonWriter = new JSONWriter(writer); JSONWriter jsonWriter = new JSONWriter(writer);

View File

@ -93,7 +93,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
" rows with " + _expression; " rows with " + _expression;
} }
protected HistoryEntry createHistoryEntry(Project project) 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);
@ -111,7 +111,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
Change change = new ColumnAdditionChange(_newColumnName, _columnInsertIndex, cellsAtRows); Change change = new ColumnAdditionChange(_newColumnName, _columnInsertIndex, cellsAtRows);
return new HistoryEntry( return new HistoryEntry(
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 {

View File

@ -43,7 +43,7 @@ public class ColumnRemovalOperation extends AbstractOperation {
return "Remove column " + _columnName; return "Remove column " + _columnName;
} }
protected HistoryEntry createHistoryEntry(Project project) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
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);
@ -53,6 +53,6 @@ public class ColumnRemovalOperation extends AbstractOperation {
Change change = new ColumnRemovalChange(project.columnModel.columns.indexOf(column)); Change change = new ColumnRemovalChange(project.columnModel.columns.indexOf(column));
return new HistoryEntry(project, description, ColumnRemovalOperation.this, change); return new HistoryEntry(historyEntryID, project, description, ColumnRemovalOperation.this, change);
} }
} }

View File

@ -47,7 +47,7 @@ public class ColumnRenameOperation extends AbstractOperation {
return "Rename column " + _oldColumnName + " to " + _newColumnName; return "Rename column " + _oldColumnName + " to " + _newColumnName;
} }
protected HistoryEntry createHistoryEntry(Project project) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
if (project.columnModel.getColumnByName(_oldColumnName) == null) { if (project.columnModel.getColumnByName(_oldColumnName) == null) {
throw new Exception("No column named " + _oldColumnName); throw new Exception("No column named " + _oldColumnName);
} }
@ -57,6 +57,6 @@ public class ColumnRenameOperation extends AbstractOperation {
Change change = new ColumnRenameChange(_oldColumnName, _newColumnName); Change change = new ColumnRenameChange(_oldColumnName, _newColumnName);
return new HistoryEntry(project, getBriefDescription(null), ColumnRenameOperation.this, change); return new HistoryEntry(historyEntryID, project, getBriefDescription(null), ColumnRenameOperation.this, change);
} }
} }

View File

@ -138,7 +138,7 @@ public class ColumnSplitOperation extends EngineDependentOperation {
("separator".equals(_mode) ? " by separator" : " by field lengths"); ("separator".equals(_mode) ? " by separator" : " by field lengths");
} }
protected HistoryEntry createHistoryEntry(Project project) 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);
@ -212,7 +212,7 @@ public class ColumnSplitOperation extends EngineDependentOperation {
); );
return new HistoryEntry( return new HistoryEntry(
project, description, this, change); historyEntryID, project, description, this, change);
} }
protected class ColumnSplitRowVisitor implements RowVisitor { protected class ColumnSplitRowVisitor implements RowVisitor {

View File

@ -26,7 +26,7 @@ abstract public class EngineDependentMassCellOperation extends EngineDependentOp
_updateRowContextDependencies = updateRowContextDependencies; _updateRowContextDependencies = updateRowContextDependencies;
} }
protected HistoryEntry createHistoryEntry(Project project) 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);
@ -38,7 +38,7 @@ abstract public class EngineDependentMassCellOperation extends EngineDependentOp
FilteredRows filteredRows = engine.getAllFilteredRows(false); FilteredRows filteredRows = engine.getAllFilteredRows(false);
try { try {
filteredRows.accept(project, createRowVisitor(project, cellChanges)); filteredRows.accept(project, createRowVisitor(project, cellChanges, historyEntryID));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -46,7 +46,7 @@ abstract public class EngineDependentMassCellOperation extends EngineDependentOp
String description = createDescription(column, cellChanges); String description = createDescription(column, cellChanges);
return new HistoryEntry( return new HistoryEntry(
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) {
@ -54,6 +54,6 @@ abstract public class EngineDependentMassCellOperation extends EngineDependentOp
cellChanges, column.getName(), _updateRowContextDependencies); cellChanges, column.getName(), _updateRowContextDependencies);
} }
abstract protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) 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

@ -95,6 +95,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
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;
final protected long _historyEntryID;
protected int _cellIndex; protected int _cellIndex;
protected FreebaseDataExtensionJob _job; protected FreebaseDataExtensionJob _job;
@ -106,6 +107,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
super(description); super(description);
_project = project; _project = project;
_engineConfig = engineConfig; _engineConfig = engineConfig;
_historyEntryID = HistoryEntry.allocateID();
_job = new FreebaseDataExtensionJob(_extension); _job = new FreebaseDataExtensionJob(_extension);
} }
@ -230,6 +232,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
} }
HistoryEntry historyEntry = new HistoryEntry( HistoryEntry historyEntry = new HistoryEntry(
_historyEntryID,
_project, _project,
_description, _description,
ExtendDataOperation.this, ExtendDataOperation.this,
@ -239,7 +242,8 @@ public class ExtendDataOperation extends EngineDependentOperation {
columnNames, columnNames,
columnTypes, columnTypes,
rowIndices, rowIndices,
dataExtensions) dataExtensions,
_historyEntryID)
); );
_project.history.addEntry(historyEntry); _project.history.addEntry(historyEntry);

View File

@ -129,7 +129,7 @@ public class MassEditOperation extends EngineDependentMassCellOperation {
" cells in column " + column.getName(); " cells in column " + column.getName();
} }
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception { protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception {
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
Evaluable eval = MetaParser.parse(_expression); Evaluable eval = MetaParser.parse(_expression);

View File

@ -56,7 +56,7 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
return "Join multi-valued cells in column " + _columnName; return "Join multi-valued cells in column " + _columnName;
} }
protected HistoryEntry createHistoryEntry(Project project) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
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);
@ -118,6 +118,7 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
} }
return new HistoryEntry( return new HistoryEntry(
historyEntryID,
project, project,
getBriefDescription(null), getBriefDescription(null),
this, this,

View File

@ -62,7 +62,7 @@ public class MultiValuedCellSplitOperation extends AbstractOperation {
} }
@Override @Override
protected HistoryEntry createHistoryEntry(Project project) throws Exception { protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
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);
@ -136,6 +136,7 @@ public class MultiValuedCellSplitOperation extends AbstractOperation {
} }
return new HistoryEntry( return new HistoryEntry(
historyEntryID,
project, project,
getBriefDescription(null), getBriefDescription(null),
this, this,

View File

@ -58,17 +58,19 @@ public class ReconDiscardJudgmentsOperation extends EngineDependentMassCellOpera
" cells in column " + column.getName(); " cells in column " + column.getName();
} }
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception { protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception {
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
return new RowVisitor() { return new RowVisitor() {
int cellIndex; int cellIndex;
List<CellChange> cellChanges; List<CellChange> cellChanges;
Map<Long, Recon> dupReconMap = new HashMap<Long, Recon>(); Map<Long, Recon> dupReconMap = new HashMap<Long, Recon>();
long historyEntryID;
public RowVisitor init(int cellIndex, List<CellChange> cellChanges) { public RowVisitor init(int cellIndex, List<CellChange> cellChanges, long historyEntryID) {
this.cellIndex = cellIndex; this.cellIndex = cellIndex;
this.cellChanges = cellChanges; this.cellChanges = cellChanges;
this.historyEntryID = historyEntryID;
return this; return this;
} }
@ -80,7 +82,7 @@ public class ReconDiscardJudgmentsOperation extends EngineDependentMassCellOpera
newRecon = dupReconMap.get(cell.recon.id); newRecon = dupReconMap.get(cell.recon.id);
newRecon.judgmentBatchSize++; newRecon.judgmentBatchSize++;
} else { } else {
newRecon = cell.recon.dup(); newRecon = cell.recon.dup(historyEntryID);
newRecon.match = null; newRecon.match = null;
newRecon.matchRank = -1; newRecon.matchRank = -1;
newRecon.judgment = Judgment.None; newRecon.judgment = Judgment.None;
@ -97,7 +99,7 @@ public class ReconDiscardJudgmentsOperation extends EngineDependentMassCellOpera
} }
return false; return false;
} }
}.init(column.getCellIndex(), cellChanges); }.init(column.getCellIndex(), cellChanges, historyEntryID);
} }
protected Change createChange(Project project, Column column, List<CellChange> cellChanges) { protected Change createChange(Project project, Column column, List<CellChange> cellChanges) {

View File

@ -145,7 +145,7 @@ public class ReconJudgeSimilarCellsOperation extends EngineDependentMassCellOper
throw new InternalError("Can't get here"); throw new InternalError("Can't get here");
} }
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception { protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception {
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
return new RowVisitor() { return new RowVisitor() {
@ -153,10 +153,12 @@ public class ReconJudgeSimilarCellsOperation extends EngineDependentMassCellOper
List<CellChange> _cellChanges; List<CellChange> _cellChanges;
Recon _sharedNewRecon = null; Recon _sharedNewRecon = null;
Map<Long, Recon> _dupReconMap = new HashMap<Long, Recon>(); Map<Long, Recon> _dupReconMap = new HashMap<Long, Recon>();
long _historyEntryID;
public RowVisitor init(int cellIndex, List<CellChange> cellChanges) { public RowVisitor init(int cellIndex, List<CellChange> cellChanges, long historyEntryID) {
_cellIndex = cellIndex; _cellIndex = cellIndex;
_cellChanges = cellChanges; _cellChanges = cellChanges;
_historyEntryID = historyEntryID;
return this; return this;
} }
@ -169,7 +171,7 @@ public class ReconJudgeSimilarCellsOperation extends EngineDependentMassCellOper
Recon recon = null; Recon recon = null;
if (_judgment == Judgment.New && _shareNewTopics) { if (_judgment == Judgment.New && _shareNewTopics) {
if (_sharedNewRecon == null) { if (_sharedNewRecon == null) {
_sharedNewRecon = new Recon(); _sharedNewRecon = new Recon(_historyEntryID);
_sharedNewRecon.judgment = Judgment.New; _sharedNewRecon.judgment = Judgment.New;
_sharedNewRecon.judgmentBatchSize = 0; _sharedNewRecon.judgmentBatchSize = 0;
_sharedNewRecon.judgmentAction = "similar"; _sharedNewRecon.judgmentAction = "similar";
@ -182,7 +184,7 @@ public class ReconJudgeSimilarCellsOperation extends EngineDependentMassCellOper
recon = _dupReconMap.get(cell.recon.id); recon = _dupReconMap.get(cell.recon.id);
recon.judgmentBatchSize++; recon.judgmentBatchSize++;
} else { } else {
recon = cell.recon.dup(); recon = cell.recon.dup(_historyEntryID);
recon.judgmentBatchSize = 1; recon.judgmentBatchSize = 1;
recon.matchRank = -1; recon.matchRank = -1;
recon.judgmentAction = "similar"; recon.judgmentAction = "similar";
@ -218,7 +220,7 @@ public class ReconJudgeSimilarCellsOperation extends EngineDependentMassCellOper
} }
return false; return false;
} }
}.init(column.getCellIndex(), cellChanges); }.init(column.getCellIndex(), cellChanges, historyEntryID);
} }

View File

@ -68,7 +68,7 @@ public class ReconMarkNewTopicsOperation extends EngineDependentMassCellOperatio
", one topic for each cell"); ", one topic for each cell");
} }
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception { protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception {
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
return new RowVisitor() { return new RowVisitor() {
@ -76,10 +76,12 @@ public class ReconMarkNewTopicsOperation extends EngineDependentMassCellOperatio
List<CellChange> cellChanges; List<CellChange> cellChanges;
Map<String, Recon> sharedRecons = new HashMap<String, Recon>(); Map<String, Recon> sharedRecons = new HashMap<String, Recon>();
Map<Long, Recon> dupReconMap = new HashMap<Long, Recon>(); Map<Long, Recon> dupReconMap = new HashMap<Long, Recon>();
long historyEntryID;
public RowVisitor init(int cellIndex, List<CellChange> cellChanges) { public RowVisitor init(int cellIndex, List<CellChange> cellChanges, long historyEntryID) {
this.cellIndex = cellIndex; this.cellIndex = cellIndex;
this.cellChanges = cellChanges; this.cellChanges = cellChanges;
this.historyEntryID = historyEntryID;
return this; return this;
} }
@ -93,7 +95,7 @@ public class ReconMarkNewTopicsOperation extends EngineDependentMassCellOperatio
recon = sharedRecons.get(s); recon = sharedRecons.get(s);
recon.judgmentBatchSize++; recon.judgmentBatchSize++;
} else { } else {
recon = new Recon(); recon = new Recon(historyEntryID);
recon.judgment = Judgment.New; recon.judgment = Judgment.New;
recon.judgmentBatchSize = 1; recon.judgmentBatchSize = 1;
recon.judgmentAction = "mass"; recon.judgmentAction = "mass";
@ -106,7 +108,7 @@ public class ReconMarkNewTopicsOperation extends EngineDependentMassCellOperatio
recon = dupReconMap.get(reconID); recon = dupReconMap.get(reconID);
recon.judgmentBatchSize++; recon.judgmentBatchSize++;
} else { } else {
recon = cell.recon == null ? new Recon() : cell.recon.dup(); recon = cell.recon == null ? new Recon(historyEntryID) : cell.recon.dup(historyEntryID);
recon.match = null; recon.match = null;
recon.matchRank = -1; recon.matchRank = -1;
recon.judgment = Judgment.New; recon.judgment = Judgment.New;
@ -124,7 +126,7 @@ public class ReconMarkNewTopicsOperation extends EngineDependentMassCellOperatio
} }
return false; return false;
} }
}.init(column.getCellIndex(), cellChanges); }.init(column.getCellIndex(), cellChanges, historyEntryID);
} }
protected Change createChange(Project project, Column column, List<CellChange> cellChanges) { protected Change createChange(Project project, Column column, List<CellChange> cellChanges) {

View File

@ -59,17 +59,19 @@ public class ReconMatchBestCandidatesOperation extends EngineDependentMassCellOp
" cells to its best candidate in column " + column.getName(); " cells to its best candidate in column " + column.getName();
} }
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception { protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception {
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
return new RowVisitor() { return new RowVisitor() {
int cellIndex; int cellIndex;
List<CellChange> cellChanges; List<CellChange> cellChanges;
Map<Long, Recon> dupReconMap = new HashMap<Long, Recon>(); Map<Long, Recon> dupReconMap = new HashMap<Long, Recon>();
long historyEntryID;
public RowVisitor init(int cellIndex, List<CellChange> cellChanges) { public RowVisitor init(int cellIndex, List<CellChange> cellChanges, long historyEntryID) {
this.cellIndex = cellIndex; this.cellIndex = cellIndex;
this.cellChanges = cellChanges; this.cellChanges = cellChanges;
this.historyEntryID = historyEntryID;
return this; return this;
} }
@ -84,7 +86,7 @@ public class ReconMatchBestCandidatesOperation extends EngineDependentMassCellOp
newRecon = dupReconMap.get(cell.recon.id); newRecon = dupReconMap.get(cell.recon.id);
newRecon.judgmentBatchSize++; newRecon.judgmentBatchSize++;
} else { } else {
newRecon = cell.recon.dup(); newRecon = cell.recon.dup(historyEntryID);
newRecon.judgmentBatchSize = 1; newRecon.judgmentBatchSize = 1;
newRecon.match = candidate; newRecon.match = candidate;
newRecon.matchRank = 0; newRecon.matchRank = 0;
@ -105,7 +107,7 @@ public class ReconMatchBestCandidatesOperation extends EngineDependentMassCellOp
} }
return false; return false;
} }
}.init(column.getCellIndex(), cellChanges); }.init(column.getCellIndex(), cellChanges, historyEntryID);
} }
protected Change createChange(Project project, Column column, List<CellChange> cellChanges) { protected Change createChange(Project project, Column column, List<CellChange> cellChanges) {

View File

@ -92,17 +92,19 @@ public class ReconMatchSpecificTopicOperation extends EngineDependentMassCellOpe
" cells in column " + column.getName(); " cells in column " + column.getName();
} }
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception { protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception {
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
return new RowVisitor() { return new RowVisitor() {
int cellIndex; int cellIndex;
List<CellChange> cellChanges; List<CellChange> cellChanges;
Map<Long, Recon> dupReconMap = new HashMap<Long, Recon>(); Map<Long, Recon> dupReconMap = new HashMap<Long, Recon>();
long historyEntryID;
public RowVisitor init(int cellIndex, List<CellChange> cellChanges) { public RowVisitor init(int cellIndex, List<CellChange> cellChanges, long historyEntryID) {
this.cellIndex = cellIndex; this.cellIndex = cellIndex;
this.cellChanges = cellChanges; this.cellChanges = cellChanges;
this.historyEntryID = historyEntryID;
return this; return this;
} }
@ -116,7 +118,7 @@ public class ReconMatchSpecificTopicOperation extends EngineDependentMassCellOpe
newRecon = dupReconMap.get(reconID); newRecon = dupReconMap.get(reconID);
newRecon.judgmentBatchSize++; newRecon.judgmentBatchSize++;
} else { } else {
newRecon = cell.recon != null ? cell.recon.dup() : new Recon(); newRecon = cell.recon != null ? cell.recon.dup(historyEntryID) : new Recon(historyEntryID);
newRecon.match = match; newRecon.match = match;
newRecon.matchRank = -1; newRecon.matchRank = -1;
newRecon.judgment = Judgment.Matched; newRecon.judgment = Judgment.Matched;
@ -136,7 +138,7 @@ public class ReconMatchSpecificTopicOperation extends EngineDependentMassCellOpe
} }
return false; return false;
} }
}.init(column.getCellIndex(), cellChanges); }.init(column.getCellIndex(), cellChanges, historyEntryID);
} }
protected Change createChange(Project project, Column column, List<CellChange> cellChanges) { protected Change createChange(Project project, Column column, List<CellChange> cellChanges) {

View File

@ -99,6 +99,7 @@ public class ReconOperation extends EngineDependentOperation {
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;
protected List<ReconEntry> _entries; protected List<ReconEntry> _entries;
protected int _cellIndex; protected int _cellIndex;
@ -110,6 +111,7 @@ public class ReconOperation extends EngineDependentOperation {
super(description); super(description);
_project = project; _project = project;
_engineConfig = engineConfig; _engineConfig = engineConfig;
_historyEntryID = HistoryEntry.allocateID();
} }
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
@ -226,7 +228,7 @@ public class ReconOperation extends EngineDependentOperation {
jobs.add(groups.get(j).job); jobs.add(groups.get(j).job);
} }
List<Recon> recons = _reconConfig.batchRecon(jobs); 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;
@ -268,6 +270,7 @@ public class ReconOperation extends EngineDependentOperation {
); );
HistoryEntry historyEntry = new HistoryEntry( HistoryEntry historyEntry = new HistoryEntry(
_historyEntryID,
_project, _project,
_description, _description,
ReconOperation.this, ReconOperation.this,

View File

@ -52,7 +52,7 @@ public class RowFlagOperation extends EngineDependentOperation {
return (_flagged ? "Flag rows" : "Unflag rows"); return (_flagged ? "Flag rows" : "Unflag rows");
} }
protected HistoryEntry createHistoryEntry(Project project) 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());
@ -61,6 +61,7 @@ public class RowFlagOperation extends EngineDependentOperation {
filteredRows.accept(project, createRowVisitor(project, changes)); filteredRows.accept(project, createRowVisitor(project, changes));
return new HistoryEntry( return new HistoryEntry(
historyEntryID,
project, project,
(_flagged ? "Flag" : "Unflag") + " " + changes.size() + " rows", (_flagged ? "Flag" : "Unflag") + " " + changes.size() + " rows",
this, this,

View File

@ -44,7 +44,7 @@ public class RowRemovalOperation extends EngineDependentOperation {
return "Remove rows"; return "Remove rows";
} }
protected HistoryEntry createHistoryEntry(Project project) 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>();
@ -53,6 +53,7 @@ public class RowRemovalOperation extends EngineDependentOperation {
filteredRows.accept(project, createRowVisitor(project, rowIndices)); filteredRows.accept(project, createRowVisitor(project, rowIndices));
return new HistoryEntry( return new HistoryEntry(
historyEntryID,
project, project,
"Remove " + rowIndices.size() + " rows", "Remove " + rowIndices.size() + " rows",
this, this,

View File

@ -52,7 +52,7 @@ public class RowStarOperation extends EngineDependentOperation {
return (_starred ? "Star rows" : "Unstar rows"); return (_starred ? "Star rows" : "Unstar rows");
} }
protected HistoryEntry createHistoryEntry(Project project) 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());
@ -61,6 +61,7 @@ public class RowStarOperation extends EngineDependentOperation {
filteredRows.accept(project, createRowVisitor(project, changes)); filteredRows.accept(project, createRowVisitor(project, changes));
return new HistoryEntry( return new HistoryEntry(
historyEntryID,
project, project,
(_starred ? "Star" : "Unstar") + " " + changes.size() + " rows", (_starred ? "Star" : "Unstar") + " " + changes.size() + " rows",
this, this,

View File

@ -45,12 +45,12 @@ public class SaveProtographOperation extends AbstractOperation {
} }
@Override @Override
protected HistoryEntry createHistoryEntry(Project project) 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 new HistoryEntry(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 {

View File

@ -98,7 +98,7 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
" cells in column " + column.getName() + ": " + _expression; " cells in column " + column.getName() + ": " + _expression;
} }
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges) throws Exception { protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception {
Column column = project.columnModel.getColumnByName(_columnName); Column column = project.columnModel.getColumnByName(_columnName);
Evaluable eval = MetaParser.parse(_expression); Evaluable eval = MetaParser.parse(_expression);

View File

@ -33,7 +33,7 @@ abstract public class QuickHistoryEntryProcess extends Process {
public HistoryEntry performImmediate() throws Exception { public HistoryEntry performImmediate() throws Exception {
if (_historyEntry == null) { if (_historyEntry == null) {
_historyEntry = createHistoryEntry(); _historyEntry = createHistoryEntry(HistoryEntry.allocateID());
} }
_project.history.addEntry(_historyEntry); _project.history.addEntry(_historyEntry);
_done = true; _done = true;
@ -62,5 +62,5 @@ abstract public class QuickHistoryEntryProcess extends Process {
return _done; return _done;
} }
abstract protected HistoryEntry createHistoryEntry() throws Exception; abstract protected HistoryEntry createHistoryEntry(long historyEntryID) throws Exception;
} }