diff --git a/coverage/src/test/java/Coverage/Coverage.java b/coverage/src/test/java/Coverage/Coverage.java index 06d65d3a8..86f1b0ac8 100644 --- a/coverage/src/test/java/Coverage/Coverage.java +++ b/coverage/src/test/java/Coverage/Coverage.java @@ -1,4 +1,4 @@ -package coverage; +package Coverage; import org.junit.jupiter.api.Test; diff --git a/vip-application-importer/src/main/java/fr/insalyon/creatis/vip/applicationimporter/client/view/applicationdisplay/DisplayTab.java b/vip-application-importer/src/main/java/fr/insalyon/creatis/vip/applicationimporter/client/view/applicationdisplay/DisplayTab.java index fab59f9e9..b8490a287 100644 --- a/vip-application-importer/src/main/java/fr/insalyon/creatis/vip/applicationimporter/client/view/applicationdisplay/DisplayTab.java +++ b/vip-application-importer/src/main/java/fr/insalyon/creatis/vip/applicationimporter/client/view/applicationdisplay/DisplayTab.java @@ -31,6 +31,9 @@ */ package fr.insalyon.creatis.vip.applicationimporter.client.view.applicationdisplay; +import java.util.HashSet; +import java.util.Set; + import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.widgets.Canvas; import com.smartgwt.client.widgets.IButton; @@ -39,6 +42,7 @@ import com.smartgwt.client.widgets.layout.HLayout; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.tab.Tab; + import fr.insalyon.creatis.vip.application.client.bean.boutiquesTools.BoutiquesApplication; import fr.insalyon.creatis.vip.application.client.view.boutiquesParsing.BoutiquesParser; import fr.insalyon.creatis.vip.application.client.view.boutiquesParsing.InvalidBoutiquesDescriptorException; @@ -49,6 +53,7 @@ import fr.insalyon.creatis.vip.core.client.view.layout.Layout; import fr.insalyon.creatis.vip.core.client.view.util.WidgetUtil; + public class DisplayTab extends Tab { // Layouts @@ -158,6 +163,34 @@ private static void verifyBoutiquesTool(BoutiquesApplication boutiquesTool) if (boutiquesTool.getAuthor() == null) { throw new ApplicationImporterException("Boutiques file must have an author"); } + checkvipdot(boutiquesTool); + } + + /** + * display warning message if any. + * + * @param application BoutiquesApplication object to cehck warning message + * @throws ApplicationImporterException + * **/ + private static void checkvipdot(BoutiquesApplication application) throws ApplicationImporterException { + Set commandLineFlags = application.getCommandLineFlag(); + Set vipDotInputIds = application.getVipDotInputIds(); + Set inputIds = application.getinputIds(); + Set commonValues = new HashSet<>(vipDotInputIds); + + commonValues.retainAll(commandLineFlags); + + if (!commonValues.isEmpty()) { + String warningMessage = "" + String.join(", ", commonValues) + " appears as command-line flag input(s), it should not be included in Dot iteration. Importing it may cause functionality issues, although the application will still be imported."; + Layout.getInstance().setWarningMessage(warningMessage); + } + // Check if all vipDotInputIds are in inputs + if (!inputIds.containsAll(vipDotInputIds)) { + Set incorrectInputs = new HashSet<>(vipDotInputIds); + incorrectInputs.removeAll(inputIds); + String errorMessage = "" + String.join(", ", incorrectInputs) + " appears in vipDotInputIds but not in inputs. Please ensure all ids are correct."; + throw new ApplicationImporterException(errorMessage); + } } /** diff --git a/vip-application-importer/src/main/java/fr/insalyon/creatis/vip/applicationimporter/client/view/applicationdisplay/GeneralLayout.java b/vip-application-importer/src/main/java/fr/insalyon/creatis/vip/applicationimporter/client/view/applicationdisplay/GeneralLayout.java index eeb7a190a..22f44a5d9 100644 --- a/vip-application-importer/src/main/java/fr/insalyon/creatis/vip/applicationimporter/client/view/applicationdisplay/GeneralLayout.java +++ b/vip-application-importer/src/main/java/fr/insalyon/creatis/vip/applicationimporter/client/view/applicationdisplay/GeneralLayout.java @@ -46,7 +46,8 @@ public class GeneralLayout extends AbstractFormLayout { version, schemaVersion, description, - vipContainer; + vipContainer, + dotInputs; public GeneralLayout(String width, String height) { super(width, height); @@ -63,8 +64,9 @@ public GeneralLayout(String width, String height) { schemaVersion = new LocalTextField("Schema Version", false, false); description = new LocalTextField("Description", false, false); vipContainer = new LocalTextField("VIP Container", false, false); + dotInputs = new LocalTextField("DOT Inputs", false, false); - this.addMembers(name, commandLine, dockerImage, dockerIndex, version, schemaVersion, description, vipContainer); + this.addMembers(name, commandLine, dockerImage, dockerIndex, version, schemaVersion, description, vipContainer, dotInputs); } public void setTool(BoutiquesApplication bt) { @@ -76,5 +78,7 @@ public void setTool(BoutiquesApplication bt) { dockerIndex.setValue(bt.getContainerIndex()); schemaVersion.setValue(bt.getSchemaVersion()); vipContainer.setValue(bt.getVipContainer()); + String dotInputsValue = String.join(", ", bt.getVipDotInputIds()); + dotInputs.setValue(dotInputsValue + (bt.getVipDotIncludesResultsDir() ? (dotInputsValue.isEmpty() ? "results-directory" : ", results-directory") : "")); } } diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/bean/boutiquesTools/BoutiquesApplication.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/bean/boutiquesTools/BoutiquesApplication.java index d2624347a..9f23c3723 100644 --- a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/bean/boutiquesTools/BoutiquesApplication.java +++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/bean/boutiquesTools/BoutiquesApplication.java @@ -1,5 +1,6 @@ package fr.insalyon.creatis.vip.application.client.bean.boutiquesTools; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -10,6 +11,8 @@ import com.google.gwt.user.client.rpc.IsSerializable; +import fr.insalyon.creatis.vip.application.client.bean.boutiquesTools.BoutiquesInput.InputType; + /** * Representation of an application Boutiques descriptor * @@ -38,6 +41,8 @@ public class BoutiquesApplication implements IsSerializable { private Set outputFiles = new HashSet<>(); private Map tags = new HashMap<>(); private String jsonFile; + private Set vipDotInputIds; + private boolean vipDotIncludesResultsDir; private BoutiquesApplicationExtensions boutiquesExtensions; @@ -229,6 +234,30 @@ public String getVipContainer() { return vipContainer; } + public Set getVipDotInputIds() { + if (vipDotInputIds == null) { + return Collections.emptySet(); + } + return vipDotInputIds; + } + + public Set getCommandLineFlag() { + return inputs.stream() + .filter(i -> InputType.FLAG.equals(i.getType())) + .map(BoutiquesInput::getId) + .collect(Collectors.toSet()); + } + + public Set getinputIds() { + return this.getInputs().stream() + .map(BoutiquesInput::getId) + .collect(Collectors.toSet()); + } + + public boolean getVipDotIncludesResultsDir() { + return vipDotIncludesResultsDir; + } + public void addInput(BoutiquesInput input){ this.inputs.add(input); } @@ -280,4 +309,12 @@ public void addTag(String key, String value) { public void setVipContainer(String vipContainer) { this.vipContainer = vipContainer; } -} \ No newline at end of file + + public void setVipDotInputIds(Set inputIds) { + this.vipDotInputIds = inputIds; + } + + public void setVipDotIncludesResultsDir(boolean vipDotIncludesResultsDir) { + this.vipDotIncludesResultsDir = vipDotIncludesResultsDir; + } +} diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/view/boutiquesParsing/BoutiquesParser.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/view/boutiquesParsing/BoutiquesParser.java index f46f0e8c4..400d40956 100644 --- a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/view/boutiquesParsing/BoutiquesParser.java +++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/view/boutiquesParsing/BoutiquesParser.java @@ -114,8 +114,9 @@ public BoutiquesApplication parseApplication(String descriptor) throws InvalidBo // Custom property JSONObject customObject = getObjectValue(parsedDescriptor, "custom", true); if (customObject != null) { - String vipImagePath = getStringValue(customObject, "vip:imagepath", true); - application.setVipContainer(vipImagePath); + application.setVipContainer(getStringValue(customObject, "vip:imagepath", true)); + application.setVipDotInputIds(getArrayValueAsStringSet(customObject, "vip:dot", true)); + application.setVipDotIncludesResultsDir(getBooleanValue(customObject, "vip:dot-with-results-directory", true)); } // Json descriptor application.setJsonFile(parsedDescriptor.toString()); @@ -241,6 +242,4 @@ private BoutiquesOutputFile parseBoutiquesOutputFile(JSONObject outputFile) bof.setCommandLineFlag(commandLineFlag); return bof; } - - } diff --git a/vip-portal/src/main/resources/vm/gwendia-standalone.vm b/vip-portal/src/main/resources/vm/gwendia-standalone.vm index 98400e423..603ea5e0f 100644 --- a/vip-portal/src/main/resources/vm/gwendia-standalone.vm +++ b/vip-portal/src/main/resources/vm/gwendia-standalone.vm @@ -71,14 +71,30 @@ if ( result.startsWith("/") || result.startsWith("lfn:") ) { #foreach( $output in $tool.getOutputFiles() ) #end - - + + +#if($tool.getVipDotInputIds() && !$tool.getVipDotInputIds().isEmpty()) + + #if($tools.getVipDotResultDirs) + #end + #foreach($dotInput in $tool.getVipDotInputIds()) + + #end + + #if( ! $tools.getVipDotResultDirs) + + #end +#else + +#end #foreach($input in $tool.getInputs()) - + #if(!$tool.getVipDotInputIds().contains($input.getId())) + + #end #end - - + + @@ -92,4 +108,4 @@ if ( result.startsWith("/") || result.startsWith("lfn:") ) { #end - + \ No newline at end of file