SiLeBAT/FSK-Lab

View on GitHub
de.bund.bfr.knime.fsklab.nodes/src/de/bund/bfr/knime/fsklab/v2_0/reader/ReaderNodeModel.java

Summary

Maintainability
A
35 mins
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.v2_0.reader;

import de.bund.bfr.knime.fsklab.v2_0.FskPortObject;
import de.bund.bfr.knime.fsklab.v2_0.FskPortObjectSpec;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import org.apache.commons.io.IOUtils;
import org.knime.core.node.ExecutionContext;
import org.knime.core.node.InvalidSettingsException;
import org.knime.core.node.NoInternalsModel;
import org.knime.core.node.NodeSettingsRO;
import org.knime.core.node.NodeSettingsWO;
import org.knime.core.node.defaultnodesettings.SettingsModelString;
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.util.CheckUtils;
import org.knime.core.node.workflow.NodeContext;
import org.knime.core.node.workflow.WorkflowContext;
import org.knime.core.node.workflow.WorkflowManager;
import org.knime.core.util.FileUtil;


public class ReaderNodeModel extends NoInternalsModel {

  private static final PortType[] IN_TYPES = {};
  private static final PortType[] OUT_TYPES = {FskPortObject.TYPE};

  static final String CFG_FILE = "filename";
  
  private final SettingsModelString filePath = new SettingsModelString(CFG_FILE, null);

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

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

  @Override
  protected void loadValidatedSettingsFrom(NodeSettingsRO settings)
      throws InvalidSettingsException {
    filePath.loadSettingsFrom(settings);
  }

  @Override
  protected void validateSettings(NodeSettingsRO settings) throws InvalidSettingsException {
    filePath.validateSettings(settings);
  }

  @Override
  protected void reset() {
    NodeContext nodeContext = NodeContext.getContext();
    WorkflowManager wfm = nodeContext.getWorkflowManager();
    WorkflowContext workflowContext = wfm.getContext();
    /*
     * find and delete only the working directory folder related to current reader node in the mean
     * that, we are not deleting folders which are representing the working directory of other
     * reader nodes which maybe exist in the same workflow
     */

    try {
      Files.walk(workflowContext.getCurrentLocation().toPath())
      .filter(path -> path.toString()
          .contains(nodeContext.getNodeContainer().getNameWithID().toString()
              .replaceAll("\\W", "").replace(" ", "") + "_" + "workingDirectory"))
      .sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(file -> {
        try {
          file.delete();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      });
    } catch (IOException e) {
      e.printStackTrace();
    }
    File fskxFile = new File(getDownloadedFilePath());
    if(fskxFile.exists())
      fskxFile.delete();
  }


  @Override
  protected PortObjectSpec[] configure(PortObjectSpec[] inSpecs) throws InvalidSettingsException {
    String warning = CheckUtils.checkSourceFile(filePath.getStringValue());
    if (warning != null) {
        setWarningMessage(warning);
    }
    return new PortObjectSpec[] {FskPortObjectSpec.INSTANCE};
  }

  @Override
  protected PortObject[] execute(PortObject[] inObjects, ExecutionContext exec) throws Exception {
    URL url = FileUtil.toURL(filePath.getStringValue());
    Path localPath = FileUtil.resolveToPath(url);

    FskPortObject inObject;

    if (localPath != null) {
      inObject = ReaderNodeUtil.readArchive(localPath.toFile());
    }
    // if path is an external URL the archive is downloaded to a file in the Workflow Temp Dir. and to be removed by node's reset.
    else {
      File fskxFile = new File(getDownloadedFilePath());
      try (
          InputStream inStream =
          FileUtil.openStreamWithTimeout(new URL(filePath.getStringValue()), 10000);
          OutputStream outStream = new FileOutputStream(fskxFile)) {
        IOUtils.copy(inStream, outStream);
        this.pushFlowVariableString("lokalModelPath", "knime://knime.workflow/" + fskxFile.getName());
      }

      
      inObject = ReaderNodeUtil.readArchive(fskxFile);
    }

    return new PortObject[] {inObject};
  }
  
  private String getDownloadedFilePath() {
    NodeContext nodeContext = NodeContext.getContext();
    WorkflowManager wfm = nodeContext.getWorkflowManager();
    WorkflowContext workflowContext = wfm.getContext();
    return workflowContext.getCurrentLocation().toPath() + File.separator + nodeContext.getNodeContainer().getNameWithID().toString()
        .replaceAll("\\W", "").replace(" ", "") + ".fskx";
  }
 
}