Skip to content

Commit

Permalink
Merge pull request #99 from sanctuuary/improve_api
Browse files Browse the repository at this point in the history
Improve API methods
  • Loading branch information
vedran-kasalica authored Nov 22, 2023
2 parents ef5f246 + a632bae commit fb468be
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 264 deletions.
12 changes: 2 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.sanctuuary</groupId>
<artifactId>APE</artifactId>
<version>2.2.1</version>
<version>2.2.4</version>
<packaging>jar</packaging>
<name>io.github.sanctuuary:APE</name>
<description>APE is a command line tool and an API for the automated exploration of possible computational pipelines (workflows) from large collections of computational tools.</description>
Expand Down Expand Up @@ -142,15 +142,7 @@
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.4.0</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<version>4.8.1.0</version>
</plugin>
</plugins>
</build>
Expand Down
23 changes: 13 additions & 10 deletions src/main/java/nl/uu/cs/ape/APE.java
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ public static boolean writeExecutableWorkflows(SolutionsList allSolutions) {
final File executeDir = executionsFolder.toFile();
if (executeDir.isDirectory()) {
// If the directory already exists, empty it first
deleteExistingFiles(executeDir, SolutionWorkflow.getFileNamePrefix());
deleteExistingFiles(executeDir, SolutionWorkflow.getFileNamePrefix(), "sh");
} else {
executeDir.mkdir();
}
Expand Down Expand Up @@ -480,7 +480,7 @@ public static boolean writeDataFlowGraphs(SolutionsList allSolutions, RankDir or
File graphDir = graphsFolder.toFile();
if (graphDir.isDirectory()) {
// If the directory already exists, empty it first
deleteExistingFiles(graphDir, SolutionWorkflow.getFileNamePrefix());
deleteExistingFiles(graphDir, SolutionWorkflow.getFileNamePrefix(), "png");
} else {
graphDir.mkdir();
}
Expand Down Expand Up @@ -539,7 +539,7 @@ public static boolean writeTavernaDesignGraphs(SolutionsList allSolutions, Forma
File graphDir = graphsFolder.toFile();
if (graphDir.isDirectory()) {
// If the directory already exists, empty it first
deleteExistingFiles(graphDir, SolutionWorkflow.getFileNamePrefix());
deleteExistingFiles(graphDir, SolutionWorkflow.getFileNamePrefix(), format.fileExtension);
} else {
graphDir.mkdir();
}
Expand Down Expand Up @@ -599,7 +599,7 @@ public static boolean writeControlFlowGraphs(SolutionsList allSolutions, RankDir
File graphDir = graphsFolder.toFile();
if (graphDir.isDirectory()) {
// If the directory already exists, empty it first
deleteExistingFiles(graphDir, SolutionWorkflow.getFileNamePrefix());
deleteExistingFiles(graphDir, SolutionWorkflow.getFileNamePrefix(), "png");
} else {
graphDir.mkdir();
}
Expand Down Expand Up @@ -648,7 +648,7 @@ public static boolean writeCWLWorkflows(SolutionsList allSolutions) {
final File cwlDir = cwlFolder.toFile();
if (cwlDir.isDirectory()) {
// If the directory already exists, empty it first
deleteExistingFiles(cwlDir, SolutionWorkflow.getFileNamePrefix());
deleteExistingFiles(cwlDir, SolutionWorkflow.getFileNamePrefix(), "cwl");
} else {
// Create the CWL directory if it does not already exist
cwlDir.mkdir();
Expand Down Expand Up @@ -686,14 +686,17 @@ public static boolean writeCWLWorkflows(SolutionsList allSolutions) {
}

/**
* Delete all files in the given directory that start with the given prefix.
* Delete all files in the given directory that start with the given prefix and
* have the given extension.
*
* @param dirName The directory to delete files from.
* @param filePrefix The prefix of the files to delete.
* @param dirName The directory to delete files from.
* @param filePrefix The prefix of the files to delete.
* @param fileExtension The extension of the files to delete.
*/
private static void deleteExistingFiles(File dirName, String filePrefix) {
private static void deleteExistingFiles(File dirName, String filePrefix, String fileExtension) {
File[] oldFiles = dirName
.listFiles((dir, fileName) -> fileName.toLowerCase().startsWith(filePrefix.toLowerCase()));
.listFiles((dir, fileName) -> fileName.toLowerCase().startsWith(filePrefix.toLowerCase())
&& fileName.toLowerCase().endsWith(fileExtension.toLowerCase()));
if (oldFiles != null) {
Arrays.stream(oldFiles).forEach(f -> {
try {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/nl/uu/cs/ape/models/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public Type getPlainType() {
public static Type taxonomyInstanceFromJson(JSONObject jsonParam, APEDomainSetup domainSetup, boolean isOutputData)
throws JSONException, APEDimensionsException {
/* Set of predicates where each describes a type dimension */
SortedSet<TaxonomyPredicate> parameterDimensions = new TreeSet<TaxonomyPredicate>();
SortedSet<TaxonomyPredicate> parameterDimensions = new TreeSet<>();
boolean labelDefined = false;
AllTypes allTypes = domainSetup.getAllTypes();
/* Iterate through each of the dimensions */
Expand All @@ -115,7 +115,7 @@ public static Type taxonomyInstanceFromJson(JSONObject jsonParam, APEDomainSetup
+ "', in JSON: '" + jsonParam + "'");
}
LogicOperation logConn = LogicOperation.OR;
SortedSet<TaxonomyPredicate> logConnectedPredicates = new TreeSet<TaxonomyPredicate>();
SortedSet<TaxonomyPredicate> logConnectedPredicates = new TreeSet<>();
/* for each dimensions a disjoint array of types/tools is given */
for (String currTypeLabel : APEUtils.getListFromJson(jsonParam, currRootLabel, String.class)) {
String currTypeIRI = currTypeLabel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public Graph addModuleToGraph(Graph workflowGraph) {
public Graph addTavernaStyleModuleToGraph(Graph workflowGraph) {
return workflowGraph
.with(node(getNodeID()).with(Style.FILLED, Color.rgb("F8FFB0").fill(),
Label.html(getNodeLabelHTML()), Shape.RECTANGLE));
Label.html(getNodeGraphLabel()), Shape.RECTANGLE));
}

/**
Expand All @@ -323,7 +323,7 @@ public String getNodeLabel() {
/**
* Get label of the current workflow node as an HTML element.
*/
public String getNodeLabelHTML() {
public String getNodeGraphLabel() {
return "<b>" + this.usedModule.getPredicateLabel() + "</b>";
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
package nl.uu.cs.ape.solver.solutionStructure;

import guru.nidi.graphviz.attribute.Color;
import guru.nidi.graphviz.attribute.Label;
import guru.nidi.graphviz.attribute.LinkAttr;
import guru.nidi.graphviz.attribute.Rank;
import guru.nidi.graphviz.attribute.Rank.RankDir;
import guru.nidi.graphviz.engine.Format;
import guru.nidi.graphviz.attribute.Shape;
import guru.nidi.graphviz.attribute.Style;
import guru.nidi.graphviz.model.Graph;
import lombok.Getter;
import nl.uu.cs.ape.automaton.Block;
import nl.uu.cs.ape.automaton.ModuleAutomaton;
Expand All @@ -28,14 +20,11 @@
import nl.uu.cs.ape.solver.solutionStructure.graphviz.SolutionGraphFactory;
import nl.uu.cs.ape.models.enums.AtomType;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static guru.nidi.graphviz.model.Factory.*;

/**
* The {@code SolutionWorkflow} class is used to represent a single workflow
* solution. The workflow consists of multiple instances of
Expand Down Expand Up @@ -322,6 +311,25 @@ public String getFileName() {
return String.format("%s%o", getFileNamePrefix(), getIndex());
}

public String getDescriptiveName() {
StringBuilder descrName = new StringBuilder();
this.moduleNodes.forEach(moduleNode -> descrName.append(moduleNode.toString()).append("->"));
descrName.delete(descrName.length() - 2, descrName.length());
return descrName.toString();
}

public String getDescription() {
StringBuilder descrName = new StringBuilder();
int stepNo = 1;
for (ModuleNode moduleNode : this.moduleNodes) {
descrName.append("Step ").append(stepNo++).append(": ").append(moduleNode.getUsedModule().getPredicateID())
.append("\n");
}
descrName.delete(descrName.length() - 2, descrName.length());
return descrName.toString();

}

/**
* Gets solution length.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import guru.nidi.graphviz.attribute.Label;
import guru.nidi.graphviz.attribute.Shape;
import guru.nidi.graphviz.attribute.Style;
import guru.nidi.graphviz.attribute.Label.Justification;
import guru.nidi.graphviz.model.Graph;
import lombok.extern.slf4j.Slf4j;
import nl.uu.cs.ape.automaton.State;
Expand Down Expand Up @@ -218,7 +219,7 @@ public Graph addTypeToGraph(Graph workflowGraph) {
public Graph addTavernaStyleTypeToGraph(Graph workflowGraph) {
return workflowGraph
.with(node(getNodeID()).with(Style.FILLED, Color.rgb("6CF1FF").fill(),
Label.html(getNodeLabelHTML()), Shape.RECTANGLE));
Label.lines(Justification.MIDDLE, getNodeGraphLabels()), Shape.RECTANGLE));
}

/**
Expand All @@ -244,21 +245,18 @@ public String getNodeLabel() {
/**
* Get label of the current workflow node as an HTML element.
*/
public String getNodeLabelHTML() {
StringBuilder printString = new StringBuilder("<b>");
public String[] getNodeGraphLabels() {
String[] labels = new String[this.usedTypes.size()];
int i = 0;
for (Type type : this.usedTypes) {
String typeLabel = type.getPredicateLabel();
if (typeLabel.endsWith("_p")) {
// remove "_plain" suffix
typeLabel = APEUtils.removeNLastChar(typeLabel, 2);
}
printString.append(typeLabel);
if (++i < this.usedTypes.size()) {
printString.append(",<br/> ");
}
labels[i++] = typeLabel;
}
return printString.append("</b>").toString();
return labels;
}

/**
Expand Down Expand Up @@ -320,6 +318,6 @@ public String getNodeLongLabel() {
* @return A short non descriptive node ID, that can be used as a variable name.
*/
public String getShortNodeID() {
return "node" + Math.abs(getNodeID().hashCode());
return "node" + getNodeID().hashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private void generateWorkflowInputs() {
cwlRepresentation.append("inputs:").append("\n");
// Inputs
for (TypeNode typeNode : solution.getWorkflowInputTypeStates()) {
String inputName = String.format("input%o", workflowParameters.size() + 1);
String inputName = String.format("input_%o", workflowParameters.size() + 1);
addParameter(typeNode, inputName);
cwlRepresentation
// Name
Expand Down Expand Up @@ -86,7 +86,7 @@ private void generateWorkflowOutputs() {
cwlRepresentation
// Name
.append(ind(1))
.append(String.format("output%o", i))
.append(String.format("output_%o", i))
.append(":\n")
// Data type
.append(ind(2))
Expand All @@ -107,7 +107,7 @@ private void generateWorkflowOutputs() {
int outId = typeNode.getCreatedByModule().getOutputTypes().get(i - 1).getAutomatonState()
.getLocalStateNumber();
cwlRepresentation
.append(inOutName(typeNode.getCreatedByModule(), "out", outId + 1))
.append(generateInputOrOutputName(typeNode.getCreatedByModule(), "out", outId + 1))
.append("\n");
i++;
}
Expand Down Expand Up @@ -164,7 +164,7 @@ private void generateStepIn(ModuleNode moduleNode) {
for (TypeNode typeNode : moduleNode.getInputTypes()) {
cwlRepresentation
.append(ind(baseInd + 1))
.append(inOutName(moduleNode, "in", i + 1))
.append(generateInputOrOutputName(moduleNode, "in", i + 1))
.append(": ")
.append(workflowParameters.get(typeNode.getNodeID()))
.append("\n");
Expand All @@ -187,7 +187,7 @@ private void generateStepOut(ModuleNode moduleNode) {
.append("[");
int i = 1;
for (TypeNode typeNode : moduleNode.getOutputTypes()) {
String name = inOutName(moduleNode, "out", i);
String name = generateInputOrOutputName(moduleNode, "out", i);
addParameter(typeNode, String.format("%s/%s", stepName(moduleNode), name));
cwlRepresentation
.append(name)
Expand Down Expand Up @@ -317,7 +317,7 @@ private void generateTypeNodes(ModuleNode moduleNode, List<TypeNode> typeNodeLis
cwlRepresentation
// Name
.append(ind(baseInd))
.append(inOutName(moduleNode, input ? "in" : "out", i))
.append(generateInputOrOutputName(moduleNode, input ? "in" : "out", i))
.append(":\n")
// Data type
.append(ind(baseInd + 1))
Expand All @@ -331,22 +331,6 @@ private void generateTypeNodes(ModuleNode moduleNode, List<TypeNode> typeNodeLis
}
}

/**
* Generate the name of the input or output of a step's run input or output.
* I.e. "moduleName_indicator_n".
*
* @param moduleNode The {@link ModuleNode} that is the workflow step.
* @param indicator Indicator whether it is an input or an output.
* @param n The n-th input or output this is.
* @return The name of the input or output.
*/
private String inOutName(ModuleNode moduleNode, String indicator, int n) {
return String.format("%s_%s_%o",
moduleNode.getNodeLabel(),
indicator,
n);
}

/**
* Add a parameter to the parameter hashmap.
* Will log an error to the error output if {@link TypeNode} is already known.
Expand All @@ -356,18 +340,8 @@ private String inOutName(ModuleNode moduleNode, String indicator, int n) {
*/
private void addParameter(TypeNode typeNode, String name) {
if (workflowParameters.putIfAbsent(typeNode.getNodeID(), name) != null) {
log.warn("Duplicate key \"{}\" in workflow inputs!\n", typeNode.getNodeID());
log.warn("Duplicate key \"%s\" in workflow inputs!\n", typeNode.getNodeID());
}
}

/**
* Generate the name for a step in the workflow.
*
* @param moduleNode The {@link ModuleNode} that is the workflow step.
* @return The name of the workflow step.
*/
private String stepName(ModuleNode moduleNode) {
return moduleNode.getUsedModule().getPredicateLabel() +
moduleNode.getAutomatonState().getLocalStateNumber();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,37 @@ private void generateDoc() {
cwlRepresentation.append(".").append("\n").append("\n");
}

/**
* Generate the name of the input or output of a step's run input or output.
* I.e. "moduleName_indicator_n".
*
* @param moduleNode The {@link ModuleNode} that is the workflow step.
* @param indicator Indicator whether it is an input or an output.
* @param n The n-th input or output this is.
* @return The name of the input or output.
*/
protected String generateInputOrOutputName(ModuleNode moduleNode, String indicator, int n) {
return String.format("%s_%s_%o",
moduleNode.getNodeLabel(),
indicator,
n);
}

/**
* Generate the name for a step in the workflow.
*
* @param moduleNode The {@link ModuleNode} that is the workflow step.
* @return The name of the workflow step.
*/
protected String stepName(ModuleNode moduleNode) {
int stepNumber = moduleNode.getAutomatonState().getLocalStateNumber();
if (stepNumber < 10) {
return String.format("%s_0%o", moduleNode.getUsedModule().getPredicateLabel(), stepNumber);
} else {
return String.format("%s_%o", moduleNode.getUsedModule().getPredicateLabel(), stepNumber);
}
}

/**
* Generate the main part of the CWL representation.
*/
Expand Down
Loading

0 comments on commit fb468be

Please sign in to comment.