Package edu.isi.karma.controller.history

Source Code of edu.isi.karma.controller.history.WorksheetCommandHistoryExecutor

/*******************************************************************************
* Copyright 2012 University of Southern California
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This code was developed by the Information Integration Group as part
* of the Karma project at the Information Sciences Institute of the
* University of Southern California.  For more information, publications,
* and related projects, please see: http://www.isi.edu/integration
******************************************************************************/

package edu.isi.karma.controller.history;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.isi.karma.controller.command.Command;
import edu.isi.karma.controller.command.CommandException;
import edu.isi.karma.controller.command.CommandFactory;
import edu.isi.karma.controller.command.ICommand.CommandTag;
import edu.isi.karma.controller.history.CommandHistory.HistoryArguments;
import edu.isi.karma.controller.history.HistoryJsonUtil.ClientJsonKeys;
import edu.isi.karma.controller.history.HistoryJsonUtil.ParameterType;
import edu.isi.karma.controller.update.AbstractUpdate;
import edu.isi.karma.controller.update.TrivialErrorUpdate;
import edu.isi.karma.controller.update.UpdateContainer;
import edu.isi.karma.modeling.alignment.Alignment;
import edu.isi.karma.modeling.alignment.AlignmentManager;
import edu.isi.karma.rep.HNode;
import edu.isi.karma.rep.HNode.HNodeType;
import edu.isi.karma.rep.HTable;
import edu.isi.karma.rep.Workspace;
import edu.isi.karma.util.Util;
import edu.isi.karma.webserver.ExecutionController;
import edu.isi.karma.webserver.KarmaException;
import edu.isi.karma.webserver.WorkspaceRegistry;

public class WorksheetCommandHistoryExecutor {

  private final String worksheetId;
  private final Workspace workspace;

  private static Logger logger = LoggerFactory.getLogger(WorksheetCommandHistoryExecutor.class);
  private static String[] commandsIgnoreNodeBefore = { "AddColumnCommand",
    "SubmitPythonTransformationCommand"
  };

  public WorksheetCommandHistoryExecutor(String worksheetId, Workspace workspace) {
    super();
    this.worksheetId = worksheetId;
    this.workspace = workspace;
  }

  public UpdateContainer executeCommandsByTags(
      List<CommandTag> tags, JSONArray historyJson) throws JSONException,
      KarmaException, CommandException {
    JSONArray filteredCommands = HistoryJsonUtil.filterCommandsByTag(tags, historyJson);
    return executeAllCommands(filteredCommands);
  }
 
  public UpdateContainer executeAllCommands(JSONArray historyJson)
      throws JSONException, KarmaException, CommandException {
    UpdateContainer uc =new UpdateContainer();
    boolean saveToHistory = false;
   
    for (int i = 0; i< historyJson.length(); i++) {
      JSONObject commObject = (JSONObject) historyJson.get(i);
      if(i == historyJson.length() - 1) saveToHistory = true;
      UpdateContainer update = executeCommand(commObject, saveToHistory);
      if(update != null)
        uc.append(update);
    }
   
    Alignment alignment = AlignmentManager.Instance().getAlignment(workspace.getId(), worksheetId);
    if(alignment != null)
      alignment.align();
   
    return uc;
  }

  private UpdateContainer executeCommand(JSONObject commObject, boolean saveToHistory)
      throws JSONException, KarmaException, CommandException {
    ExecutionController ctrl = WorkspaceRegistry.getInstance().getExecutionController(workspace.getId());
    HashMap<String, CommandFactory> commandFactoryMap = ctrl.getCommandFactoryMap();

    JSONArray inputParamArr = (JSONArray) commObject.get(HistoryArguments.inputParameters.name());
    String commandName = (String)commObject.get(HistoryArguments.commandName.name());
    logger.info("Command in history: " + commandName);

    // Change the hNode ids, vworksheet id to point to the current worksheet ids
    try {
      UpdateContainer uc = normalizeCommandHistoryJsonInput(workspace, worksheetId, inputParamArr, commandName, true);
      // Invoke the command
      if (uc == null) {
        uc = new UpdateContainer();
      }
      CommandFactory cf = commandFactoryMap.get(commObject.get(HistoryArguments.commandName.name()));
      if(cf != null) {
        try { // This is sort of a hack the way I did this, but could not think of a better way to get rid of the dependency
          Command comm = cf.createCommand(inputParamArr, workspace);
          if(comm != null){
            try {
              comm.setExecutedInBatch(true);
              logger.info("Executing command: " + commandName);
              uc.append(workspace.getCommandHistory().doCommand(comm, workspace, saveToHistory));
              comm.setExecutedInBatch(false);
            } catch(Exception e) {
              logger.error("Error executing command: "+ commandName + ". Please notify this error");
              Util.logException(logger, e);
              //make these InfoUpdates so that the UI can still process the rest of the model
              return new UpdateContainer(new TrivialErrorUpdate("Error executing command " + commandName + " from history"));
            }
          }
          else {
            logger.error("Error occured while creating command (Could not create Command object): "
                + commObject.get(HistoryArguments.commandName.name()));
            return new UpdateContainer(new TrivialErrorUpdate("Error executing command " + commandName + " from history"));
          }
        } catch (UnsupportedOperationException ignored) {

        }
      }

      return uc;
    } catch(Exception e) {
      logger.error("Error executing command: "+ commandName + ".", e);
      //make these InfoUpdates so that the UI can still process the rest of the model
      return new UpdateContainer(new TrivialErrorUpdate("Error executing command " + commandName + " from history"));
    }
   
   
  }

  private boolean ignoreIfBeforeColumnDoesntExist(String commandName) {
    boolean ignore = false;
    for(String ignoreCom : commandsIgnoreNodeBefore) {
      if(commandName.equals(ignoreCom)) {
        ignore = true;
        break;
      }
    }
    return ignore;
  }

  public UpdateContainer normalizeCommandHistoryJsonInput(Workspace workspace, String worksheetId,
      JSONArray inputArr, String commandName, boolean addIfNonExist) throws JSONException {
    UpdateContainer uc = null;
    HTable hTable = workspace.getWorksheet(worksheetId).getHeaders();
    for (int i = 0; i < inputArr.length(); i++) {
      JSONObject inpP = inputArr.getJSONObject(i);
      if (inpP.getString(ClientJsonKeys.name.name()).equals("outputColumns") || inpP.getString(ClientJsonKeys.name.name()).equals("inputColumns"))
        continue;
      /*** Check the input parameter type and accordingly make changes ***/
      if(HistoryJsonUtil.getParameterType(inpP) == ParameterType.hNodeId) {
        JSONArray hNodeJSONRep = new JSONArray(inpP.get(ClientJsonKeys.value.name()).toString());
        for (int j=0; j<hNodeJSONRep.length(); j++) {
          JSONObject cNameObj = (JSONObject) hNodeJSONRep.get(j);
          if(hTable == null) {
            AbstractUpdate update = new TrivialErrorUpdate("null HTable while normalizing JSON input for the command " + commandName);
            if (uc == null)
              uc = new UpdateContainer(update);
            else
              uc.add(update);
            continue;
          }
          String nameObjColumnName = cNameObj.getString("columnName");
          logger.debug("Column being normalized: "+ nameObjColumnName);
          HNode node = hTable.getHNodeFromColumnName(nameObjColumnName);
          if(node == null) { //Because add column can happen even if the column after which it is to be added is not present
            AbstractUpdate update = new TrivialErrorUpdate(nameObjColumnName + " does not exist, using empty values");
            if (uc == null)
              uc = new UpdateContainer(update);
            else
              uc.add(update);
            if (addIfNonExist) {
              node = hTable.addHNode(nameObjColumnName, HNodeType.Regular, workspace.getWorksheet(worksheetId), workspace.getFactory());   
            }
            else {
              continue;
            }
          }

          if (j == hNodeJSONRep.length()-1) {    // Found!
            if(node != null)
              inpP.put(ClientJsonKeys.value.name(), node.getId());
            else {
              //Get the id of the last node in the table
              ArrayList<String> allNodeIds = hTable.getOrderedNodeIds();
              //TODO check for allNodeIds.size == 0
              String lastNodeId = allNodeIds.get(allNodeIds.size()-1);
              inpP.put(ClientJsonKeys.value.name(), lastNodeId);
            }
            hTable = workspace.
                getWorksheet(worksheetId).getHeaders();
          } else if(node != null) {
            hTable = node.getNestedTable();
            if (hTable == null && addIfNonExist) {
              hTable = node.addNestedTable("NestedTable", workspace.getWorksheet(worksheetId), workspace.getFactory());
            }
          }
        }
      } else if(HistoryJsonUtil.getParameterType(inpP) == ParameterType.worksheetId) {
        inpP.put(ClientJsonKeys.value.name(), worksheetId);
      } else if (HistoryJsonUtil.getParameterType(inpP) == ParameterType.hNodeIdList) {
        JSONArray hNodes = new JSONArray(inpP.get(ClientJsonKeys.value.name()).toString());
        for (int k = 0; k < hNodes.length(); k++) {
          JSONObject hnodeJSON = hNodes.getJSONObject(k);
          JSONArray hNodeJSONRep = new JSONArray(hnodeJSON.get(ClientJsonKeys.value.name()).toString());
          for (int j=0; j<hNodeJSONRep.length(); j++) {
            JSONObject cNameObj = (JSONObject) hNodeJSONRep.get(j);
            if(hTable == null) {
              AbstractUpdate update = new TrivialErrorUpdate("null HTable while normalizing JSON input for the command " + commandName);
              if (uc == null)
                uc = new UpdateContainer(update);
              else
                uc.add(update);
              continue;
            }
            String nameObjColumnName = cNameObj.getString("columnName");
            logger.debug("Column being normalized: "+ nameObjColumnName);
            HNode node = hTable.getHNodeFromColumnName(nameObjColumnName);
            if(node == null) { //Because add column can happen even if the column after which it is to be added is not present
              AbstractUpdate update = new TrivialErrorUpdate(nameObjColumnName + " does not exist, using empty values");
              if (uc == null)
                uc = new UpdateContainer(update);
              else
                uc.add(update);
              if (addIfNonExist) {
                hTable.addHNode(nameObjColumnName, HNodeType.Regular, workspace.getWorksheet(worksheetId), workspace.getFactory());
              }
              else {
                continue;
              }
            }

            if (j == hNodeJSONRep.length()-1) {    // Found!
              if(node != null)
                hnodeJSON.put(ClientJsonKeys.value.name(), node.getId());
              else {
                //Get the id of the last node in the table
                ArrayList<String> allNodeIds = hTable.getOrderedNodeIds();
                String lastNodeId = allNodeIds.get(allNodeIds.size()-1);
                hnodeJSON.put(ClientJsonKeys.value.name(), lastNodeId);
              }
              hTable = workspace.
                  getWorksheet(worksheetId).getHeaders();
            } else if(node != null) {
              hTable = node.getNestedTable();
              if (hTable == null && addIfNonExist) {
                hTable = node.addNestedTable("NestedTable", workspace.getWorksheet(worksheetId), workspace.getFactory());
              }
            }
          }
        }
        inpP.put(ClientJsonKeys.value.name(), hNodes.toString());
      }
      else if (HistoryJsonUtil.getParameterType(inpP) == ParameterType.orderedColumns) {
        JSONArray hNodes = new JSONArray(inpP.get(ClientJsonKeys.value.name()).toString());
        for (int k = 0; k < hNodes.length(); k++) {
          JSONObject hnodeJSON = hNodes.getJSONObject(k);
          JSONArray hNodeJSONRep = new JSONArray(hnodeJSON.get(ClientJsonKeys.id.name()).toString());
          processHNodeId(hNodeJSONRep, hTable, commandName, hnodeJSON);
          if (hnodeJSON.has(ClientJsonKeys.children.name())) {
            JSONArray children = new JSONArray(hnodeJSON.get(ClientJsonKeys.children.name()).toString());
            hnodeJSON.put(ClientJsonKeys.children.name(), processChildren(children, hTable, commandName));
          }

        }
        inpP.put(ClientJsonKeys.value.name(), hNodes.toString());
      }
    }
    AlignmentManager.Instance().getAlignmentOrCreateIt(workspace.getId(), worksheetId, workspace.getOntologyManager());
    return uc;
  }

  private boolean processHNodeId(JSONArray hNodeJSONRep, HTable hTable, String commandName, JSONObject hnodeJSON) {
    for (int j=0; j<hNodeJSONRep.length(); j++) {
      JSONObject cNameObj = (JSONObject) hNodeJSONRep.get(j);
      if(hTable == null) {
        return false;
      }
      String nameObjColumnName = cNameObj.getString("columnName");
      logger.debug("Column being normalized: "+ nameObjColumnName);
      HNode node = hTable.getHNodeFromColumnName(nameObjColumnName);
      if(node == null && !ignoreIfBeforeColumnDoesntExist(commandName)) { //Because add column can happen even if the column after which it is to be added is not present
        logger.info("null HNode " + nameObjColumnName + " while normalizing JSON input for the command " + commandName);
        return false;
      }

      if (j == hNodeJSONRep.length()-1) {    // Found!
        if(node != null)
          hnodeJSON.put(ClientJsonKeys.id.name(), node.getId());
        else {
          //Get the id of the last node in the table
          ArrayList<String> allNodeIds = hTable.getOrderedNodeIds();
          String lastNodeId = allNodeIds.get(allNodeIds.size()-1);
          hnodeJSON.put(ClientJsonKeys.id.name(), lastNodeId);
        }
        hTable = workspace.
            getWorksheet(worksheetId).getHeaders();
      } else if(node != null) {
        hTable = node.getNestedTable();
      }
    }
    return true;
  }
  private JSONArray processChildren(JSONArray children, HTable hTable, String commandName) {
    for (int i = 0; i < children.length(); i++) {
      JSONObject obj = children.getJSONObject(i);
      JSONArray array = new JSONArray(obj.get(ClientJsonKeys.id.name()).toString());
      processHNodeId(array, hTable, commandName, obj);
      if (obj.has(ClientJsonKeys.children.name())) {
        obj.put(ClientJsonKeys.children.name(), processChildren(new JSONArray(obj.get(ClientJsonKeys.children.name()).toString()), hTable, commandName));
      }
    }
    return children;
  }
}
TOP

Related Classes of edu.isi.karma.controller.history.WorksheetCommandHistoryExecutor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.