package edu.isi.karma.controller.command.transformation;
import edu.isi.karma.controller.command.CommandException;
import edu.isi.karma.controller.command.CommandType;
import edu.isi.karma.controller.command.WorksheetSelectionCommand;
import edu.isi.karma.controller.command.selection.SuperSelection;
import edu.isi.karma.controller.update.UpdateContainer;
import edu.isi.karma.controller.update.WorksheetUpdateFactory;
import edu.isi.karma.er.helper.CloneTableUtils;
import edu.isi.karma.er.helper.PythonRepository;
import edu.isi.karma.er.helper.PythonRepositoryRegistry;
import edu.isi.karma.er.helper.PythonTransformationHelper;
import edu.isi.karma.rep.*;
import edu.isi.karma.webserver.ContextParametersRegistry;
import edu.isi.karma.webserver.ServletContextParameterMap;
import org.python.core.Py;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.util.PythonInterpreter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by chengyey on 9/15/15.
*/
public class AggregationPythonCommand extends WorksheetSelectionCommand {
private String hNodeId;
private String newHNodeId;
private String pythonCode;
private String constructor;
private String newColumnName;
private String newColumnAbsoluteName;
public AggregationPythonCommand(String id, String model, String worksheetId,
String selectionId, String hNodeId,
String pythonCode, String constructor,
String newColumnName) {
super(id, model, worksheetId, selectionId);
this.hNodeId = hNodeId;
this.pythonCode = pythonCode;
this.constructor = constructor;
this.newColumnName = newColumnName;
addTag(CommandTag.Transformation);
}
@Override
public String getCommandName() {
return AggregationPythonCommand.class.getSimpleName();
}
@Override
public String getTitle() {
return "Aggregation";
}
@Override
public String getDescription() {
return newColumnAbsoluteName + ": " + constructor;
}
@Override
public CommandType getCommandType() {
return CommandType.undoable;
}
@Override
public UpdateContainer doIt(Workspace workspace) throws CommandException {
final ServletContextParameterMap contextParameters = ContextParametersRegistry.getInstance().getContextParameters(workspace.getContextId());
PythonRepository repo = PythonRepositoryRegistry.getInstance().getPythonRepository(contextParameters.getParameterValue(ServletContextParameterMap.ContextParameter.USER_PYTHON_SCRIPTS_DIRECTORY));
PythonInterpreter interpreter = repo.getInterpreter();
repo.initializeInterpreter(interpreter);
interpreter.getLocals().__setitem__("workspaceid", new PyString(workspace.getId()));
interpreter.getLocals().__setitem__("selectionName", new PyString(selectionId));
interpreter.getLocals().__setitem__("command", Py.java2py(this));
interpreter.getLocals().__setitem__("worksheetId", new PyString(worksheetId));
if (!pythonCode.trim().isEmpty()) {
interpreter.exec(pythonCode);
}
RepFactory factory = workspace.getFactory();
Worksheet worksheet = workspace.getWorksheet(worksheetId);
SuperSelection selection = getSuperSelection(worksheet);
HNode hNode = factory.getHNode(hNodeId);
HTable hTable = hNode.getHTable(factory);
HTable parentHTable = hTable.getParentHNode().getHTable(factory);
newHNodeId = parentHTable.addHNode(newColumnName, HNode.HNodeType.Transformation, worksheet, factory).getId();
HNode newHNode = factory.getHNode(newHNodeId);
newColumnAbsoluteName = newHNode.getAbsoluteColumnName(factory);
List<Table> parentTables = new ArrayList<>();
CloneTableUtils.getDatatable(worksheet.getDataTable(), parentHTable, parentTables, selection);
for (Table parentTable : parentTables) {
for (Row parentRow : parentTable.getRows(0, parentTable.getNumRows(), selection)) {
interpreter.getLocals().__setitem__("nodeid", new PyString(parentRow.getNode(hTable.getParentHNode().getId()).getId()));
Table nestedTable = parentRow.getNode(hTable.getParentHNode().getId()).getNestedTable();
String instanceName = "aggregation" + System.currentTimeMillis();
interpreter.exec(instanceName + " = " + constructor);
if (nestedTable != null) {
for (Row nestedRow : nestedTable.getRows(0, nestedTable.getNumRows(), selection)) {
interpreter.getLocals().__setitem__("nodeid", new PyString(nestedRow.getNode(hNodeId).getId()));
interpreter.exec(String.format("%s.accumulate(%s.transform())", instanceName, instanceName));
}
}
interpreter.getLocals().__setitem__("nodeid", new PyString(parentRow.getNode(hTable.getParentHNode().getId()).getId()));
PyObject returnVal = interpreter.eval(String.format("%s.getResult()", instanceName));
parentRow.getNode(newHNodeId).setValue(PythonTransformationHelper.getPyObjectValueAsString(returnVal), Node.NodeStatus.original, factory);
}
}
UpdateContainer c = new UpdateContainer();
c.append(WorksheetUpdateFactory.createRegenerateWorksheetUpdates(worksheetId, selection, workspace.getContextId()));
c.append(computeAlignmentAndSemanticTypesAndCreateUpdates(workspace));
WorksheetUpdateFactory.detectSelectionStatusChange(worksheetId, workspace, this);
return c;
}
@Override
public UpdateContainer undoIt(Workspace workspace) {
RepFactory factory = workspace.getFactory();
HTable hTable = factory.getHNode(newHNodeId).getHTable(factory);
hTable.removeHNode(newHNodeId, factory.getWorksheet(worksheetId));
UpdateContainer c = new UpdateContainer();
c.append(WorksheetUpdateFactory.createRegenerateWorksheetUpdates(worksheetId, getSuperSelection(workspace), workspace.getContextId()));
c.append(computeAlignmentAndSemanticTypesAndCreateUpdates(workspace));
WorksheetUpdateFactory.detectSelectionStatusChange(worksheetId, workspace, this);
return c;
}
public void addInputColumns(String hNodeId) {
inputColumns.add(hNodeId);
}
}