Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi Level Drop Downs #3

Merged
merged 22 commits into from
Sep 27, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
66f804d
Added a few help files
jdimatteo Sep 3, 2013
a00bfcb
Multi level multi select now implemented
jdimatteo Sep 13, 2013
fac2593
Multiple multi-selects are now working
jdimatteo Sep 13, 2013
daac035
Removed warning that doesn't apply to muli-level selections
jdimatteo Sep 14, 2013
ddd4092
Removed annoying spacing
jdimatteo Sep 14, 2013
4d98e78
Remove another annoying space
jdimatteo Sep 14, 2013
a8ac4c0
Cleaned up more whitespace
jdimatteo Sep 14, 2013
a5530ee
Renamed button
jdimatteo Sep 14, 2013
d54f91a
Added remove button to remove prior selections
jdimatteo Sep 17, 2013
1655e2e
Merge branch 'master' of https://github.com/jenkinsci/extended-choice…
jdimatteo Sep 17, 2013
c1a6d8d
Added a remove button and removed the li entries
jdimatteo Sep 18, 2013
d2e0eb1
Updated to support removing selections and always allow adding anothe…
jdimatteo Sep 19, 2013
f69e5ee
Merge branch 'master' of https://github.com/jenkinsci/extended-choice…
jdimatteo Sep 19, 2013
6a50876
Renamed a couple things
jdimatteo Sep 20, 2013
cd64367
Remove button no longer visible when only one selection div remaining
jdimatteo Sep 20, 2013
7da51d9
Selections are now numbered
jdimatteo Sep 20, 2013
b28027e
Mulit level single select no longer numbered
jdimatteo Sep 20, 2013
028d275
Fixed bug where you couldn't reselect something previously selected
jdimatteo Sep 20, 2013
d286fdb
cleaned up white space
jdimatteo Sep 25, 2013
f8b8d5d
Removed debugging statement
jdimatteo Sep 25, 2013
6550b95
Only last selection(s) from multi-level is included in variable value…
jdimatteo Sep 26, 2013
d56396c
Removed possibly misleading descriptions for 'Radio Buttons' and 'Tex…
jdimatteo Sep 27, 2013
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
</developer>
</developers>

<dependencies>
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.0</version>
</dependency>
</dependencies>

<!-- get every artifact through maven.glassfish.org, which proxies all the artifacts that we need -->
<repositories>
<repository>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import hudson.util.FormValidation;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
Expand All @@ -19,6 +20,9 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;

import javax.servlet.ServletException;

Expand All @@ -32,6 +36,8 @@
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;

Expand All @@ -44,6 +50,10 @@ public class ExtendedChoiceParameterDefinition extends ParameterDefinition {
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 {
Expand All @@ -52,7 +62,7 @@ public String getDisplayName() {
return Messages.ExtendedChoiceParameterDefinition_DisplayName();
}

public FormValidation doCheckPropertyFile(@QueryParameter final String propertyFile, @QueryParameter final String propertyKey) throws IOException, ServletException {
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();
}
Expand All @@ -76,7 +86,12 @@ public FormValidation doCheckPropertyFile(@QueryParameter final String propertyF
return FormValidation.warning(Messages.ExtendedChoiceParameterDefinition_PropertyFileDoesntExist(), propertyFile);
}

if(StringUtils.isNotBlank(propertyKey)) {
if( type.equals(PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT)
|| type.equals(PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT))
{
return FormValidation.ok();
}
else if(StringUtils.isNotBlank(propertyKey)) {
if(project.getProperty(propertyKey) != null) {
return FormValidation.ok();
}
Expand All @@ -89,18 +104,20 @@ public FormValidation doCheckPropertyFile(@QueryParameter final String propertyF
}
}

public FormValidation doCheckPropertyKey(@QueryParameter final String propertyFile, @QueryParameter final String propertyKey) throws IOException, ServletException {
return doCheckPropertyFile(propertyFile, propertyKey);
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) throws IOException, ServletException {
return doCheckPropertyFile(defaultPropertyFile, defaultPropertyKey);
@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) throws IOException, ServletException {
return doCheckPropertyFile(defaultPropertyFile, defaultPropertyKey);
@QueryParameter final String defaultPropertyKey, @QueryParameter final String type) throws IOException, ServletException
{
return doCheckPropertyFile(defaultPropertyFile, defaultPropertyKey, type);
}
}

Expand All @@ -111,7 +128,7 @@ public FormValidation doCheckDefaultPropertyKey(@QueryParameter final String def
private String type;

private String value;

private String propertyFile;

private String propertyKey;
Expand Down Expand Up @@ -194,17 +211,39 @@ public ParameterValue createValue(StaplerRequest request) {
}
return null;
}

@Override
public ParameterValue createValue(StaplerRequest request, JSONObject jO) {
public ParameterValue createValue(StaplerRequest request, JSONObject jO) {
Object value = jO.get("value");
String strValue = "";
if(value instanceof String) {
strValue = (String)value;
}
else if(value instanceof JSONArray) {
JSONArray jsonValues = (JSONArray)value;
strValue = StringUtils.join(jsonValues.iterator(), getMultiSelectDelimiter());
if ( type.equals(PARAMETER_TYPE_MULTI_LEVEL_SINGLE_SELECT)
|| type.equals(PARAMETER_TYPE_MULTI_LEVEL_MULTI_SELECT))
{
final int valuesBetweenLevels = this.value.split(",").length;

Iterator it = jsonValues.iterator();
for (int i = 1; it.hasNext(); i++)
{
String nextValue = it.next().toString();
if (i % valuesBetweenLevels == 0)
{
if (strValue.length() > 0)
{
strValue += getMultiSelectDelimiter();
}
strValue += nextValue;
}
}
}
else
{
strValue = StringUtils.join(jsonValues.iterator(), getMultiSelectDelimiter());
}
}

if(quoteValue) {
Expand All @@ -224,7 +263,8 @@ public ParameterValue getDefaultParameterValue() {
}
return super.getDefaultParameterValue();
}


// note that computeValue is not called by multiLevel.jelly
private String computeValue(String value, String propertyFilePath, String propertyKey) {
if(!StringUtils.isBlank(propertyFile) && !StringUtils.isBlank(propertyKey)) {
try {
Expand Down Expand Up @@ -295,7 +335,156 @@ public void setDefaultPropertyKey(String defaultPropertyKey) {
public String getEffectiveValue() {
return computeValue(value, propertyFile, propertyKey);
}

private ArrayList<Integer> columnIndicesForDropDowns(String[] headerColumns)
{
ArrayList<Integer> columnIndicesForDropDowns = new ArrayList<Integer>();

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<String, LinkedHashSet<String>> calculateChoicesByDropdownId() throws Exception
{
List<String[]> fileLines =
new CSVReader(new FileReader(propertyFile), '\t').readAll();

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<Integer> columnIndicesForDropDowns =
columnIndicesForDropDowns(fileLines.get(0));

List<String[]> dataLines = fileLines.subList(1, fileLines.size());

LinkedHashMap<String, LinkedHashSet<String>> choicesByDropdownId =
new LinkedHashMap<String, LinkedHashSet<String>>();

String prefix = getName() + " dropdown MultiLevelMultiSelect 0";
choicesByDropdownId.put(prefix, new LinkedHashSet<String>());

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<String>());
}
LinkedHashSet<String> 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<String, LinkedHashSet<String>> 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<String, String> getChoicesByDropdownId() throws Exception
{
LinkedHashMap<String, LinkedHashSet<String>> choicesByDropdownId =
calculateChoicesByDropdownId();

Map<String, String> collapsedMap = new LinkedHashMap<String, String>();

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;
}
Expand Down Expand Up @@ -347,5 +536,4 @@ public void setDefaultPropertyFile(String defaultPropertyFile) {
public Map<String, Boolean> getDefaultValueMap() {
return computeDefaultValueMap();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,24 @@
</j:when>
<j:otherwise>
<option value="PT_TEXTBOX">Text Box</option>
</j:otherwise>
</j:choose>
</j:otherwise>
</j:choose>
<j:choose>
<j:when test="${instance.type eq 'PT_MULTI_LEVEL_SINGLE_SELECT'}">
<option value="PT_MULTI_LEVEL_SINGLE_SELECT" selected="selected">Multi-Level Single Select</option>
</j:when>
<j:otherwise>
<option value="PT_MULTI_LEVEL_SINGLE_SELECT">Multi-Level Single Select</option>
</j:otherwise>
</j:choose>
<j:choose>
<j:when test="${instance.type eq 'PT_MULTI_LEVEL_MULTI_SELECT'}">
<option value="PT_MULTI_LEVEL_MULTI_SELECT" selected="selected">Multi-Level Multi Select</option>
</j:when>
<j:otherwise>
<option value="PT_MULTI_LEVEL_MULTI_SELECT">Multi-Level Multi Select</option>
</j:otherwise>
</j:choose>
</select>
</f:entry>
<f:entry title="Value" field="value">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
Absolute path (specified without using environment variables).
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div>
Initial selection of the single-select or mult-select box.
<br><br>In case of the multi-select box, default value can be a comma separated string.
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div>
The <a href="http://download.oracle.com/javase/6/docs/api/java/util/Properties.html">properties file</a>
is a collection of key,value pairs of the form key=value1,value2,...
<br><br>
Property files may reference other properties. For example:
<blockquote>
prop1=a,b,c,d,e<br>
prop2=${prop1},f,g,h
</blockquote>
The properties file can be placed anywhere on the file-system that Jenkins can access.
<br><br>
This property file has different meaning for multi-level select -- see the parameter type help for more info.
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div>
The property of the property file to use.
<br><br>
For example, if the property file was the following:
<blockquote>
prop1=a,b,c,d,e<br>
prop2=1,2,3,4
</blockquote>
Then you could specify the property as either prop1 or prop2.
</div>
Loading