Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
92 changes: 92 additions & 0 deletions src/main/java/hudson/plugins/URLSCM/URLParameter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package hudson.plugins.URLSCM;

import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
* Represents a parameter in a URL
*/
public class URLParameter {

private static String PARAMETER_NAME_REGEX = "[\\w.-]+";
private static Pattern PARAMETER_DEFINITION_PATTERN = Pattern.compile("\\$\\{(" + PARAMETER_NAME_REGEX + ")\\}");
private final String parameterName;

/**
* Creates a parameter with the given name.
* @param parameterName The name of the parameter.
* @exception IllegalArgumentException If parameterName contains any illegal characters
*/
public URLParameter(String parameterName) {
if(Pattern.matches("^" + PARAMETER_NAME_REGEX + "$", parameterName)) {
this.parameterName = parameterName;
}
else throw new IllegalArgumentException(parameterName + " contains invalid characters");
}

/**
* Substitutes this parameter into a parameterised url based on its build parameter value.
* @param url The url to substitute this parameter into
* @param buildParameters The current collection of build parameters
* @return The url with the current parameter substituted with the value specified in buildParameters. If
* the this parameter does not exist in the collection of build parameters, the url will not be modified.
*/
public String substitute(final String url, final Map<String, String> buildParameters) {
String marker = "${" + this.parameterName + "}";
String value = buildParameters.get(this.parameterName);

return value == null ? url : url.replace(marker, value);
}

/**
* Whether this instance is equal to another object.
* @param other The object to compare to this parameter.
* @return True if other is a URLParameter with the same name.
*/
@Override public boolean equals(Object other) {
return other instanceof URLParameter && ((URLParameter)other).parameterName.equals(this.parameterName);
}

/**
* Gets the hash code for this parameter.
* @return
*/
@Override public int hashCode() {
return this.parameterName.hashCode();
}

/**
* Finds all parameters in a URL.
* @param url The URL to search.
* @return A collection of all the parameters found in the input string.
*/
public static Set<URLParameter> getParameters(final String url) {
HashSet<URLParameter> parameters = new HashSet<URLParameter>();

if(url == null) return parameters;

Matcher matcher = PARAMETER_DEFINITION_PATTERN.matcher(url);
while(matcher.find()) {
parameters.add(new URLParameter(matcher.group(1)));
}

return parameters;
}

/**
* Substitutes all parameters in a url based on their current values for the build.
* @param url The URL to substitute parameters into.
* @param buildParameters The current collection of build parameters.
* @return
*/
public static String substituteAll(String url, Map<String, String> buildParameters) {
Collection<URLParameter> parameters = getParameters(url);

for(URLParameter param : parameters) {
url = param.substitute(url, buildParameters);
}

return url;
}
}
19 changes: 18 additions & 1 deletion src/main/java/hudson/plugins/URLSCM/URLSCM.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletException;

Expand Down Expand Up @@ -63,10 +65,12 @@ public boolean checkout(final AbstractBuild<?, ?> build,
workspace.deleteContents();
}

Map<String, String> buildParameters = build.getBuildVariables();

final URLDateAction dates = new URLDateAction(build);

for (final URLTuple tuple : urls) {
final String urlString = tuple.getUrl();
final String urlString = expandUrl(tuple, buildParameters);
InputStream is = null;
OutputStream os = null;
try {
Expand Down Expand Up @@ -105,6 +109,11 @@ public boolean checkout(final AbstractBuild<?, ?> build,
return true;
}

private static String expandUrl(final URLTuple urlTuple, final Map<String, String> buildParameters) {
final String rawUrl = urlTuple.getUrl();
return URLParameter.substituteAll(rawUrl, buildParameters);
}

@Override
public ChangeLogParser createChangeLogParser() {
return new NullChangeLogParser();
Expand Down Expand Up @@ -201,11 +210,19 @@ public FormValidation doUrlCheck(@QueryParameter final String value)
if (!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) {
return FormValidation.ok();
}

return new FormValidation.URLCheck() {
@Override
protected FormValidation check() throws IOException,
ServletException {
final String url = fixEmpty(value);

//parameters cannot be validated here, so allow
Set<URLParameter> parameters = URLParameter.getParameters(url);
if(! parameters.isEmpty()) {
return FormValidation.ok("URL contains parameters");
}

URL u = null;
try {
u = new URL(url);
Expand Down
113 changes: 113 additions & 0 deletions src/test/java/hudson/plugins/URLSCM/URLParameterTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package hudson.plugins.URLSCM;

import java.util.HashMap;
import java.util.Set;
import org.junit.Test;
import static org.junit.Assert.*;

/**
* Tests for {@link URLParameter}
*/
public class URLParameterTests {

/**
* Tests an exception is thrown if the parameter name contains invalid characters
*/
@Test(expected = IllegalArgumentException.class)
public void shouldThrowIfParameterContainsInvalidCharacters() {
URLParameter p = new URLParameter("invalid!par ameter");
}

/**
* Tests a parameter substitutes itself in a parameterised string.
*/
@Test
public void shouldSubstituteParameter() {
URLParameter param = new URLParameter("host");

HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("host", "example");

String result = param.substitute("http://${host}.com/path", parameters);

assertEquals("http://example.com/path", result);
}

/**
* Tests a parameter does not try to substitute itself if the corresponding build parameter does not exist.
*/
@Test
public void shouldNotSubstituteIfParameterNotFound() {
URLParameter param = new URLParameter("test");

String parameterised = "http://example.com/${test}";
String result = param.substitute(parameterised, new HashMap<String, String>());

assertEquals(parameterised, result);
}

/**
* Tests build parameters are found in a parameterised string.
*/
@Test
public void shouldFindParameters() {
String url = "http://${host}.com/${testPath}";
Set<URLParameter> parameters = URLParameter.getParameters(url);

assertEquals(2, parameters.size());
}

/**
* Tests no parameters are found in a string without any valid parameters.
*/
@Test
public void shouldNotFindAnyParameters() {
String str = "String ${with no parameters!}${}";
Set<URLParameter> parameters = URLParameter.getParameters(str);

assertEquals(0, parameters.size());
}

/**
* Tests repeated parameters are only returned once.
*/
@Test
public void shouldNotDuplicateParameters() {
String parameterised = "${param} followed by ${param}";
Set<URLParameter> parameters = URLParameter.getParameters(parameterised);

assertEquals(1, parameters.size());
}

/**
* Tests all parameters are substituted into a parameterised string.
*/
@Test
public void shouldSubstituteAll() {
String parameterised = "http://${host}.com/${path1}/${path2}";

HashMap<String, String> buildParameters = new HashMap<String, String>();
buildParameters.put("host", "example");
buildParameters.put("path1", "first");
buildParameters.put("path2", "second");

String sub = URLParameter.substituteAll(parameterised, buildParameters);

assertEquals("http://example.com/first/second", sub);
}

/**
* Tests a parameterless string is not modified.
*/
@Test
public void shouldNotModifyUrlWithNoParameters() {
String unparameterised = "http://example.com/some/path/without/parameters";

HashMap<String, String> buildParameters = new HashMap<String, String>();
buildParameters.put("param1", "first");
buildParameters.put("param2", "second");

String sub = URLParameter.substituteAll(unparameterised, buildParameters);
assertEquals(unparameterised, sub);
}
}