SiLeBAT/FSK-Lab

View on GitHub
de.bund.bfr.knime.fsklab.nodes/src/de/bund/bfr/knime/fsklab/nodes/WorkflowReaderNodeModel.java

Summary

Maintainability
D
1 day
Test Coverage
/*
 ***************************************************************************************************
 * Copyright (c) 2017 Federal Institute for Risk Assessment (BfR), Germany
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program. If
 * not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors: Department Biological Safety - BfR
 *************************************************************************************************
 */
package de.bund.bfr.knime.fsklab.nodes;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.knime.core.data.DataTableSpec;
import org.knime.core.node.BufferedDataContainer;
import org.knime.core.node.BufferedDataTable;
import org.knime.core.node.ExecutionContext;
import org.knime.core.node.InvalidSettingsException;
import org.knime.core.node.NoInternalsModel;
import org.knime.core.node.NodeLogger;
import org.knime.core.node.NodeSettingsRO;
import org.knime.core.node.NodeSettingsWO;
import org.knime.core.node.port.PortObject;
import org.knime.core.node.port.PortObjectSpec;
import org.knime.core.node.port.PortType;
import org.knime.core.node.port.flowvariable.FlowVariablePortObject;
import org.knime.core.node.workflow.NodeContainer;
import org.knime.core.node.workflow.NodeContext;
import org.knime.core.node.workflow.NodeID;
import org.knime.core.node.workflow.NodeUIInformation;
import org.knime.core.node.workflow.WorkflowContext;
import org.knime.core.node.workflow.WorkflowCopyContent;
import org.knime.core.node.workflow.WorkflowLoadHelper;
import org.knime.core.node.workflow.WorkflowManager;
import org.knime.core.node.workflow.WorkflowPersistor.WorkflowLoadResult;
import org.knime.core.util.FileUtil;

class WorkflowReaderNodeModel extends NoInternalsModel {

  private static final PortType[] IN_TYPES = {};
  private static final PortType[] OUT_TYPES = {PortObject.TYPE, BufferedDataTable.TYPE};

  private static final NodeLogger LOGGER = NodeLogger.getLogger("Workflow Reader node");

  private final WorkflowReaderNodeSettings nodeSettings = new WorkflowReaderNodeSettings();

  public WorkflowReaderNodeModel() {
    super(IN_TYPES, OUT_TYPES);
  }

  @Override
  protected void saveSettingsTo(NodeSettingsWO settings) {
    nodeSettings.save(settings);
  }

  @Override
  protected void loadValidatedSettingsFrom(NodeSettingsRO settings)
      throws InvalidSettingsException {
    nodeSettings.load(settings);
  }

  @Override
  protected void validateSettings(NodeSettingsRO settings) throws InvalidSettingsException {
    // does nothing
  }

  @Override
  protected void reset() {}

  @Override
  protected PortObjectSpec[] configure(PortObjectSpec[] inSpecs) throws InvalidSettingsException {
    return new PortObjectSpec[] {};
  }

  @Override
  protected PortObject[] execute(PortObject[] inObjects, ExecutionContext exec) throws Exception {
    exec.setMessage("Reading subworkflow");
    final WorkflowContext origContext = NodeContext.getContext().getWorkflowManager().getContext();
    NodeContext nodeContext = NodeContext.getContext();
    Path tempDirWithPrefix = Files.createTempDirectory(nodeContext.getNodeContainer()
        .getNameWithID().toString().replaceAll("\\W", "").replace(" ", ""));

    FileUtil.unzip(new File(nodeSettings.filePath), tempDirWithPrefix.toFile());

    // reading the workflow from the temp folder
    WorkflowLoadResult result = WorkflowManager.loadProject(tempDirWithPrefix.toFile(), exec,
        new WorkflowLoadHelper(origContext));
    WorkflowManager embeddedSubWorkflowManager = result.getWorkflowManager();
    Collection<NodeContainer> nodeContainers = result.getLoadedInstance().getNodeContainers();
    // should always has one meta node
    if (nodeContainers.size() != 1) {
      throw new Exception("Not a valid file");
    }
    NodeContainer embeddedSubWorkflow = (NodeContainer) nodeContainers.toArray()[0];
    Map<NodeID, Object> ParentWorkflowsNodes =
        embeddedSubWorkflowManager.findNodes(Object.class, true);
    Set<NodeID> nodeIdKeySet = ParentWorkflowsNodes.keySet();

    List<NodeID> myList = new ArrayList<NodeID>();
    myList.addAll(nodeIdKeySet);

    // loads the loaded project content
    if (nodeSettings.loadedAsMetaNode) {
      WorkflowManager wfm = nodeContext.getWorkflowManager();
      WorkflowCopyContent.Builder orgContentBuilder = WorkflowCopyContent.builder();
      orgContentBuilder.setNodeIDs(embeddedSubWorkflow.getID());
      orgContentBuilder.setIncludeInOutConnections(true);
      WorkflowCopyContent copiedContent = wfm.copyFromAndPasteHere((WorkflowManager) embeddedSubWorkflowManager,
          orgContentBuilder.build());
     //shift the location
      NodeContainer nc = wfm.getNodeContainer(copiedContent.getNodeIDs()[0]);
      NodeUIInformation newUii =
          NodeUIInformation.builder().setNodeLocation(150, 150, 0, 0).build();
      nc.setUIInformation(newUii);
    } else {
      embeddedSubWorkflowManager.executeAllAndWaitUntilDone();
    }

    // result

    PortObject[] out = new PortObject[2];
    for (int i = 0; i < out.length; i++) {
      if (embeddedSubWorkflow.getOutPort(i).getPortObject() instanceof FlowVariablePortObject) {
        System.out.println("FlowVariablePortObject");
      } else if (embeddedSubWorkflow.getOutPort(i).getPortObject() instanceof BufferedDataTable) {
        out[1] = embeddedSubWorkflow.getOutPort(i).getPortObject();
      } else if (embeddedSubWorkflow.getOutPort(i).getPortObject() instanceof PortObject) {
        out[0] = embeddedSubWorkflow.getOutPort(i).getPortObject();
      }
    }
    
    // result
    for (int i = 0; i < out.length; i++) {
      if (out[i] == null) {
        System.out.println(out[i]);
        // the DataTableSpec of the final table
        DataTableSpec spec = new DataTableSpec();
        // init the container
        BufferedDataContainer container = exec.createDataContainer(spec);
        // finally close the container and get the result table.
        container.close();
        out[i] = container.getTable();
      }
    }

    return out;
  }
}