<commit_before>/** Workflows.java
 *
 * Copyright 2017 President and Fellows of Harvard College
 *
 * 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.
 */
package controllers;

import be.objectify.deadbolt.java.actions.Group;
import be.objectify.deadbolt.java.actions.Restrict;
import be.objectify.deadbolt.java.actions.SubjectPresent;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.typesafe.config.ConfigFactory;
import config.*;
import dao.UserAccessDao;
import dao.UserDao;
import dao.WorkflowDao;
import models.PackageData;
import models.db.user.User;
import models.db.user.UserUpload;
import models.db.workflow.ResultFile;
import models.db.workflow.Workflow;
import models.db.workflow.WorkflowResult;
import models.db.workflow.WorkflowRun;
import models.json.ArtifactDef;
import models.json.RunResult;
import models.json.WorkflowDefinition;
import org.apache.commons.io.FileUtils;
import org.kurator.akka.WorkflowConfig;
import org.kurator.akka.WorkflowRunner;
import org.kurator.akka.YamlStreamWorkflowRunner;
import org.restflow.yaml.spring.YamlBeanDefinitionReader;
import org.springframework.context.support.GenericApplicationContext;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Http;
import play.mvc.Result;
import ui.input.*;
import util.AsyncWorkflowRunnable;
import util.ClasspathStreamHandler;
import util.ConfigurableStreamHandlerFactory;
import util.WorkflowPackageVerifier;

import javax.inject.Singleton;
import java.io.*;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * This controller deals with actions related to running a workflow, uploading files, checking the status of a run, and
 * obtaining artifacts produced by the run.
 */
@Singleton
public class Workflows extends Controller {
    // Get jython home and path directories relative to the current directory
    private static final String JYTHON_HOME = new File("jython").getAbsolutePath();
    private static final String JYTHON_PATH = new File("packages").getAbsolutePath();

    // Get the workspace basedir relative to the current directory
    private static final String WORKSPACE_DIR = new File("workspace").getAbsolutePath();

    private final WorkflowDao workflowDao = new WorkflowDao();
    private final UserDao userDao = new UserDao();
    private final UserAccessDao userAccessDao = new UserAccessDao();

    // For handling classpath url scheme in workflows.conf files
    static {
        try {
            URL.setURLStreamHandlerFactory(new ConfigurableStreamHandlerFactory("classpath",
                    new ClasspathStreamHandler()));
        } catch (Error e) {
            // if the stream handler was already set ignore the "factory already defined" error
        }
    }

    /**
     * List the available workflows from config
     *
     * @return
     */
    public Result list(String search, String inputs, String dwcCls) {
        // TODO: use the filter criteria to determine which workflows are returned
        System.out.println(search + " " +  inputs + " " + dwcCls);

        //ObjectNode response = Json.newObject();

        //ArrayNode workflowsArray = response.putArray("workflows");

        ArrayNode response = Json.newArray();

        ConfigManager configManager = ConfigManager.getInstance();
        Collection<config.WorkflowConfig> workflows = configManager.getWorkflowConfigs();

        for (config.WorkflowConfig workflowConfig : workflows) {

            // Create the workflow list entry json
            ObjectNode workflowJson = Json.newObject();

            workflowJson.put("name", workflowConfig.getName());
            workflowJson.put("title", workflowConfig.getTitle());
            workflowJson.put("summary", workflowConfig.getSummary());
            workflowJson.put("documentation", workflowConfig.getDocumentation());

            // Add the list of dwc classes to an array
            ArrayNode classArray = workflowJson.putArray("class");

            for (String dwcClass : workflowConfig.getDwcClass()) {
                classArray.add(dwcClass);
            }

            // Add an entry for each workflow alternative
            ArrayNode alternativesArray = workflowJson.putArray("alternatives");

            for (WorkflowAlternativeConfig alternativeConfig : workflowConfig.getWorkflowAlternativeConfigs()) {

                ObjectNode alternativeJson = Json.newObject();

                // construct a title for this alternative
                alternativeJson.put("title", workflowConfig.getTitle());

                alternativeJson.put("name", alternativeConfig.getName());
                alternativeJson.put("instructions", alternativeConfig.getInstructions());

                alternativeJson.put("type", alternativeConfig.getInputType());
                alternativeJson.put("format", alternativeConfig.getInputFormat());

                ArrayNode parametersArray = alternativeJson.putArray("parameters");

                for (ParameterConfig parameterConfig : alternativeConfig.getParameters()) {
                    ObjectNode parametersJson = Json.newObject();

                    parametersJson.put("name", parameterConfig.getName());
                    parametersJson.put("type", parameterConfig.getType());
                    parametersJson.put("label", parameterConfig.getLabel());
                    parametersJson.put("description", parameterConfig.getDescription());

                    // If there are options (e.g. select form component, checkboxes, etc)
                    if (parameterConfig.getOptions() != null) {
                        ArrayNode optionsArray = parametersJson.putArray("options");

                        Map<String, Object> options = parameterConfig.getOptions();
                        for (String value : options.keySet()) {
                            String label = (String) options.get(value);

                            ObjectNode optionJson = Json.newObject();

                            optionJson.put("value", value);
                            optionJson.put("label",  label);

                            optionsArray.add(optionJson);
                        }
                    }

                    parametersArray.add(parametersJson);
                }

                alternativesArray.add(alternativeJson);
            }

            response.add(workflowJson);
        }

        return ok(response);
    }

    @Restrict({@Group("ADMIN")})
    public Result deletePackage(String name) {
        boolean success = ConfigManager.getInstance().deletePacakge(name);

        if (success) {
            flash("message", "Successfully deleted package " + name);
        } else {
            flash("error", "Unable to delete package " + name);
        }
        return redirect(routes.Workflows.deploy());
    }<commit_msg>Filter workflows in the backend controller and return result in array<commit_after>/** Workflows.java
 *
 * Copyright 2017 President and Fellows of Harvard College
 *
 * 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.
 */
package controllers;

import be.objectify.deadbolt.java.actions.Group;
import be.objectify.deadbolt.java.actions.Restrict;
import be.objectify.deadbolt.java.actions.SubjectPresent;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.typesafe.config.ConfigFactory;
import config.*;
import dao.UserAccessDao;
import dao.UserDao;
import dao.WorkflowDao;
import models.PackageData;
import models.db.user.User;
import models.db.user.UserUpload;
import models.db.workflow.ResultFile;
import models.db.workflow.Workflow;
import models.db.workflow.WorkflowResult;
import models.db.workflow.WorkflowRun;
import models.json.ArtifactDef;
import models.json.RunResult;
import models.json.WorkflowDefinition;
import org.apache.commons.io.FileUtils;
import org.kurator.akka.WorkflowConfig;
import org.kurator.akka.WorkflowRunner;
import org.kurator.akka.YamlStreamWorkflowRunner;
import org.restflow.yaml.spring.YamlBeanDefinitionReader;
import org.springframework.context.support.GenericApplicationContext;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Http;
import play.mvc.Result;
import ui.input.*;
import util.AsyncWorkflowRunnable;
import util.ClasspathStreamHandler;
import util.ConfigurableStreamHandlerFactory;
import util.WorkflowPackageVerifier;

import javax.inject.Singleton;
import java.io.*;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * This controller deals with actions related to running a workflow, uploading files, checking the status of a run, and
 * obtaining artifacts produced by the run.
 */
@Singleton
public class Workflows extends Controller {
    // Get jython home and path directories relative to the current directory
    private static final String JYTHON_HOME = new File("jython").getAbsolutePath();
    private static final String JYTHON_PATH = new File("packages").getAbsolutePath();

    // Get the workspace basedir relative to the current directory
    private static final String WORKSPACE_DIR = new File("workspace").getAbsolutePath();

    private final WorkflowDao workflowDao = new WorkflowDao();
    private final UserDao userDao = new UserDao();
    private final UserAccessDao userAccessDao = new UserAccessDao();

    // For handling classpath url scheme in workflows.conf files
    static {
        try {
            URL.setURLStreamHandlerFactory(new ConfigurableStreamHandlerFactory("classpath",
                    new ClasspathStreamHandler()));
        } catch (Error e) {
            // if the stream handler was already set ignore the "factory already defined" error
        }
    }

    /**
     * List the available workflows from config
     *
     * @return
     */
    public Result list(String search, String input, String dwcCls) {
        ArrayNode response = Json.newArray();

        ConfigManager configManager = ConfigManager.getInstance();
        Collection<config.WorkflowConfig> workflows = configManager.getWorkflowConfigs();

        for (config.WorkflowConfig workflowConfig : workflows) {
            // whether or not to include this workflow based on filter criteria
            boolean match = false;
            boolean hasDwcClass = false;
            boolean hasInputType = false;

            if (search == null || search.isEmpty()) {
                System.out.println("search is null");
                match = true;
            } else {
                // if a search term is provided as a parameter, check if the name of this workflow
                // contains the string
                match = workflowConfig.getTitle().toLowerCase().contains(search.toLowerCase());
            }

            if (dwcCls.equalsIgnoreCase("any")) {
                System.out.println("has dwc class: " + dwcCls);
                hasDwcClass = true;
            } else {
                // if a dwc class besides any is provided as a parameter, check if the workflow configuration
                // includes it
                for (String value : workflowConfig.getDwcClass()) {
                    if (value.equalsIgnoreCase(dwcCls)) {
                        hasDwcClass = true;
                    }
                }
            }

            // Create the workflow list entry json
            ObjectNode workflowJson = Json.newObject();

            workflowJson.put("name", workflowConfig.getName());
            workflowJson.put("title", workflowConfig.getTitle());
            workflowJson.put("summary", workflowConfig.getSummary());
            workflowJson.put("documentation", workflowConfig.getDocumentation());

            // Add the list of dwc classes to an array
            ArrayNode classArray = workflowJson.putArray("class");

            for (String dwcClass : workflowConfig.getDwcClass()) {
                classArray.add(dwcClass);
            }

            // Add an entry for each workflow alternative
            ArrayNode alternativesArray = workflowJson.putArray("alternatives");

            for (WorkflowAlternativeConfig alternativeConfig : workflowConfig.getWorkflowAlternativeConfigs()) {
                String inputType = alternativeConfig.getInputType();
                String inputFormat = alternativeConfig.getInputFormat();

                if (input.equalsIgnoreCase("any")) {
                    System.out.println("has input type: " + input);
                    hasInputType = true;
                } else {
                    // if an input type and/or darwin core class besides any is specified, check each
                    // alternative to see if it matches the filter criteria
                    hasInputType = hasInputType || inputType.equalsIgnoreCase(input);
                }

                ObjectNode alternativeJson = Json.newObject();

                // construct a title for this alternative
                alternativeJson.put("title", workflowConfig.getTitle());

                alternativeJson.put("name", alternativeConfig.getName());
                alternativeJson.put("instructions", alternativeConfig.getInstructions());

                alternativeJson.put("type", alternativeConfig.getInputType());
                alternativeJson.put("format", alternativeConfig.getInputFormat());

                ArrayNode parametersArray = alternativeJson.putArray("parameters");

                for (ParameterConfig parameterConfig : alternativeConfig.getParameters()) {
                    ObjectNode parametersJson = Json.newObject();

                    parametersJson.put("name", parameterConfig.getName());
                    parametersJson.put("type", parameterConfig.getType());
                    parametersJson.put("label", parameterConfig.getLabel());
                    parametersJson.put("description", parameterConfig.getDescription());

                    // If there are options (e.g. select form component, checkboxes, etc)
                    if (parameterConfig.getOptions() != null) {
                        ArrayNode optionsArray = parametersJson.putArray("options");

                        Map<String, Object> options = parameterConfig.getOptions();
                        for (String value : options.keySet()) {
                            String label = (String) options.get(value);

                            ObjectNode optionJson = Json.newObject();

                            optionJson.put("value", value);
                            optionJson.put("label",  label);

                            optionsArray.add(optionJson);
                        }
                    }

                    parametersArray.add(parametersJson);
                }

                alternativesArray.add(alternativeJson);
            }

            // Only include the workflows that satisfy filter criteria in the response
            if (match && hasDwcClass && hasInputType) {
                response.add(workflowJson);
            }
        }

        return ok(response);
    }

    @Restrict({@Group("ADMIN")})
    public Result deletePackage(String name) {
        boolean success = ConfigManager.getInstance().deletePacakge(name);

        if (success) {
            flash("message", "Successfully deleted package " + name);
        } else {
            flash("error", "Unable to delete package " + name);
        }
        return redirect(routes.Workflows.deploy());
    }
{'fraction_non_alphanumeric': 0.09085985919730429, 'fraction_numerical': 0.0009627534749383236, 'mean_word_length': 2.562700964630225, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4986249', 'n_tokens_mistral': 4160, 'n_tokens_neox': 3934, 'n_words': 1116}