Skip to content

Commit

Permalink
Properly decode jar URLs with spaces (%20). Closes #866
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy committed May 14, 2015
1 parent 1e9d1d5 commit dc84220
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 87 deletions.
1 change: 1 addition & 0 deletions History.md
@@ -1,5 +1,6 @@
## [1.2.3-SNAPSHOT](https://github.com/cucumber/cucumber-jvm/compare/v1.2.2...master) (In Git) ## [1.2.3-SNAPSHOT](https://github.com/cucumber/cucumber-jvm/compare/v1.2.2...master) (In Git)


* [Core] Properly decode jar URLs with spaces (%20) - ([#866](https://github.com/cucumber/cucumber-jvm/issues/866) Aslak Hellesøy)
* [Java] Arity mismatch Java8 Step Definition error ([#852](https://github.com/cucumber/cucumber-jvm/issues/852), [#847](https://github.com/cucumber/cucumber-jvm/pull/847) David Coelho) * [Java] Arity mismatch Java8 Step Definition error ([#852](https://github.com/cucumber/cucumber-jvm/issues/852), [#847](https://github.com/cucumber/cucumber-jvm/pull/847) David Coelho)
* [Java] Print Java 8 lambda snippets when `cucumber-java8` is active (Aslak Hellesøy) * [Java] Print Java 8 lambda snippets when `cucumber-java8` is active (Aslak Hellesøy)
* [Core] Make the Summary Printer into a plugin ([#828](https://github.com/cucumber/cucumber-jvm/pull/828) Björn Rasmusson) * [Core] Make the Summary Printer into a plugin ([#828](https://github.com/cucumber/cucumber-jvm/pull/828) Björn Rasmusson)
Expand Down
Expand Up @@ -39,15 +39,4 @@ public Iterator<Resource> iterator() {
} }
} }


static boolean hasSuffix(String suffix, String name) {
return suffix == null || name.endsWith(suffix);
}

static String getPath(URL url) {
try {
return URLDecoder.decode(url.getPath(), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new CucumberException("Encoding problem", e);
}
}
} }
Expand Up @@ -4,7 +4,7 @@
import java.io.FileFilter; import java.io.FileFilter;
import java.util.Iterator; import java.util.Iterator;


import static cucumber.runtime.io.ClasspathResourceIterable.hasSuffix; import static cucumber.runtime.io.Helpers.hasSuffix;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;


public class FileResourceIterator implements Iterator<Resource> { public class FileResourceIterator implements Iterator<Resource> {
Expand Down
Expand Up @@ -4,7 +4,7 @@
import java.net.URL; import java.net.URL;
import java.util.Iterator; import java.util.Iterator;


import static cucumber.runtime.io.ClasspathResourceIterable.getPath; import static cucumber.runtime.io.Helpers.filePath;


/** /**
* Factory which creates {@link FileResourceIterator}s. * Factory which creates {@link FileResourceIterator}s.
Expand All @@ -25,7 +25,7 @@ public boolean isFactoryFor(URL url) {


@Override @Override
public Iterator<Resource> createIterator(URL url, String path, String suffix) { public Iterator<Resource> createIterator(URL url, String path, String suffix) {
File file = new File(getPath(url)); File file = new File(filePath(url));
File rootDir = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - path.length())); File rootDir = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - path.length()));
return new FileResourceIterator(rootDir, file, suffix); return new FileResourceIterator(rootDir, file, suffix);
} }
Expand Down
32 changes: 32 additions & 0 deletions core/src/main/java/cucumber/runtime/io/Helpers.java
@@ -0,0 +1,32 @@
package cucumber.runtime.io;

import cucumber.runtime.CucumberException;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;

public class Helpers {
static boolean hasSuffix(String suffix, String name) {
return suffix == null || name.endsWith(suffix);
}

static String filePath(URL url) {
try {
return url.toURI().getSchemeSpecificPart();
} catch (URISyntaxException e) {
throw new CucumberException(e);
}
}

static String jarFilePath(URL jarUrl) throws UnsupportedEncodingException, MalformedURLException {
String urlFile = jarUrl.getFile();

int separatorIndex = urlFile.indexOf("!/");
if (separatorIndex == -1) {
throw new CucumberException("Not a jar URL: " + jarUrl.toExternalForm());
}
return filePath(new URL(urlFile.substring(0, separatorIndex)));
}
}
Expand Up @@ -50,7 +50,7 @@ private void moveToNext() {
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
ZipEntry jarEntry = entries.nextElement(); ZipEntry jarEntry = entries.nextElement();
String entryName = jarEntry.getName(); String entryName = jarEntry.getName();
if (entryName.startsWith(path) && ClasspathResourceIterable.hasSuffix(suffix, entryName)) { if (entryName.startsWith(path) && Helpers.hasSuffix(suffix, entryName)) {
next = new ZipResource(jarFile, jarEntry); next = new ZipResource(jarFile, jarEntry);
break; break;
} }
Expand Down
@@ -1,9 +1,6 @@
package cucumber.runtime.io; package cucumber.runtime.io;


import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Iterator; import java.util.Iterator;


Expand All @@ -15,27 +12,15 @@
*/ */
public class ZipResourceIteratorFactory implements ResourceIteratorFactory { public class ZipResourceIteratorFactory implements ResourceIteratorFactory {


static String filePath(URL jarUrl) throws UnsupportedEncodingException, MalformedURLException {
String urlFile = jarUrl.getFile();

int separatorIndex = urlFile.indexOf("!/");
if (separatorIndex != -1) {
urlFile = urlFile.substring(0, separatorIndex);
}

URL url = new URL(urlFile);
return new File(url.getFile()).getPath();
}

@Override @Override
public boolean isFactoryFor(URL url) { public boolean isFactoryFor(URL url) {
return url.getFile().indexOf("!/") != -1; return url.getFile().contains("!/");
} }


@Override @Override
public Iterator<Resource> createIterator(URL url, String path, String suffix) { public Iterator<Resource> createIterator(URL url, String path, String suffix) {
try { try {
String jarPath = filePath(url); String jarPath = Helpers.jarFilePath(url);
return new ZipResourceIterator(jarPath, path, suffix); return new ZipResourceIterator(jarPath, path, suffix);
} catch (IOException e) { } catch (IOException e) {
throw new CucumberException(e); throw new CucumberException(e);
Expand Down

This file was deleted.

40 changes: 40 additions & 0 deletions core/src/test/java/cucumber/runtime/io/HelpersTest.java
@@ -0,0 +1,40 @@
package cucumber.runtime.io;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;

import static cucumber.runtime.io.Helpers.filePath;
import static cucumber.runtime.io.Helpers.jarFilePath;
import static org.junit.Assert.assertEquals;

public class HelpersTest {
private static final URLStreamHandler NULL_URL_STREAM_HANDLER = new URLStreamHandler() {
@Override
protected URLConnection openConnection(URL u) throws IOException {
throw new UnsupportedOperationException();
}
};

@Test
public void computes_file_path_for_file_url() throws UnsupportedEncodingException, MalformedURLException {
URL url = new URL("file:/Users/First%20Last/.m2/repository/info/cukes/cucumber-java/1.2.2/cucumber-java-1.2.2.jar");
assertEquals(new File("/Users/First Last/.m2/repository/info/cukes/cucumber-java/1.2.2/cucumber-java-1.2.2.jar").getAbsolutePath(), filePath(url));
}

@Test
public void computes_file_path_for_jar_protocols() throws Exception {
assertEquals("foo bar+zap/cucumber-core.jar", jarFilePath(new URL("jar:file:foo%20bar+zap/cucumber-core.jar!/cucumber/runtime/io")));
assertEquals("foo bar+zap/cucumber-core.jar", jarFilePath(new URL(null, "zip:file:foo%20bar+zap/cucumber-core.jar!/cucumber/runtime/io", NULL_URL_STREAM_HANDLER)));
assertEquals("foo bar+zap/cucumber-core.jar", jarFilePath(new URL(null, "wsjar:file:foo%20bar+zap/cucumber-core.jar!/cucumber/runtime/io", NULL_URL_STREAM_HANDLER)));
assertEquals("foo bar+zap/cucumber-core.jar", jarFilePath(new URL("jar:file:foo%20bar+zap/cucumber-core.jar!/")));
assertEquals("foo bar+zap/cucumber-core.jar", jarFilePath(new URL(null, "zip:file:foo%20bar+zap/cucumber-core.jar!/", NULL_URL_STREAM_HANDLER)));
assertEquals("foo bar+zap/cucumber-core.jar", jarFilePath(new URL(null, "wsjar:file:foo%20bar+zap/cucumber-core.jar!/", NULL_URL_STREAM_HANDLER)));
}
}
@@ -1,24 +1,22 @@
package cucumber.runtime.io; package cucumber.runtime.io;


import static cucumber.runtime.io.ZipResourceIteratorFactory.filePath; import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;


import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.URLStreamHandler; import java.net.URLStreamHandler;


import org.junit.Test; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;


// https://github.com/cucumber/cucumber-jvm/issues/808 // https://github.com/cucumber/cucumber-jvm/issues/808
public class ZipResourceIteratorFactoryTest { public class ZipResourceIteratorFactoryTest {


private static final URLStreamHandler NULL_URL_STREAM_HANDLER = new URLStreamHandler() { private static final URLStreamHandler NULL_URL_STREAM_HANDLER = new URLStreamHandler() {
@Override @Override
protected URLConnection openConnection(URL u) throws IOException { protected URLConnection openConnection(URL u) throws IOException {
return null; throw new UnsupportedOperationException();
} }
}; };


Expand All @@ -32,14 +30,4 @@ public void is_factory_for_jar_protocols() throws IOException {
assertFalse(factory.isFactoryFor(new URL("file:cucumber-core"))); assertFalse(factory.isFactoryFor(new URL("file:cucumber-core")));
assertFalse(factory.isFactoryFor(new URL("http://http://cukes.info/cucumber-core.jar"))); assertFalse(factory.isFactoryFor(new URL("http://http://cukes.info/cucumber-core.jar")));
} }

@Test
public void computes_file_path_for_jar_protocols() throws Exception {
assertEquals("cucumber-core.jar", filePath(new URL("jar:file:cucumber-core.jar!/cucumber/runtime/io")));
assertEquals("cucumber-core.jar", filePath(new URL(null, "zip:file:cucumber-core.jar!/cucumber/runtime/io", NULL_URL_STREAM_HANDLER)));
assertEquals("cucumber-core.jar", filePath(new URL(null, "wsjar:file:cucumber-core.jar!/cucumber/runtime/io", NULL_URL_STREAM_HANDLER)));
assertEquals("cucumber-core.jar", filePath(new URL("jar:file:cucumber-core.jar!/")));
assertEquals("cucumber-core.jar", filePath(new URL(null, "zip:file:cucumber-core.jar!/", NULL_URL_STREAM_HANDLER)));
assertEquals("cucumber-core.jar", filePath(new URL(null, "wsjar:file:cucumber-core.jar!/", NULL_URL_STREAM_HANDLER)));
}
} }

0 comments on commit dc84220

Please sign in to comment.