/** * Copyright 2014 VU University Medical Center. * Licensed under the Apache License version 2.0 (see http://www.apache.org/licenses/LICENSE-2.0.html). */ package nl.vumc.biomedbridges.demonstration; import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.io.Files; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Random; import nl.vumc.biomedbridges.core.BaseWorkflow; import nl.vumc.biomedbridges.core.Constants; import nl.vumc.biomedbridges.core.FileUtils; import nl.vumc.biomedbridges.core.Workflow; import nl.vumc.biomedbridges.examples.RandomLinesExample; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This is a very simple implementation of the Workflow interface. * * @author <a href="mailto:f.debruijn@vumc.nl">Freek de Bruijn</a> */ public class DemonstrationWorkflow extends BaseWorkflow implements Workflow { /** * The logger for this class. */ private static final Logger logger = LoggerFactory.getLogger(DemonstrationWorkflow.class); /** * Create a demonstration workflow. * * @param name the workflow name. */ protected DemonstrationWorkflow(final String name) { super(name); } @Override public boolean run() throws IOException, InterruptedException { boolean result = false; if (Constants.CONCATENATE_WORKFLOW.equals(getName())) result = runConcatenateWorkflow(); else if (Constants.WORKFLOW_RANDOM_LINES_TWICE.equals(getName())) result = runRandomLinesWorkflow(); return result; } /** * Run the concatenate workflow. * * @return whether the workflow ran successfully. * @throws IOException if reading the workflow results fails. */ private boolean runConcatenateWorkflow() throws IOException { final Object input1 = getInput("WorkflowInput1"); final Object input2 = getInput("WorkflowInput2"); final boolean result = input1 instanceof File && input2 instanceof File; if (result) { final String inputString1 = Joiner.on("").join(Files.readLines((File) input1, Charsets.UTF_8)); final String inputString2 = Joiner.on("").join(Files.readLines((File) input2, Charsets.UTF_8)); logger.info("input 1: {}", inputString1); logger.info("input 2: {}", inputString2); addOutput("output", FileUtils.createOutputFile(this, inputString1, inputString2)); logger.info("output: {} {}", inputString1, inputString2); } else logger.error("Input parameters are not of the expected type (two input files where expected)."); return result; } /** * Run the random lines twice workflow. * * @return whether the workflow ran successfully. * @throws IOException if reading the workflow results fails. */ private boolean runRandomLinesWorkflow() throws IOException { final String inputName = "Input Dataset"; final Object input = getInput(inputName); final boolean result = input instanceof File; if (result) { final int stepId2 = 2; final int stepId3 = 3; final String numberOfLinesParameter = "num_lines"; final int initialLineCount = (int) getParameters().get(stepId2).get(numberOfLinesParameter); final int definitiveLineCount = (int) getParameters().get(stepId3).get(numberOfLinesParameter); final Random randomGenerator = new Random(123456); final List<String> lines = Files.readLines((File) input, Charsets.UTF_8); final List<String> selectedLines1 = selectRandomLines(lines, initialLineCount, randomGenerator); final List<String> selectedLines2 = selectRandomLines(selectedLines1, definitiveLineCount, randomGenerator); final String[] selectedLines2Array = selectedLines2.toArray(new String[selectedLines2.size()]); final File outputFile = FileUtils.createOutputFile(this, selectedLines2Array); addOutput(RandomLinesExample.OUTPUT_NAME, outputFile); logger.info("output: {}", selectedLines2); } else logger.error("Expected input file was not found."); return result; } /** * Select a number of random lines from the list of lines. If the number of lines to be selected is greater than or * equal to the total number of lines in the list, the entire list is returned. * * @param lines the list of lines. * @param lineCount the number of lines to select. * @param randomGenerator the random generator to use. * @return the randomly selected lines. */ private List<String> selectRandomLines(final List<String> lines, final int lineCount, final Random randomGenerator) { final List<String> selectedLines = new ArrayList<>(); final List<Integer> selectedIndices = new ArrayList<>(); if (lineCount >= lines.size()) selectedLines.addAll(lines); else while (selectedIndices.size() < lineCount) { final int selectedIndex = randomGenerator.nextInt(lines.size()); if (!selectedIndices.contains(selectedIndex)) { selectedIndices.add(selectedIndex); selectedLines.add(lines.get(selectedIndex)); } } return selectedLines; } }