From b7a5a76b9cfec71cd127c92c5d15b9c0911e26ce Mon Sep 17 00:00:00 2001 From: lkisac Date: Thu, 22 Jan 2015 10:51:42 -0500 Subject: [PATCH 1/7] added functionality to store all multi-level multi selected values --- .../ExtendedChoiceParameterDefinition.java | 37 ++++++++++++++++++- .../ExtendedChoiceParameterValue.java | 16 +++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java index a3846766..f7778715 100644 --- a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java +++ b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java @@ -1,4 +1,5 @@ /* + *Copyright (c) 2015 Len Isac *Copyright (c) 2013 Costco, Vimil Saju *Copyright (c) 2013 John DiMatteo *See the file license.txt for copying permission. @@ -228,7 +229,11 @@ else if(value == 1) { private String type; private String value; + + private transient int multiSelectTotal = 0; + private transient Map allCols = new HashMap(); + private String propertyFile; private String groovyScript; @@ -322,6 +327,7 @@ public ParameterValue createValue(CLICommand command, String value) throws IOExc String valueStr = getEffectiveValue(); if(valueStr != null) { List result = new ArrayList(); + Map> allCols = new HashMap>(); String[] values = valueStr.split(","); Set valueSet = new HashSet(); @@ -345,34 +351,61 @@ public ParameterValue createValue(CLICommand command, String value) throws IOExc public ParameterValue createValue(StaplerRequest request, JSONObject jO) { Object value = jO.get("value"); String strValue = ""; + Map allCols = new HashMap(); + if(value instanceof String) { strValue = (String)value; } else if(value instanceof JSONArray) { + int multiLevelColumns = 0; JSONArray jsonValues = (JSONArray)value; if(type.equals(PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT) || type.equals(PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT)) { final int valuesBetweenLevels = this.value.split(",").length; - + multiLevelColumns = valuesBetweenLevels; + Iterator it = jsonValues.iterator(); for(int i = 1; it.hasNext(); i++) { String nextValue = it.next().toString(); + this.multiSelectTotal = i; + + allCols.put(i, nextValue); + if(i % valuesBetweenLevels == 0) { if(strValue.length() > 0) { strValue += getMultiSelectDelimiter(); } strValue += nextValue; } + this.allCols = allCols; } } else { strValue = StringUtils.join(jsonValues.iterator(), getMultiSelectDelimiter()); } + + // Concatenate all multi-select values into one string + strValue = ""; + StringBuilder strCols = new StringBuilder(); + for (int eachSelect = 1, col = 1, row = 1; eachSelect <= this.multiSelectTotal; eachSelect++, col++) { + if (col == 1) { // 1st column + strCols.append(row).append(":").append(this.allCols.get(eachSelect)).append(","); + } + else if ((eachSelect % multiLevelColumns) == 0) { // last column + strCols.append(this.allCols.get(eachSelect)).append(":"); + col = 0; + row++; + } + else { // columns in between + strCols.append(this.allCols.get(eachSelect)).append(","); + } + } + strValue = strCols.toString(); } if(quoteValue) { strValue = "\"" + strValue + "\""; } - return new ExtendedChoiceParameterValue(getName(), strValue); + return new ExtendedChoiceParameterValue(getName(), strValue, multiSelectTotal, allCols); } @Override diff --git a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java index e1ab4926..6cc839ed 100644 --- a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java +++ b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java @@ -1,4 +1,5 @@ /* + *Copyright (c) 2015 Len Isac *Copyright (c) 2013 Costco, Vimil Saju *See the file license.txt for copying permission. */ @@ -8,14 +9,27 @@ import org.kohsuke.stapler.DataBoundConstructor; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.List; + import hudson.model.StringParameterValue; public class ExtendedChoiceParameterValue extends StringParameterValue{ private static final long serialVersionUID = 7993744779892775177L; + private Map allCols; + private Map> allColsList; + private int multiLevelColumns; @DataBoundConstructor public ExtendedChoiceParameterValue(String name, String value) { super(name, value); } - + + public ExtendedChoiceParameterValue(String name, String value, + int multiLevelColumns, Map allCols) { + super(name, value); + this.allCols = allCols; + this.multiLevelColumns = multiLevelColumns; + } } From 899c4774cbf1256acd31f1a6a9436f97d0115982 Mon Sep 17 00:00:00 2001 From: lkisac Date: Mon, 23 Feb 2015 15:38:34 -0500 Subject: [PATCH 2/7] integrated RebuildParameterProvider extension for rebuild plugin compatibility 1. added rebuild dependency to pom 2. created ExtendedChoiceRebuildParameterProvider class (extends RebuildParameterProvider) 3. ExtendedChoiceParameterValue - get/set methods --- .gitignore | 6 +++- pom.xml | 6 ++++ .../ExtendedChoiceParameterDefinition.java | 1 - .../ExtendedChoiceParameterValue.java | 30 +++++++++++++++--- ...xtendedChoiceRebuildParameterProvider.java | 31 +++++++++++++++++++ 5 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceRebuildParameterProvider.java diff --git a/.gitignore b/.gitignore index 3f29f5da..8aca4ffd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ /target/ -/work/ \ No newline at end of file +/work/ +/classes/ +.project +.classpath +.settings/ \ No newline at end of file diff --git a/pom.xml b/pom.xml index 10088f57..eced6f1c 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,12 @@ opencsv 2.0 + + com.sonyericsson.hudson.plugins.rebuild + rebuild + 1.21 + true + diff --git a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java index f7778715..d70e780e 100644 --- a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java +++ b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java @@ -1,5 +1,4 @@ /* - *Copyright (c) 2015 Len Isac *Copyright (c) 2013 Costco, Vimil Saju *Copyright (c) 2013 John DiMatteo *See the file license.txt for copying permission. diff --git a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java index 6cc839ed..04e0339c 100644 --- a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java +++ b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java @@ -1,5 +1,4 @@ /* - *Copyright (c) 2015 Len Isac *Copyright (c) 2013 Costco, Vimil Saju *See the file license.txt for copying permission. */ @@ -9,17 +8,16 @@ import org.kohsuke.stapler.DataBoundConstructor; -import java.util.LinkedHashMap; import java.util.Map; import java.util.List; import hudson.model.StringParameterValue; -public class ExtendedChoiceParameterValue extends StringParameterValue{ +public class ExtendedChoiceParameterValue extends StringParameterValue { private static final long serialVersionUID = 7993744779892775177L; private Map allCols; private Map> allColsList; - private int multiLevelColumns; + private int multiLevelColumns; @DataBoundConstructor public ExtendedChoiceParameterValue(String name, String value) { @@ -29,7 +27,31 @@ public ExtendedChoiceParameterValue(String name, String value) { public ExtendedChoiceParameterValue(String name, String value, int multiLevelColumns, Map allCols) { super(name, value); + this.setAllCols(allCols); + this.setMultiLevelColumns(multiLevelColumns); + } + + public Map getAllCols() { + return allCols; + } + + public void setAllCols(Map allCols) { this.allCols = allCols; + } + + public Map> getAllColsList() { + return allColsList; + } + + public void setAllColsList(Map> allColsList) { + this.allColsList = allColsList; + } + + public int getMultiLevelColumns() { + return multiLevelColumns; + } + + public void setMultiLevelColumns(int multiLevelColumns) { this.multiLevelColumns = multiLevelColumns; } } diff --git a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceRebuildParameterProvider.java b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceRebuildParameterProvider.java new file mode 100644 index 00000000..39ab8131 --- /dev/null +++ b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceRebuildParameterProvider.java @@ -0,0 +1,31 @@ +/* + *Copyright (c) 2015 Len Isac + *See the file license.txt for copying permission. + */ +package com.cwctravel.hudson.plugins.extended_choice_parameter; + +import hudson.Extension; +import hudson.model.ParameterValue; + +import com.sonyericsson.rebuild.RebuildParameterPage; +import com.sonyericsson.rebuild.RebuildParameterProvider; + +/** + * An extension class to inject {@link ExtendedChoiceParameterValue} to rebuild-plugin. + */ +@Extension(optional = true) +public class ExtendedChoiceRebuildParameterProvider extends RebuildParameterProvider { + /** + * @param value + * @return + * @see com.sonyericsson.rebuild.RebuildParameterProvider#getRebuildPage(hudson.model.ParameterValue) + */ + @Override + public RebuildParameterPage getRebuildPage(ParameterValue value) { + if (value instanceof ExtendedChoiceParameterValue) { + return new RebuildParameterPage(ExtendedChoiceParameterValue.class, "rebuild.groovy"); + } + + return null; + } +} From cfed87d2f1a7ca7af7626c5bc28eb7e4ced105c4 Mon Sep 17 00:00:00 2001 From: lkisac Date: Wed, 25 Feb 2015 14:57:06 -0500 Subject: [PATCH 3/7] added to .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3f29f5da..bb105306 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ /target/ -/work/ \ No newline at end of file +/work/ +.classpath +.project +classes/ \ No newline at end of file From bd715d00e8e0de7008db625815025cfba48e99fb Mon Sep 17 00:00:00 2001 From: lkisac Date: Wed, 25 Feb 2015 15:04:39 -0500 Subject: [PATCH 4/7] removed unnecessary class members, so no RebuildParameterProvider extension required --- .../ExtendedChoiceParameterDefinition.java | 3 +-- .../ExtendedChoiceParameterValue.java | 17 +---------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java index f7778715..113c6b35 100644 --- a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java +++ b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java @@ -327,7 +327,6 @@ public ParameterValue createValue(CLICommand command, String value) throws IOExc String valueStr = getEffectiveValue(); if(valueStr != null) { List result = new ArrayList(); - Map> allCols = new HashMap>(); String[] values = valueStr.split(","); Set valueSet = new HashSet(); @@ -405,7 +404,7 @@ else if ((eachSelect % multiLevelColumns) == 0) { // last column if(quoteValue) { strValue = "\"" + strValue + "\""; } - return new ExtendedChoiceParameterValue(getName(), strValue, multiSelectTotal, allCols); + return new ExtendedChoiceParameterValue(getName(), strValue); } @Override diff --git a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java index 6cc839ed..a48c80e8 100644 --- a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java +++ b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterValue.java @@ -1,5 +1,4 @@ /* - *Copyright (c) 2015 Len Isac *Copyright (c) 2013 Costco, Vimil Saju *See the file license.txt for copying permission. */ @@ -9,27 +8,13 @@ import org.kohsuke.stapler.DataBoundConstructor; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.List; - import hudson.model.StringParameterValue; public class ExtendedChoiceParameterValue extends StringParameterValue{ private static final long serialVersionUID = 7993744779892775177L; - private Map allCols; - private Map> allColsList; - private int multiLevelColumns; @DataBoundConstructor public ExtendedChoiceParameterValue(String name, String value) { super(name, value); - } - - public ExtendedChoiceParameterValue(String name, String value, - int multiLevelColumns, Map allCols) { - super(name, value); - this.allCols = allCols; - this.multiLevelColumns = multiLevelColumns; - } + } } From 2eb7a11e3ff1c6ecc08ece481718bec820188170 Mon Sep 17 00:00:00 2001 From: lkisac Date: Thu, 26 Feb 2015 13:22:21 -0500 Subject: [PATCH 5/7] fixed conflict in .gitignore --- .gitignore | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 5f50cfb5..0e63ad86 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,7 @@ /target/ /work/ -<<<<<<< HEAD /classes/ .project .classpath .settings/ -======= -.classpath -.project -classes/ ->>>>>>> len-storeMultipleValues2 + From 82daa12695942a5c5c6954aeb6fab0f027c111aa Mon Sep 17 00:00:00 2001 From: lkisac Date: Thu, 26 Feb 2015 14:01:49 -0500 Subject: [PATCH 6/7] updated pom Jenkins version to 1.580.1 LTS release --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 10088f57..5084ec42 100644 --- a/pom.xml +++ b/pom.xml @@ -3,8 +3,8 @@ org.jenkins-ci.plugins plugin - 1.466 - + 1.580.1 + From e2e7a3f4419617d63c78aacac9a4a30249ac0ba1 Mon Sep 17 00:00:00 2001 From: lkisac Date: Wed, 15 Apr 2015 09:57:45 -0400 Subject: [PATCH 7/7] added comment for createValue method --- .../ExtendedChoiceParameterDefinition.java | 1591 +++++++++-------- 1 file changed, 798 insertions(+), 793 deletions(-) diff --git a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java index 8cd13f4c..214c4ec5 100644 --- a/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java +++ b/src/main/java/com/cwctravel/hudson/plugins/extended_choice_parameter/ExtendedChoiceParameterDefinition.java @@ -1,793 +1,798 @@ -/* - *Copyright (c) 2013 Costco, Vimil Saju - *Copyright (c) 2013 John DiMatteo - *See the file license.txt for copying permission. - */ - -package com.cwctravel.hudson.plugins.extended_choice_parameter; - -import groovy.lang.GroovyShell; -import hudson.Extension; -import hudson.Util; -import hudson.cli.CLICommand; -import hudson.model.ParameterValue; -import hudson.model.ParameterDefinition; -import hudson.util.FormValidation; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.servlet.ServletException; - -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; - -import org.apache.commons.lang.StringUtils; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.Property; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; - -import au.com.bytecode.opencsv.CSVReader; - -public class ExtendedChoiceParameterDefinition extends ParameterDefinition { - private static final long serialVersionUID = -2946187268529865645L; - - public static final String PARAMETER_TYPE_SINGLE_SELECT = "PT_SINGLE_SELECT"; - - public static final String PARAMETER_TYPE_MULTI_SELECT = "PT_MULTI_SELECT"; - - public static final String PARAMETER_TYPE_CHECK_BOX = "PT_CHECKBOX"; - - public static final String PARAMETER_TYPE_RADIO = "PT_RADIO"; - - public static final String PARAMETER_TYPE_TEXT_BOX = "PT_TEXTBOX"; - - public static final String PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT = "PT_MULTI_LEVEL_SINGLE_SELECT"; - - public static final String PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT = "PT_MULTI_LEVEL_MULTI_SELECT"; - - @Extension - public static class DescriptorImpl extends ParameterDescriptor { - @Override - public String getDisplayName() { - return Messages.ExtendedChoiceParameterDefinition_DisplayName(); - } - - public FormValidation doCheckPropertyFile(@QueryParameter final String propertyFile, @QueryParameter final String propertyKey, - @QueryParameter final String type) throws IOException, ServletException { - if(StringUtils.isBlank(propertyFile)) { - return FormValidation.ok(); - } - - Project project = new Project(); - Property property = new Property(); - property.setProject(project); - - File prop = new File(propertyFile); - try { - if(prop.exists()) { - property.setFile(prop); - } - else { - URL propertyFileUrl = new URL(propertyFile); - property.setUrl(propertyFileUrl); - } - property.execute(); - } - catch(Exception e) { - return FormValidation.warning(Messages.ExtendedChoiceParameterDefinition_PropertyFileDoesntExist(), propertyFile); - } - - if(PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT.equals(type) || PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT.equals(type)) { - return FormValidation.ok(); - } - else if(StringUtils.isNotBlank(propertyKey)) { - if(project.getProperty(propertyKey) != null) { - return FormValidation.ok(); - } - else { - return FormValidation.warning(Messages.ExtendedChoiceParameterDefinition_PropertyFileExistsButProvidedKeyIsInvalid(), propertyFile, propertyKey); - } - } - else { - return FormValidation.warning(Messages.ExtendedChoiceParameterDefinition_PropertyFileExistsButNoProvidedKey(), propertyFile); - } - } - - public FormValidation doCheckPropertyKey(@QueryParameter final String propertyFile, @QueryParameter final String propertyKey, - @QueryParameter final String type) throws IOException, ServletException { - return doCheckPropertyFile(propertyFile, propertyKey, type); - } - - public FormValidation doCheckDefaultPropertyFile(@QueryParameter final String defaultPropertyFile, - @QueryParameter final String defaultPropertyKey, @QueryParameter final String type) throws IOException, ServletException { - return doCheckPropertyFile(defaultPropertyFile, defaultPropertyKey, type); - } - - public FormValidation doCheckDefaultPropertyKey(@QueryParameter final String defaultPropertyFile, - @QueryParameter final String defaultPropertyKey, @QueryParameter final String type) throws IOException, ServletException { - return doCheckPropertyFile(defaultPropertyFile, defaultPropertyKey, type); - } - - @Override - public ExtendedChoiceParameterDefinition newInstance(StaplerRequest req, JSONObject formData) throws FormException { - String name = null; - String type = null; - String description = null; - String multiSelectDelimiter = null; - boolean quoteValue = false; - int visibleItemCount = 5; - - String propertyValue = null; - String propertyKey = null; - String propertyFile = null; - String groovyScript = null; - String groovyScriptFile = null; - String bindings = null; - - String defaultPropertyValue = null; - String defaultPropertyKey = null; - String defaultPropertyFile = null; - String defaultGroovyScript = null; - String defaultGroovyScriptFile = null; - String defaultBindings = null; - - name = formData.getString("name"); - description = formData.getString("description"); - - JSONObject parameterGroup = formData.getJSONObject("parameterGroup"); - if(parameterGroup != null) { - int value = parameterGroup.getInt("value"); - if(value == 0) { - type = parameterGroup.getString("type"); - quoteValue = parameterGroup.getBoolean("quoteValue"); - visibleItemCount = parameterGroup.optInt("visibleItemCount", 5); - multiSelectDelimiter = parameterGroup.getString("multiSelectDelimiter"); - if(StringUtils.isEmpty(multiSelectDelimiter)) { - multiSelectDelimiter = ","; - } - - JSONObject propertySourceJSON = (JSONObject)parameterGroup.get("propertySource"); - if(propertySourceJSON != null) { - if(propertySourceJSON.getInt("value") == 0) { - propertyValue = propertySourceJSON.getString("propertyValue"); - } - else if(propertySourceJSON.getInt("value") == 1) { - propertyFile = propertySourceJSON.getString("propertyFile"); - propertyKey = propertySourceJSON.getString("propertyKey"); - } - else if(propertySourceJSON.getInt("value") == 2) { - groovyScript = propertySourceJSON.getString("groovyScript"); - bindings = propertySourceJSON.getString("bindings"); - } - else if(propertySourceJSON.getInt("value") == 3) { - groovyScriptFile = propertySourceJSON.getString("groovyScriptFile"); - bindings = propertySourceJSON.getString("bindings"); - } - } - - JSONObject defaultPropertySourceJSON = (JSONObject)parameterGroup.get("defaultPropertySource"); - if(defaultPropertySourceJSON != null) { - if(defaultPropertySourceJSON.getInt("value") == 0) { - defaultPropertyValue = defaultPropertySourceJSON.getString("defaultPropertyValue"); - } - else if(defaultPropertySourceJSON.getInt("value") == 1) { - defaultPropertyFile = defaultPropertySourceJSON.getString("defaultPropertyFile"); - defaultPropertyKey = defaultPropertySourceJSON.getString("defaultPropertyKey"); - } - else if(defaultPropertySourceJSON.getInt("value") == 2) { - defaultGroovyScript = defaultPropertySourceJSON.getString("defaultGroovyScript"); - defaultBindings = defaultPropertySourceJSON.getString("defaultBindings"); - } - else if(defaultPropertySourceJSON.getInt("value") == 3) { - defaultGroovyScriptFile = defaultPropertySourceJSON.getString("defaultGroovyScriptFile"); - defaultBindings = defaultPropertySourceJSON.getString("defaultBindings"); - } - } - } - else if(value == 1) { - type = parameterGroup.getString("type"); - propertyFile = parameterGroup.getString("propertyFile"); - propertyValue = parameterGroup.optString("propertyValue"); - } - } - else { - type = formData.getString("type"); - propertyFile = formData.getString("propertyFile"); - propertyKey = formData.getString("propertyKey"); - propertyValue = formData.optString("value"); - defaultPropertyFile = formData.optString("defaultPropertyFile"); - defaultPropertyKey = formData.optString("defaultPropertyKey"); - defaultPropertyValue = formData.optString("defaultValue"); - } - - return new ExtendedChoiceParameterDefinition(name, type, propertyValue, propertyFile, groovyScript, groovyScriptFile, bindings, propertyKey, defaultPropertyValue, defaultPropertyFile, defaultGroovyScript, defaultGroovyScriptFile, defaultBindings, defaultPropertyKey, quoteValue, visibleItemCount, description, multiSelectDelimiter); - } - } - - private boolean quoteValue; - - private int visibleItemCount; - - private String type; - - private String value; - - private transient int multiSelectTotal = 0; - - private transient Map allCols = new HashMap(); - - private String propertyFile; - - private String groovyScript; - - private String groovyScriptFile; - - private String bindings; - - private String propertyKey; - - private String defaultValue; - - private String defaultPropertyFile; - - private String defaultGroovyScript; - - private String defaultGroovyScriptFile; - - private String defaultBindings; - - private String defaultPropertyKey; - - private String multiSelectDelimiter; - - public ExtendedChoiceParameterDefinition(String name, String type, String value, String propertyFile, String groovyScript, - String groovyScriptFile, String bindings, String propertyKey, String defaultValue, String defaultPropertyFile, - String defaultGroovyScript, String defaultGroovyScriptFile, String defaultBindings, String defaultPropertyKey, boolean quoteValue, - int visibleItemCount, String description, String multiSelectDelimiter) { - super(name, description); - this.type = type; - - this.value = value; - this.propertyFile = propertyFile; - this.propertyKey = propertyKey; - this.groovyScript = groovyScript; - this.groovyScriptFile = groovyScriptFile; - this.bindings = bindings; - - this.defaultValue = defaultValue; - this.defaultPropertyFile = defaultPropertyFile; - this.defaultPropertyKey = defaultPropertyKey; - this.defaultGroovyScript = defaultGroovyScript; - this.defaultGroovyScriptFile = defaultGroovyScriptFile; - this.defaultBindings = defaultBindings; - - this.quoteValue = quoteValue; - if(visibleItemCount == 0) { - visibleItemCount = 5; - } - this.visibleItemCount = visibleItemCount; - - if(multiSelectDelimiter == null || "".equals(multiSelectDelimiter)) { - multiSelectDelimiter = ","; - } - this.multiSelectDelimiter = multiSelectDelimiter; - } - - private Map computeDefaultValueMap() { - Map defaultValueMap = null; - String effectiveDefaultValue = getEffectiveDefaultValue(); - if(!StringUtils.isBlank(effectiveDefaultValue)) { - defaultValueMap = new HashMap(); - String[] defaultValues = StringUtils.split(effectiveDefaultValue, ','); - for(String value: defaultValues) { - defaultValueMap.put(StringUtils.trim(value), true); - } - } - return defaultValueMap; - } - - @Override - public ParameterValue createValue(StaplerRequest request) { - String[] requestValues = request.getParameterValues(getName()); - return createValue(requestValues); - } - - @Override - public ParameterValue createValue(CLICommand command, String value) throws IOException, InterruptedException { - String[] requestValues = (value != null) ? value.split(",") : null; - return createValue(requestValues); - } - - /*package*/ParameterValue createValue(String[] requestValues) { - if(requestValues == null || requestValues.length == 0) { - return getDefaultParameterValue(); - } - if(PARAMETER_TYPE_TEXT_BOX.equals(type)) { - return new ExtendedChoiceParameterValue(getName(), requestValues[0]); - } - else { - String valueStr = getEffectiveValue(); - if(valueStr != null) { - List result = new ArrayList(); - - String[] values = valueStr.split(","); - Set valueSet = new HashSet(); - for(String value: values) { - valueSet.add(value); - } - - for(String requestValue: requestValues) { - if(valueSet.contains(requestValue)) { - result.add(requestValue); - } - } - - return new ExtendedChoiceParameterValue(getName(), StringUtils.join(result, getMultiSelectDelimiter())); - } - } - return null; - } - - @Override - public ParameterValue createValue(StaplerRequest request, JSONObject jO) { - Object value = jO.get("value"); - String strValue = ""; - Map allCols = new HashMap(); - - if(value instanceof String) { - strValue = (String)value; - } - else if(value instanceof JSONArray) { - int multiLevelColumns = 0; - JSONArray jsonValues = (JSONArray)value; - if(type.equals(PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT) || type.equals(PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT)) { - final int valuesBetweenLevels = this.value.split(",").length; - multiLevelColumns = valuesBetweenLevels; - - Iterator it = jsonValues.iterator(); - for(int i = 1; it.hasNext(); i++) { - String nextValue = it.next().toString(); - this.multiSelectTotal = i; - - allCols.put(i, nextValue); - - if(i % valuesBetweenLevels == 0) { - if(strValue.length() > 0) { - strValue += getMultiSelectDelimiter(); - } - strValue += nextValue; - } - this.allCols = allCols; - } - } - else { - strValue = StringUtils.join(jsonValues.iterator(), getMultiSelectDelimiter()); - } - - // Concatenate all multi-select values into one string - strValue = ""; - StringBuilder strCols = new StringBuilder(); - for (int eachSelect = 1, col = 1, row = 1; eachSelect <= this.multiSelectTotal; eachSelect++, col++) { - if (col == 1) { // 1st column - strCols.append(row).append(":").append(this.allCols.get(eachSelect)).append(","); - } - else if ((eachSelect % multiLevelColumns) == 0) { // last column - strCols.append(this.allCols.get(eachSelect)).append(":"); - col = 0; - row++; - } - else { // columns in between - strCols.append(this.allCols.get(eachSelect)).append(","); - } - } - strValue = strCols.toString(); - } - - if(quoteValue) { - strValue = "\"" + strValue + "\""; - } - return new ExtendedChoiceParameterValue(getName(), strValue); - } - - @Override - public ParameterValue getDefaultParameterValue() { - String defaultValue = getEffectiveDefaultValue(); - if(!StringUtils.isBlank(defaultValue)) { - if(quoteValue) { - defaultValue = "\"" + defaultValue + "\""; - } - return new ExtendedChoiceParameterValue(getName(), defaultValue); - } - return super.getDefaultParameterValue(); - } - - // note that computeValue is not called by multiLevel.jelly - private String computeValue(String value, String propertyFilePath, String propertyKey, String groovyScript, String groovyScriptFile, - String bindings, boolean isDefault) { - if(!StringUtils.isBlank(propertyFilePath) && !StringUtils.isBlank(propertyKey)) { - try { - File propertyFile = new File(propertyFilePath); - if(propertyFile.exists()) { - Project project = new Project(); - Property property = new Property(); - property.setProject(project); - property.setFile(propertyFile); - property.execute(); - return project.getProperty(propertyKey); - } - else { - Project project = new Project(); - Property property = new Property(); - property.setProject(project); - URL propertyFileUrl = new URL(propertyFilePath); - property.setUrl(propertyFileUrl); - property.execute(); - return project.getProperty(propertyKey); - } - - } - catch(Exception e) { - - } - } - else if(!StringUtils.isBlank(groovyScript)) { - try { - GroovyShell groovyShell = new GroovyShell(); - setBindings(groovyShell, bindings); - Object groovyValue = groovyShell.evaluate(groovyScript); - String processedGroovyValue = processGroovyValue(isDefault, groovyValue); - return processedGroovyValue; - } - catch(Exception e) { - - } - } - else if(!StringUtils.isBlank(groovyScriptFile)) { - try { - GroovyShell groovyShell = new GroovyShell(); - setBindings(groovyShell, bindings); - groovyScript = Util.loadFile(new File(groovyScriptFile)); - Object groovyValue = groovyShell.evaluate(groovyScript); - String processedGroovyValue = processGroovyValue(isDefault, groovyValue); - return processedGroovyValue; - } - catch(Exception e) { - - } - } - else if(!StringUtils.isBlank(value)) { - return value; - } - return null; - } - - private String processGroovyValue(boolean isDefault, Object groovyValue) { - String value = null; - if(groovyValue instanceof String[]) { - String[] groovyValues = (String[])groovyValue; - if(!isDefault) { - value = StringUtils.join((String[])groovyValue, multiSelectDelimiter); - } - else if(groovyValues.length > 0) { - value = groovyValues[0]; - } - } - else if(groovyValue instanceof String) { - value = (String)groovyValue; - } - return value; - } - - private void setBindings(GroovyShell shell, String bindings) throws IOException { - if(bindings != null) { - Properties p = new Properties(); - p.load(new StringReader(bindings)); - for(Map.Entry entry: p.entrySet()) { - shell.setVariable((String)entry.getKey(), entry.getValue()); - } - } - } - - @Override - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getEffectiveDefaultValue() { - return computeValue(defaultValue, defaultPropertyFile, defaultPropertyKey, defaultGroovyScript, defaultGroovyScriptFile, defaultBindings, true); - } - - public String getDefaultValue() { - return defaultValue; - } - - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - } - - public String getPropertyFile() { - return propertyFile; - } - - public void setPropertyFile(String propertyFile) { - this.propertyFile = propertyFile; - } - - public String getGroovyScript() { - return groovyScript; - } - - public void setGroovyScript(String groovyScript) { - this.groovyScript = groovyScript; - } - - public String getGroovyScriptFile() { - return groovyScriptFile; - } - - public void setGroovyScriptFile(String groovyScriptFile) { - this.groovyScriptFile = groovyScriptFile; - } - - public String getBindings() { - return bindings; - } - - public void setBindings(String bindings) { - this.bindings = bindings; - } - - public String getDefaultPropertyKey() { - return defaultPropertyKey; - } - - public void setDefaultPropertyKey(String defaultPropertyKey) { - this.defaultPropertyKey = defaultPropertyKey; - } - - public String getEffectiveValue() { - return computeValue(value, propertyFile, propertyKey, groovyScript, groovyScriptFile, bindings, false); - } - - private ArrayList columnIndicesForDropDowns(String[] headerColumns) { - ArrayList columnIndicesForDropDowns = new ArrayList(); - - String[] dropDownNames = value.split(","); - - for(String dropDownName: dropDownNames) { - for(int i = 0; i < headerColumns.length; ++i) { - if(headerColumns[i].equals(dropDownName)) { - columnIndicesForDropDowns.add(new Integer(i)); - } - } - } - - return columnIndicesForDropDowns; - } - - LinkedHashMap> calculateChoicesByDropdownId() throws Exception { - File file = new File(propertyFile); - List fileLines = Collections.emptyList(); - if(file.isFile()) { - CSVReader csvReader = null; - try { - csvReader = new CSVReader(new FileReader(file), '\t'); - fileLines = csvReader.readAll(); - } - finally { - csvReader.close(); - } - } - else { - URL propertyFileUrl = new URL(propertyFile); - CSVReader csvReader = null; - try { - csvReader = new CSVReader(new InputStreamReader(propertyFileUrl.openStream()), '\t'); - fileLines = csvReader.readAll(); - } - finally { - csvReader.close(); - } - } - - if(fileLines.size() < 2) { - throw new Exception("Multi level tab delimited file must have at least 2 " + "lines (one for the header, and one or more for the data)"); - } - - ArrayList columnIndicesForDropDowns = columnIndicesForDropDowns(fileLines.get(0)); - - List dataLines = fileLines.subList(1, fileLines.size()); - - LinkedHashMap> choicesByDropdownId = new LinkedHashMap>(); - - String prefix = getName() + " dropdown MultiLevelMultiSelect 0"; - choicesByDropdownId.put(prefix, new LinkedHashSet()); - - for(int i = 0; i < columnIndicesForDropDowns.size(); ++i) { - String prettyCurrentColumnName = value.split(",")[i]; - prettyCurrentColumnName = prettyCurrentColumnName.toLowerCase(); - prettyCurrentColumnName = prettyCurrentColumnName.replace("_", " "); - - for(String[] dataLine: dataLines) { - String priorLevelDropdownId = prefix; - String currentLevelDropdownId = prefix; - - int column = 0; - for(int j = 0; j <= i; ++j) { - column = columnIndicesForDropDowns.get(j); - - if(j < i) { - priorLevelDropdownId += " " + dataLine[column]; - } - currentLevelDropdownId += " " + dataLine[column]; - } - if(i != columnIndicesForDropDowns.size() - 1) { - choicesByDropdownId.put(currentLevelDropdownId, new LinkedHashSet()); - } - LinkedHashSet choicesForPriorDropdown = choicesByDropdownId.get(priorLevelDropdownId); - choicesForPriorDropdown.add("Select a " + prettyCurrentColumnName + "..."); - choicesForPriorDropdown.add(dataLine[column]); - } - } - - return choicesByDropdownId; - } - - public String getMultiLevelDropdownIds() throws Exception { - String dropdownIds = new String(); - - LinkedHashMap> choicesByDropdownId = calculateChoicesByDropdownId(); - - for(String id: choicesByDropdownId.keySet()) { - if(dropdownIds.length() > 0) { - dropdownIds += ","; - } - dropdownIds += id; - } - - return dropdownIds; - - /* dropdownIds is of a form like this: - return name + " dropdown MultiLevelMultiSelect 0," - // next select the source of the genome -- each genome gets a seperate dropdown id:" - + name + " dropdown MultiLevelMultiSelect 0 HG18,dropdown MultiLevelMultiSelect 0 ZZ23," - // next select the cell type of the source -- each source gets a seperate dropdown id - + name + " dropdown MultiLevelMultiSelect 0 HG18 Diffuse large B-cell lymphoma, dropdown MultiLevelMultiSelect 0 HG18 Multiple Myeloma," - + name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma," - // next select the name from the cell type -- each cell type gets a seperate dropdown id - + name + " dropdown MultiLevelMultiSelect 0 HG18 Diffuse large B-cell lymphoma LY1," - + name + " dropdown MultiLevelMultiSelect 0 HG18 Multiple Myeloma MM1S," - + name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma BE2C," - + name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma SKNAS";*/ - } - - public Map getChoicesByDropdownId() throws Exception { - LinkedHashMap> choicesByDropdownId = calculateChoicesByDropdownId(); - - Map collapsedMap = new LinkedHashMap(); - - for(String dropdownId: choicesByDropdownId.keySet()) { - String choices = new String(); - for(String choice: choicesByDropdownId.get(dropdownId)) { - if(choices.length() > 0) { - choices += ","; - } - choices += choice; - } - - collapsedMap.put(dropdownId, choices); - } - - /* collapsedMap is of a form like this: - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0", "Select a genome...,HG18,ZZ23"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18", "Select a source...,Diffuse large B-cell lymphoma,Multiple Myeloma"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 ZZ23", "Select a source...,Neuroblastoma"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18 Diffuse large B-cell lymphoma","Select a cell type...,LY1"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18 Multiple Myeloma","Select a cell type...,MM1S"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma","Select a cell type...,BE2C,SKNAS"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18 Diffuse large B-cell lymphoma LY1","Select a name...,LY1_BCL6_DMSO,LY1_BCL6_JQ1"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18 Multiple Myeloma MM1S", "Select a name...,MM1S_BRD4_150nM_JQ1,MM1S_BRD4_500nM_JQ1"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma BE2C", "Select a name...,BE2C_BRD4"); - collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma SKNAS", "Select a name...,SKNAS_H3K4ME3"); - */ - - return collapsedMap; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getPropertyKey() { - return propertyKey; - } - - public void setPropertyKey(String propertyKey) { - this.propertyKey = propertyKey; - } - - public String getDefaultPropertyFile() { - return defaultPropertyFile; - } - - public String getDefaultGroovyScript() { - return defaultGroovyScript; - } - - public void setDefaultGroovyScript(String defaultGroovyScript) { - this.defaultGroovyScript = defaultGroovyScript; - } - - public String getDefaultGroovyScriptFile() { - return defaultGroovyScriptFile; - } - - public void setDefaultGroovyScriptFile(String defaultGroovyScriptFile) { - this.defaultGroovyScriptFile = defaultGroovyScriptFile; - } - - public String getDefaultBindings() { - return defaultBindings; - } - - public void setDefaultBindings(String defaultBindings) { - this.defaultBindings = defaultBindings; - } - - public boolean isQuoteValue() { - return quoteValue; - } - - public void setQuoteValue(boolean quoteValue) { - this.quoteValue = quoteValue; - } - - public int getVisibleItemCount() { - return visibleItemCount; - } - - public void setVisibleItemCount(int visibleItemCount) { - this.visibleItemCount = visibleItemCount; - } - - public String getMultiSelectDelimiter() { - return this.multiSelectDelimiter; - } - - public void setMultiSelectDelimiter(final String multiSelectDelimiter) { - this.multiSelectDelimiter = multiSelectDelimiter; - } - - public void setDefaultPropertyFile(String defaultPropertyFile) { - this.defaultPropertyFile = defaultPropertyFile; - } - - public Map getDefaultValueMap() { - return computeDefaultValueMap(); - } -} +/* + *Copyright (c) 2013 Costco, Vimil Saju + *Copyright (c) 2013 John DiMatteo + *See the file license.txt for copying permission. + */ + +package com.cwctravel.hudson.plugins.extended_choice_parameter; + +import groovy.lang.GroovyShell; +import hudson.Extension; +import hudson.Util; +import hudson.cli.CLICommand; +import hudson.model.ParameterValue; +import hudson.model.ParameterDefinition; +import hudson.util.FormValidation; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.servlet.ServletException; + +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; + +import org.apache.commons.lang.StringUtils; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Property; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; + +import au.com.bytecode.opencsv.CSVReader; + +public class ExtendedChoiceParameterDefinition extends ParameterDefinition { + private static final long serialVersionUID = -2946187268529865645L; + + public static final String PARAMETER_TYPE_SINGLE_SELECT = "PT_SINGLE_SELECT"; + + public static final String PARAMETER_TYPE_MULTI_SELECT = "PT_MULTI_SELECT"; + + public static final String PARAMETER_TYPE_CHECK_BOX = "PT_CHECKBOX"; + + public static final String PARAMETER_TYPE_RADIO = "PT_RADIO"; + + public static final String PARAMETER_TYPE_TEXT_BOX = "PT_TEXTBOX"; + + public static final String PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT = "PT_MULTI_LEVEL_SINGLE_SELECT"; + + public static final String PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT = "PT_MULTI_LEVEL_MULTI_SELECT"; + + @Extension + public static class DescriptorImpl extends ParameterDescriptor { + @Override + public String getDisplayName() { + return Messages.ExtendedChoiceParameterDefinition_DisplayName(); + } + + public FormValidation doCheckPropertyFile(@QueryParameter final String propertyFile, @QueryParameter final String propertyKey, + @QueryParameter final String type) throws IOException, ServletException { + if(StringUtils.isBlank(propertyFile)) { + return FormValidation.ok(); + } + + Project project = new Project(); + Property property = new Property(); + property.setProject(project); + + File prop = new File(propertyFile); + try { + if(prop.exists()) { + property.setFile(prop); + } + else { + URL propertyFileUrl = new URL(propertyFile); + property.setUrl(propertyFileUrl); + } + property.execute(); + } + catch(Exception e) { + return FormValidation.warning(Messages.ExtendedChoiceParameterDefinition_PropertyFileDoesntExist(), propertyFile); + } + + if(PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT.equals(type) || PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT.equals(type)) { + return FormValidation.ok(); + } + else if(StringUtils.isNotBlank(propertyKey)) { + if(project.getProperty(propertyKey) != null) { + return FormValidation.ok(); + } + else { + return FormValidation.warning(Messages.ExtendedChoiceParameterDefinition_PropertyFileExistsButProvidedKeyIsInvalid(), propertyFile, propertyKey); + } + } + else { + return FormValidation.warning(Messages.ExtendedChoiceParameterDefinition_PropertyFileExistsButNoProvidedKey(), propertyFile); + } + } + + public FormValidation doCheckPropertyKey(@QueryParameter final String propertyFile, @QueryParameter final String propertyKey, + @QueryParameter final String type) throws IOException, ServletException { + return doCheckPropertyFile(propertyFile, propertyKey, type); + } + + public FormValidation doCheckDefaultPropertyFile(@QueryParameter final String defaultPropertyFile, + @QueryParameter final String defaultPropertyKey, @QueryParameter final String type) throws IOException, ServletException { + return doCheckPropertyFile(defaultPropertyFile, defaultPropertyKey, type); + } + + public FormValidation doCheckDefaultPropertyKey(@QueryParameter final String defaultPropertyFile, + @QueryParameter final String defaultPropertyKey, @QueryParameter final String type) throws IOException, ServletException { + return doCheckPropertyFile(defaultPropertyFile, defaultPropertyKey, type); + } + + @Override + public ExtendedChoiceParameterDefinition newInstance(StaplerRequest req, JSONObject formData) throws FormException { + String name = null; + String type = null; + String description = null; + String multiSelectDelimiter = null; + boolean quoteValue = false; + int visibleItemCount = 5; + + String propertyValue = null; + String propertyKey = null; + String propertyFile = null; + String groovyScript = null; + String groovyScriptFile = null; + String bindings = null; + + String defaultPropertyValue = null; + String defaultPropertyKey = null; + String defaultPropertyFile = null; + String defaultGroovyScript = null; + String defaultGroovyScriptFile = null; + String defaultBindings = null; + + name = formData.getString("name"); + description = formData.getString("description"); + + JSONObject parameterGroup = formData.getJSONObject("parameterGroup"); + if(parameterGroup != null) { + int value = parameterGroup.getInt("value"); + if(value == 0) { + type = parameterGroup.getString("type"); + quoteValue = parameterGroup.getBoolean("quoteValue"); + visibleItemCount = parameterGroup.optInt("visibleItemCount", 5); + multiSelectDelimiter = parameterGroup.getString("multiSelectDelimiter"); + if(StringUtils.isEmpty(multiSelectDelimiter)) { + multiSelectDelimiter = ","; + } + + JSONObject propertySourceJSON = (JSONObject)parameterGroup.get("propertySource"); + if(propertySourceJSON != null) { + if(propertySourceJSON.getInt("value") == 0) { + propertyValue = propertySourceJSON.getString("propertyValue"); + } + else if(propertySourceJSON.getInt("value") == 1) { + propertyFile = propertySourceJSON.getString("propertyFile"); + propertyKey = propertySourceJSON.getString("propertyKey"); + } + else if(propertySourceJSON.getInt("value") == 2) { + groovyScript = propertySourceJSON.getString("groovyScript"); + bindings = propertySourceJSON.getString("bindings"); + } + else if(propertySourceJSON.getInt("value") == 3) { + groovyScriptFile = propertySourceJSON.getString("groovyScriptFile"); + bindings = propertySourceJSON.getString("bindings"); + } + } + + JSONObject defaultPropertySourceJSON = (JSONObject)parameterGroup.get("defaultPropertySource"); + if(defaultPropertySourceJSON != null) { + if(defaultPropertySourceJSON.getInt("value") == 0) { + defaultPropertyValue = defaultPropertySourceJSON.getString("defaultPropertyValue"); + } + else if(defaultPropertySourceJSON.getInt("value") == 1) { + defaultPropertyFile = defaultPropertySourceJSON.getString("defaultPropertyFile"); + defaultPropertyKey = defaultPropertySourceJSON.getString("defaultPropertyKey"); + } + else if(defaultPropertySourceJSON.getInt("value") == 2) { + defaultGroovyScript = defaultPropertySourceJSON.getString("defaultGroovyScript"); + defaultBindings = defaultPropertySourceJSON.getString("defaultBindings"); + } + else if(defaultPropertySourceJSON.getInt("value") == 3) { + defaultGroovyScriptFile = defaultPropertySourceJSON.getString("defaultGroovyScriptFile"); + defaultBindings = defaultPropertySourceJSON.getString("defaultBindings"); + } + } + } + else if(value == 1) { + type = parameterGroup.getString("type"); + propertyFile = parameterGroup.getString("propertyFile"); + propertyValue = parameterGroup.optString("propertyValue"); + } + } + else { + type = formData.getString("type"); + propertyFile = formData.getString("propertyFile"); + propertyKey = formData.getString("propertyKey"); + propertyValue = formData.optString("value"); + defaultPropertyFile = formData.optString("defaultPropertyFile"); + defaultPropertyKey = formData.optString("defaultPropertyKey"); + defaultPropertyValue = formData.optString("defaultValue"); + } + + return new ExtendedChoiceParameterDefinition(name, type, propertyValue, propertyFile, groovyScript, groovyScriptFile, bindings, propertyKey, defaultPropertyValue, defaultPropertyFile, defaultGroovyScript, defaultGroovyScriptFile, defaultBindings, defaultPropertyKey, quoteValue, visibleItemCount, description, multiSelectDelimiter); + } + } + + private boolean quoteValue; + + private int visibleItemCount; + + private String type; + + private String value; + + private transient int multiSelectTotal = 0; + + private transient Map allCols = new HashMap(); + + private String propertyFile; + + private String groovyScript; + + private String groovyScriptFile; + + private String bindings; + + private String propertyKey; + + private String defaultValue; + + private String defaultPropertyFile; + + private String defaultGroovyScript; + + private String defaultGroovyScriptFile; + + private String defaultBindings; + + private String defaultPropertyKey; + + private String multiSelectDelimiter; + + public ExtendedChoiceParameterDefinition(String name, String type, String value, String propertyFile, String groovyScript, + String groovyScriptFile, String bindings, String propertyKey, String defaultValue, String defaultPropertyFile, + String defaultGroovyScript, String defaultGroovyScriptFile, String defaultBindings, String defaultPropertyKey, boolean quoteValue, + int visibleItemCount, String description, String multiSelectDelimiter) { + super(name, description); + this.type = type; + + this.value = value; + this.propertyFile = propertyFile; + this.propertyKey = propertyKey; + this.groovyScript = groovyScript; + this.groovyScriptFile = groovyScriptFile; + this.bindings = bindings; + + this.defaultValue = defaultValue; + this.defaultPropertyFile = defaultPropertyFile; + this.defaultPropertyKey = defaultPropertyKey; + this.defaultGroovyScript = defaultGroovyScript; + this.defaultGroovyScriptFile = defaultGroovyScriptFile; + this.defaultBindings = defaultBindings; + + this.quoteValue = quoteValue; + if(visibleItemCount == 0) { + visibleItemCount = 5; + } + this.visibleItemCount = visibleItemCount; + + if(multiSelectDelimiter == null || "".equals(multiSelectDelimiter)) { + multiSelectDelimiter = ","; + } + this.multiSelectDelimiter = multiSelectDelimiter; + } + + private Map computeDefaultValueMap() { + Map defaultValueMap = null; + String effectiveDefaultValue = getEffectiveDefaultValue(); + if(!StringUtils.isBlank(effectiveDefaultValue)) { + defaultValueMap = new HashMap(); + String[] defaultValues = StringUtils.split(effectiveDefaultValue, ','); + for(String value: defaultValues) { + defaultValueMap.put(StringUtils.trim(value), true); + } + } + return defaultValueMap; + } + + @Override + public ParameterValue createValue(StaplerRequest request) { + String[] requestValues = request.getParameterValues(getName()); + return createValue(requestValues); + } + + @Override + public ParameterValue createValue(CLICommand command, String value) throws IOException, InterruptedException { + String[] requestValues = (value != null) ? value.split(",") : null; + return createValue(requestValues); + } + + /*package*/ParameterValue createValue(String[] requestValues) { + if(requestValues == null || requestValues.length == 0) { + return getDefaultParameterValue(); + } + if(PARAMETER_TYPE_TEXT_BOX.equals(type)) { + return new ExtendedChoiceParameterValue(getName(), requestValues[0]); + } + else { + String valueStr = getEffectiveValue(); + if(valueStr != null) { + List result = new ArrayList(); + + String[] values = valueStr.split(","); + Set valueSet = new HashSet(); + for(String value: values) { + valueSet.add(value); + } + + for(String requestValue: requestValues) { + if(valueSet.contains(requestValue)) { + result.add(requestValue); + } + } + + return new ExtendedChoiceParameterValue(getName(), StringUtils.join(result, getMultiSelectDelimiter())); + } + } + return null; + } + + /** + * Stores each multi-level dropdown's values + * @param request, jO + * @return new ExtendedChoiceParameterValue + */ + @Override + public ParameterValue createValue(StaplerRequest request, JSONObject jO) { + Object value = jO.get("value"); + String strValue = ""; + Map allCols = new HashMap(); + + if(value instanceof String) { + strValue = (String)value; + } + else if(value instanceof JSONArray) { + int multiLevelColumns = 0; + JSONArray jsonValues = (JSONArray)value; + if(type.equals(PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT) || type.equals(PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT)) { + final int valuesBetweenLevels = this.value.split(",").length; + multiLevelColumns = valuesBetweenLevels; + + Iterator it = jsonValues.iterator(); + for(int i = 1; it.hasNext(); i++) { + String nextValue = it.next().toString(); + this.multiSelectTotal = i; + + allCols.put(i, nextValue); + + if(i % valuesBetweenLevels == 0) { + if(strValue.length() > 0) { + strValue += getMultiSelectDelimiter(); + } + strValue += nextValue; + } + this.allCols = allCols; + } + } + else { + strValue = StringUtils.join(jsonValues.iterator(), getMultiSelectDelimiter()); + } + + // Concatenate all multi-select values into one string + strValue = ""; + StringBuilder strCols = new StringBuilder(); + for (int eachSelect = 1, col = 1, row = 1; eachSelect <= this.multiSelectTotal; eachSelect++, col++) { + if (col == 1) { // 1st column + strCols.append(row).append(":").append(this.allCols.get(eachSelect)).append(","); + } + else if ((eachSelect % multiLevelColumns) == 0) { // last column + strCols.append(this.allCols.get(eachSelect)).append(":"); + col = 0; + row++; + } + else { // columns in between + strCols.append(this.allCols.get(eachSelect)).append(","); + } + } + strValue = strCols.toString(); + } + + if(quoteValue) { + strValue = "\"" + strValue + "\""; + } + return new ExtendedChoiceParameterValue(getName(), strValue); + } + + @Override + public ParameterValue getDefaultParameterValue() { + String defaultValue = getEffectiveDefaultValue(); + if(!StringUtils.isBlank(defaultValue)) { + if(quoteValue) { + defaultValue = "\"" + defaultValue + "\""; + } + return new ExtendedChoiceParameterValue(getName(), defaultValue); + } + return super.getDefaultParameterValue(); + } + + // note that computeValue is not called by multiLevel.jelly + private String computeValue(String value, String propertyFilePath, String propertyKey, String groovyScript, String groovyScriptFile, + String bindings, boolean isDefault) { + if(!StringUtils.isBlank(propertyFilePath) && !StringUtils.isBlank(propertyKey)) { + try { + File propertyFile = new File(propertyFilePath); + if(propertyFile.exists()) { + Project project = new Project(); + Property property = new Property(); + property.setProject(project); + property.setFile(propertyFile); + property.execute(); + return project.getProperty(propertyKey); + } + else { + Project project = new Project(); + Property property = new Property(); + property.setProject(project); + URL propertyFileUrl = new URL(propertyFilePath); + property.setUrl(propertyFileUrl); + property.execute(); + return project.getProperty(propertyKey); + } + + } + catch(Exception e) { + + } + } + else if(!StringUtils.isBlank(groovyScript)) { + try { + GroovyShell groovyShell = new GroovyShell(); + setBindings(groovyShell, bindings); + Object groovyValue = groovyShell.evaluate(groovyScript); + String processedGroovyValue = processGroovyValue(isDefault, groovyValue); + return processedGroovyValue; + } + catch(Exception e) { + + } + } + else if(!StringUtils.isBlank(groovyScriptFile)) { + try { + GroovyShell groovyShell = new GroovyShell(); + setBindings(groovyShell, bindings); + groovyScript = Util.loadFile(new File(groovyScriptFile)); + Object groovyValue = groovyShell.evaluate(groovyScript); + String processedGroovyValue = processGroovyValue(isDefault, groovyValue); + return processedGroovyValue; + } + catch(Exception e) { + + } + } + else if(!StringUtils.isBlank(value)) { + return value; + } + return null; + } + + private String processGroovyValue(boolean isDefault, Object groovyValue) { + String value = null; + if(groovyValue instanceof String[]) { + String[] groovyValues = (String[])groovyValue; + if(!isDefault) { + value = StringUtils.join((String[])groovyValue, multiSelectDelimiter); + } + else if(groovyValues.length > 0) { + value = groovyValues[0]; + } + } + else if(groovyValue instanceof String) { + value = (String)groovyValue; + } + return value; + } + + private void setBindings(GroovyShell shell, String bindings) throws IOException { + if(bindings != null) { + Properties p = new Properties(); + p.load(new StringReader(bindings)); + for(Map.Entry entry: p.entrySet()) { + shell.setVariable((String)entry.getKey(), entry.getValue()); + } + } + } + + @Override + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getEffectiveDefaultValue() { + return computeValue(defaultValue, defaultPropertyFile, defaultPropertyKey, defaultGroovyScript, defaultGroovyScriptFile, defaultBindings, true); + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + public String getPropertyFile() { + return propertyFile; + } + + public void setPropertyFile(String propertyFile) { + this.propertyFile = propertyFile; + } + + public String getGroovyScript() { + return groovyScript; + } + + public void setGroovyScript(String groovyScript) { + this.groovyScript = groovyScript; + } + + public String getGroovyScriptFile() { + return groovyScriptFile; + } + + public void setGroovyScriptFile(String groovyScriptFile) { + this.groovyScriptFile = groovyScriptFile; + } + + public String getBindings() { + return bindings; + } + + public void setBindings(String bindings) { + this.bindings = bindings; + } + + public String getDefaultPropertyKey() { + return defaultPropertyKey; + } + + public void setDefaultPropertyKey(String defaultPropertyKey) { + this.defaultPropertyKey = defaultPropertyKey; + } + + public String getEffectiveValue() { + return computeValue(value, propertyFile, propertyKey, groovyScript, groovyScriptFile, bindings, false); + } + + private ArrayList columnIndicesForDropDowns(String[] headerColumns) { + ArrayList columnIndicesForDropDowns = new ArrayList(); + + String[] dropDownNames = value.split(","); + + for(String dropDownName: dropDownNames) { + for(int i = 0; i < headerColumns.length; ++i) { + if(headerColumns[i].equals(dropDownName)) { + columnIndicesForDropDowns.add(new Integer(i)); + } + } + } + + return columnIndicesForDropDowns; + } + + LinkedHashMap> calculateChoicesByDropdownId() throws Exception { + File file = new File(propertyFile); + List fileLines = Collections.emptyList(); + if(file.isFile()) { + CSVReader csvReader = null; + try { + csvReader = new CSVReader(new FileReader(file), '\t'); + fileLines = csvReader.readAll(); + } + finally { + csvReader.close(); + } + } + else { + URL propertyFileUrl = new URL(propertyFile); + CSVReader csvReader = null; + try { + csvReader = new CSVReader(new InputStreamReader(propertyFileUrl.openStream()), '\t'); + fileLines = csvReader.readAll(); + } + finally { + csvReader.close(); + } + } + + if(fileLines.size() < 2) { + throw new Exception("Multi level tab delimited file must have at least 2 " + "lines (one for the header, and one or more for the data)"); + } + + ArrayList columnIndicesForDropDowns = columnIndicesForDropDowns(fileLines.get(0)); + + List dataLines = fileLines.subList(1, fileLines.size()); + + LinkedHashMap> choicesByDropdownId = new LinkedHashMap>(); + + String prefix = getName() + " dropdown MultiLevelMultiSelect 0"; + choicesByDropdownId.put(prefix, new LinkedHashSet()); + + for(int i = 0; i < columnIndicesForDropDowns.size(); ++i) { + String prettyCurrentColumnName = value.split(",")[i]; + prettyCurrentColumnName = prettyCurrentColumnName.toLowerCase(); + prettyCurrentColumnName = prettyCurrentColumnName.replace("_", " "); + + for(String[] dataLine: dataLines) { + String priorLevelDropdownId = prefix; + String currentLevelDropdownId = prefix; + + int column = 0; + for(int j = 0; j <= i; ++j) { + column = columnIndicesForDropDowns.get(j); + + if(j < i) { + priorLevelDropdownId += " " + dataLine[column]; + } + currentLevelDropdownId += " " + dataLine[column]; + } + if(i != columnIndicesForDropDowns.size() - 1) { + choicesByDropdownId.put(currentLevelDropdownId, new LinkedHashSet()); + } + LinkedHashSet choicesForPriorDropdown = choicesByDropdownId.get(priorLevelDropdownId); + choicesForPriorDropdown.add("Select a " + prettyCurrentColumnName + "..."); + choicesForPriorDropdown.add(dataLine[column]); + } + } + + return choicesByDropdownId; + } + + public String getMultiLevelDropdownIds() throws Exception { + String dropdownIds = new String(); + + LinkedHashMap> choicesByDropdownId = calculateChoicesByDropdownId(); + + for(String id: choicesByDropdownId.keySet()) { + if(dropdownIds.length() > 0) { + dropdownIds += ","; + } + dropdownIds += id; + } + + return dropdownIds; + + /* dropdownIds is of a form like this: + return name + " dropdown MultiLevelMultiSelect 0," + // next select the source of the genome -- each genome gets a seperate dropdown id:" + + name + " dropdown MultiLevelMultiSelect 0 HG18,dropdown MultiLevelMultiSelect 0 ZZ23," + // next select the cell type of the source -- each source gets a seperate dropdown id + + name + " dropdown MultiLevelMultiSelect 0 HG18 Diffuse large B-cell lymphoma, dropdown MultiLevelMultiSelect 0 HG18 Multiple Myeloma," + + name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma," + // next select the name from the cell type -- each cell type gets a seperate dropdown id + + name + " dropdown MultiLevelMultiSelect 0 HG18 Diffuse large B-cell lymphoma LY1," + + name + " dropdown MultiLevelMultiSelect 0 HG18 Multiple Myeloma MM1S," + + name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma BE2C," + + name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma SKNAS";*/ + } + + public Map getChoicesByDropdownId() throws Exception { + LinkedHashMap> choicesByDropdownId = calculateChoicesByDropdownId(); + + Map collapsedMap = new LinkedHashMap(); + + for(String dropdownId: choicesByDropdownId.keySet()) { + String choices = new String(); + for(String choice: choicesByDropdownId.get(dropdownId)) { + if(choices.length() > 0) { + choices += ","; + } + choices += choice; + } + + collapsedMap.put(dropdownId, choices); + } + + /* collapsedMap is of a form like this: + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0", "Select a genome...,HG18,ZZ23"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18", "Select a source...,Diffuse large B-cell lymphoma,Multiple Myeloma"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 ZZ23", "Select a source...,Neuroblastoma"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18 Diffuse large B-cell lymphoma","Select a cell type...,LY1"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18 Multiple Myeloma","Select a cell type...,MM1S"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma","Select a cell type...,BE2C,SKNAS"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18 Diffuse large B-cell lymphoma LY1","Select a name...,LY1_BCL6_DMSO,LY1_BCL6_JQ1"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 HG18 Multiple Myeloma MM1S", "Select a name...,MM1S_BRD4_150nM_JQ1,MM1S_BRD4_500nM_JQ1"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma BE2C", "Select a name...,BE2C_BRD4"); + collapsedMap.put(name + " dropdown MultiLevelMultiSelect 0 ZZ23 Neuroblastoma SKNAS", "Select a name...,SKNAS_H3K4ME3"); + */ + + return collapsedMap; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getPropertyKey() { + return propertyKey; + } + + public void setPropertyKey(String propertyKey) { + this.propertyKey = propertyKey; + } + + public String getDefaultPropertyFile() { + return defaultPropertyFile; + } + + public String getDefaultGroovyScript() { + return defaultGroovyScript; + } + + public void setDefaultGroovyScript(String defaultGroovyScript) { + this.defaultGroovyScript = defaultGroovyScript; + } + + public String getDefaultGroovyScriptFile() { + return defaultGroovyScriptFile; + } + + public void setDefaultGroovyScriptFile(String defaultGroovyScriptFile) { + this.defaultGroovyScriptFile = defaultGroovyScriptFile; + } + + public String getDefaultBindings() { + return defaultBindings; + } + + public void setDefaultBindings(String defaultBindings) { + this.defaultBindings = defaultBindings; + } + + public boolean isQuoteValue() { + return quoteValue; + } + + public void setQuoteValue(boolean quoteValue) { + this.quoteValue = quoteValue; + } + + public int getVisibleItemCount() { + return visibleItemCount; + } + + public void setVisibleItemCount(int visibleItemCount) { + this.visibleItemCount = visibleItemCount; + } + + public String getMultiSelectDelimiter() { + return this.multiSelectDelimiter; + } + + public void setMultiSelectDelimiter(final String multiSelectDelimiter) { + this.multiSelectDelimiter = multiSelectDelimiter; + } + + public void setDefaultPropertyFile(String defaultPropertyFile) { + this.defaultPropertyFile = defaultPropertyFile; + } + + public Map getDefaultValueMap() { + return computeDefaultValueMap(); + } +}