diff --git a/src/main/java/com/metaweb/gridworks/GridworksServlet.java b/src/main/java/com/metaweb/gridworks/GridworksServlet.java index d29a9582e..f5d8f078d 100644 --- a/src/main/java/com/metaweb/gridworks/GridworksServlet.java +++ b/src/main/java/com/metaweb/gridworks/GridworksServlet.java @@ -16,6 +16,7 @@ import org.json.JSONTokener; import com.metaweb.gridworks.commands.Command; import com.metaweb.gridworks.commands.edit.AddColumnCommand; +import com.metaweb.gridworks.commands.edit.ApplyOperationsCommand; import com.metaweb.gridworks.commands.edit.CreateProjectCommand; import com.metaweb.gridworks.commands.edit.DoTextTransformCommand; import com.metaweb.gridworks.commands.edit.JoinMultiValueCellsCommand; @@ -60,6 +61,8 @@ public class GridworksServlet extends HttpServlet { _commands.put("get-operations", new GetOperationsCommand()); _commands.put("undo-redo", new UndoRedoCommand()); + _commands.put("apply-operations", new ApplyOperationsCommand()); + _commands.put("compute-facets", new ComputeFacetsCommand()); _commands.put("do-text-transform", new DoTextTransformCommand()); diff --git a/src/main/java/com/metaweb/gridworks/commands/edit/ApplyOperationsCommand.java b/src/main/java/com/metaweb/gridworks/commands/edit/ApplyOperationsCommand.java new file mode 100644 index 000000000..fc43836e6 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/commands/edit/ApplyOperationsCommand.java @@ -0,0 +1,118 @@ +package com.metaweb.gridworks.commands.edit; + +import java.io.IOException; +import java.util.Properties; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import com.metaweb.gridworks.commands.Command; +import com.metaweb.gridworks.model.AbstractOperation; +import com.metaweb.gridworks.model.Project; +import com.metaweb.gridworks.model.operations.ApproveNewReconOperation; +import com.metaweb.gridworks.model.operations.ApproveReconOperation; +import com.metaweb.gridworks.model.operations.ColumnAdditionOperation; +import com.metaweb.gridworks.model.operations.ColumnRemovalOperation; +import com.metaweb.gridworks.model.operations.DiscardReconOperation; +import com.metaweb.gridworks.model.operations.MultiValueCellJoinOperation; +import com.metaweb.gridworks.model.operations.MultiValueCellSplitOperation; +import com.metaweb.gridworks.model.operations.ReconOperation; +import com.metaweb.gridworks.model.operations.SaveProtographOperation; +import com.metaweb.gridworks.model.operations.TextTransformOperation; +import com.metaweb.gridworks.process.Process; +import com.metaweb.gridworks.protograph.Protograph; + +public class ApplyOperationsCommand extends Command { + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + Project project = getProject(request); + String jsonString = request.getParameter("operations"); + try { + JSONArray a = jsonStringToArray(jsonString); + int count = a.length(); + for (int i = 0; i < count; i++) { + JSONObject obj = a.getJSONObject(i); + + reconstructOperation(project, obj); + } + + respond(response, "{ \"code\" : \"pending\" }"); + } catch (JSONException e) { + respondException(response, e); + } + } + + protected void reconstructOperation(Project project, JSONObject obj) { + try { + String op = obj.getString("op"); + AbstractOperation operation = null; + + JSONObject engineConfig = obj.has("engineConfig") ? obj.getJSONObject("engineConfig") : null; + String columnName = obj.has("columnName") ? obj.getString("columnName") : null; + + if ("approve-new-recon".equals(op)) { + operation = new ApproveNewReconOperation(engineConfig, columnName); + } else if ("approve-recon".equals(op)) { + operation = new ApproveReconOperation(engineConfig, columnName); + } else if ("add-column".equals(op)) { + operation = new ColumnAdditionOperation( + engineConfig, + obj.getString("baseColumnName"), + obj.getString("expression"), + obj.getString("headerLabel"), + obj.getInt("columnInsertIndex") + ); + } else if ("remove-column".equals(op)) { + operation = new ColumnRemovalOperation(columnName); + } else if ("discard-recon".equals(op)) { + operation = new DiscardReconOperation(engineConfig, columnName); + } else if ("join-multivalued-cells".equals(op)) { + operation = new MultiValueCellJoinOperation( + columnName, + obj.getString("keyColumnName"), + obj.getString("separator") + ); + } else if ("split-multivalued-cells".equals(op)) { + operation = new MultiValueCellSplitOperation( + columnName, + obj.getString("keyColumnName"), + obj.getString("separator"), + obj.getString("mode") + ); + } else if ("recon".equals(op)) { + operation = new ReconOperation( + engineConfig, + columnName, + obj.getString("typeID") + ); + } else if ("save-protograph".equals(op)) { + operation = new SaveProtographOperation( + Protograph.reconstruct(obj.getJSONObject("protograph")) + ); + } else if ("text-transform".equals(op)) { + operation = new TextTransformOperation( + engineConfig, + columnName, + obj.getString("expression") + ); + } + + if (operation != null) { + Process process = operation.createProcess(project, new Properties()); + + project.processManager.queueProcess(process); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/src/main/java/com/metaweb/gridworks/model/operations/DiscardReconOperation.java b/src/main/java/com/metaweb/gridworks/model/operations/DiscardReconOperation.java index 51b8f3a9b..fcb709c59 100644 --- a/src/main/java/com/metaweb/gridworks/model/operations/DiscardReconOperation.java +++ b/src/main/java/com/metaweb/gridworks/model/operations/DiscardReconOperation.java @@ -25,8 +25,8 @@ public class DiscardReconOperation extends EngineDependentMassCellOperation { throws JSONException { writer.object(); - writer.key("op"); writer.value("disapprove-recon"); - writer.key("description"); writer.value("Discard recon judgments in column " + _columnName); + writer.key("op"); writer.value("discard-recon"); + writer.key("description"); writer.value("Discard recon matches in column " + _columnName); writer.key("engineConfig"); writer.value(getEngineConfig()); writer.key("columnName"); writer.value(_columnName); writer.endObject(); diff --git a/src/main/webapp/scripts/project/history-widget.js b/src/main/webapp/scripts/project/history-widget.js index e65faa11f..6fff05f96 100644 --- a/src/main/webapp/scripts/project/history-widget.js +++ b/src/main/webapp/scripts/project/history-widget.js @@ -18,15 +18,26 @@ HistoryWidget.prototype._render = function() { var self = this; this._div.empty(); + this._div.unbind(); $('

Undo/Redo History

').appendTo(this._div); var bodyDiv = $('
').addClass("history-panel-body").appendTo(this._div); bodyDiv.mouseenter(function(evt) { - $(this).addClass("history-panel-body-expanded"); + bodyDiv.addClass("history-panel-body-expanded"); + }); + + this._div.mouseenter(function(evt) { + if (self._timerID != null) { + window.clearTimeout(self._timerID); + self._timerID = null; + } }).mouseleave(function(evt) { - $(this).removeClass("history-panel-body-expanded"); - autoscroll(); + self._timerID = window.setTimeout(function() { + self._timerID = null; + bodyDiv.removeClass("history-panel-body-expanded"); + autoscroll(); + }, 1000); }); var renderEntry = function(container, entry, lastDoneID, title) { @@ -71,7 +82,7 @@ HistoryWidget.prototype._render = function() { }); $('').appendTo(footerDiv); $('').text("apply").appendTo(footerDiv).click(function() { - self._applyOperations(); + self._showApplyOperationsDialog(); }); }; @@ -99,22 +110,26 @@ HistoryWidget.prototype._extractOperations = function() { null, function(data) { if ("operations" in data) { - self._showOperationsDialog(data.operations); + self._showExtractOperationsDialog(data.operations); } }, "jsonp" ); }; -HistoryWidget.prototype._showOperationsDialog = function(json) { +HistoryWidget.prototype._showExtractOperationsDialog = function(json) { var self = this; var frame = DialogSystem.createDialog(); frame.width("800px"); - var header = $('
').addClass("dialog-header").text("Operations").appendTo(frame); + var header = $('
').addClass("dialog-header").text("Extract Operations").appendTo(frame); var body = $('
').addClass("dialog-body").appendTo(frame); var footer = $('
').addClass("dialog-footer").appendTo(frame); + $('

').text( + "The following JSON code encodes the operations you have done that can be abstracted. " + + "You can copy and save it in order to apply the same operations in the future.").appendTo(body); + var textarea = $('