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

Add namespace context for Saxon compatibility #503

Merged
merged 10 commits into from Jul 8, 2020
16 changes: 13 additions & 3 deletions src/main/java/io/github/bonigarcia/wdm/WebDriverManager.java
Expand Up @@ -59,9 +59,11 @@
import java.util.Optional;
import java.util.regex.Matcher;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
Expand Down Expand Up @@ -819,17 +821,24 @@ protected List<URL> getDriversFromMirror(URL driverUrl) throws IOException {
}
}

protected List<URL> getDriversFromXml(URL driverUrl, String xpath)
protected NamespaceContext getNamespaceContext() {
return null;
}

protected List<URL> getDriversFromXml(URL driverUrl, String xpath, NamespaceContext namespaceContext)
throws IOException {
logSeekRepo(driverUrl);
List<URL> urls = new ArrayList<>();
try {
try (CloseableHttpResponse response = httpClient
.execute(httpClient.createHttpGet(driverUrl))) {
Document xml = loadXML(response.getEntity().getContent());
NodeList nodes = (NodeList) newInstance().newXPath()
XPath xPath = newInstance().newXPath();
if (namespaceContext != null){
xPath.setNamespaceContext(namespaceContext);
}
NodeList nodes = (NodeList) xPath
.evaluate(xpath, xml.getDocumentElement(), NODESET);

for (int i = 0; i < nodes.getLength(); ++i) {
Element e = (Element) nodes.item(i);
urls.add(new URL(driverUrl.toURI().resolve(".")
Expand All @@ -849,6 +858,7 @@ private void logSeekRepo(URL driverUrl) {
protected Document loadXML(InputStream inputStream)
throws SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new InputSource(
new ByteArrayInputStream(IOUtils.toByteArray(inputStream))));
Expand Down
Expand Up @@ -24,11 +24,15 @@
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

import io.github.bonigarcia.wdm.WebDriverManager;
import io.github.bonigarcia.wdm.config.DriverManagerType;
import io.github.bonigarcia.wdm.online.S3BucketListNamespaceContext;

import javax.xml.namespace.NamespaceContext;

/**
* Manager for Chrome.
Expand All @@ -38,6 +42,8 @@
*/
public class ChromeDriverManager extends WebDriverManager {

private static final S3BucketListNamespaceContext S3_BUCKET_LIST_NAMESPACE_CONTEXT = new S3BucketListNamespaceContext();

@Override
public DriverManagerType getDriverManagerType() {
return CHROME;
Expand Down Expand Up @@ -94,7 +100,7 @@ protected List<URL> getDriverUrls() throws IOException {
if (mirrorUrl.isPresent() && config().isUseMirror()) {
return getDriversFromMirror(mirrorUrl.get());
} else {
return getDriversFromXml(getDriverUrl(), "//Contents/Key");
return getDriversFromXml(getDriverUrl(), "//s3:Contents/s3:Key");
}
}

Expand Down Expand Up @@ -145,4 +151,9 @@ protected Charset getVersionCharset() {
return StandardCharsets.UTF_8;
}

@Override
protected NamespaceContext getNamespaceContext() {
return S3_BUCKET_LIST_NAMESPACE_CONTEXT;
}

}
Expand Up @@ -26,6 +26,9 @@

import io.github.bonigarcia.wdm.WebDriverManager;
import io.github.bonigarcia.wdm.config.DriverManagerType;
import io.github.bonigarcia.wdm.online.S3BucketListNamespaceContext;

import javax.xml.namespace.NamespaceContext;

/**
* Manager for Internet Explorer.
Expand All @@ -35,6 +38,8 @@
*/
public class InternetExplorerDriverManager extends WebDriverManager {

private static final S3BucketListNamespaceContext S3_BUCKET_LIST_NAMESPACE_CONTEXT = new S3BucketListNamespaceContext();

@Override
public DriverManagerType getDriverManagerType() {
return IEXPLORER;
Expand Down Expand Up @@ -87,7 +92,7 @@ protected void setDriverUrl(URL url) {

@Override
protected List<URL> getDriverUrls() throws IOException {
return getDriversFromXml(getDriverUrl(), "//Contents/Key");
return getDriversFromXml(getDriverUrl(), "//s3:Contents/s3:Key");
}

@Override
Expand All @@ -101,4 +106,9 @@ protected Optional<String> getDriverVersionFromRepository(
return empty();
}

@Override
protected NamespaceContext getNamespaceContext() {
return S3_BUCKET_LIST_NAMESPACE_CONTEXT;
}

}
Expand Up @@ -27,6 +27,9 @@

import io.github.bonigarcia.wdm.WebDriverManager;
import io.github.bonigarcia.wdm.config.DriverManagerType;
import io.github.bonigarcia.wdm.online.S3BucketListNamespaceContext;

import javax.xml.namespace.NamespaceContext;

/**
* Manager for selenium-server-standalone.
Expand All @@ -36,6 +39,8 @@
*/
public class SeleniumServerStandaloneManager extends WebDriverManager {

private static final S3BucketListNamespaceContext S3_BUCKET_LIST_NAMESPACE_CONTEXT = new S3BucketListNamespaceContext();

@Override
public DriverManagerType getDriverManagerType() {
return SELENIUM_SERVER_STANDALONE;
Expand Down Expand Up @@ -88,7 +93,7 @@ protected Optional<String> getBrowserVersionFromTheShell() {

@Override
protected List<URL> getDriverUrls() throws IOException {
return getDriversFromXml(getDriverUrl(), "//Contents/Key");
return getDriversFromXml(getDriverUrl(), "//s3:Contents/s3:Key");
}

@Override
Expand All @@ -107,4 +112,9 @@ protected void setBrowserVersion(String browserVersion) {
// Nothing required
}

@Override
protected NamespaceContext getNamespaceContext() {
return S3_BUCKET_LIST_NAMESPACE_CONTEXT;
}

}
@@ -0,0 +1,39 @@
package io.github.bonigarcia.wdm.online;

import javax.xml.namespace.NamespaceContext;
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class S3BucketListNamespaceContext implements NamespaceContext {

private static final String S3_BUCKET_LIST_NS = "http://doc.s3.amazonaws.com/2006-03-01";

private static final String S3_PREFIX = "s3";

@Override
public String getNamespaceURI(String prefix) {
if (S3_PREFIX.equals(prefix)) {
return S3_BUCKET_LIST_NS;
}
throw new IllegalArgumentException("Unsupported prefix");
}

@Override
public String getPrefix(String namespaceURI) {
if (S3_BUCKET_LIST_NS.equals(namespaceURI)) {
return S3_PREFIX;
}
throw new IllegalArgumentException("Unsupported namespace URI");
}

@Override
public Iterator<String> getPrefixes(String namespaceURI) {
if (S3_BUCKET_LIST_NS.equals(namespaceURI)) {
return Collections.singletonList(S3_PREFIX).iterator();
} else {
return Collections.EMPTY_LIST.iterator();
}
}

}
@@ -0,0 +1,137 @@
package io.github.bonigarcia.wdm.test.other;

import io.github.bonigarcia.wdm.WebDriverManager;
import io.github.bonigarcia.wdm.config.DriverManagerType;
import io.github.bonigarcia.wdm.online.HttpClient;
import io.github.bonigarcia.wdm.online.S3BucketListNamespaceContext;
import org.hamcrest.Matchers;
import org.junit.Test;

import javax.xml.namespace.NamespaceContext;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.fail;

public class NamespaceContextTest {

public static final S3BucketListNamespaceContext S_3_BUCKET_LIST_NAMESPACE_CONTEXT = new S3BucketListNamespaceContext();

public static final String S3_URI = "http://doc.s3.amazonaws.com/2006-03-01";

@Test
public void testS3BucketListNamespaceContextUrls() throws IOException {
TestWebDriverManager testManager = new TestWebDriverManager();
List<URL> urls = testManager.getDriverUrls();
assertThat(urls, is(not(empty())));
}

@Test
public void testS3BucketListNamespaceContextPrefixes() {
assertThat(S_3_BUCKET_LIST_NAMESPACE_CONTEXT.getNamespaceURI("s3"), equalTo(S3_URI));
assertThat(S_3_BUCKET_LIST_NAMESPACE_CONTEXT.getPrefix(S3_URI), equalTo("s3"));
Iterator<String> prefixes = S_3_BUCKET_LIST_NAMESPACE_CONTEXT.getPrefixes(S3_URI);
assertThat(prefixes.next(), equalTo("s3"));
assertThat(prefixes.hasNext(), equalTo(false));
}


@Test
public void testS3BucketListNamespaceContextInvalidPrefixes() {
try {
S_3_BUCKET_LIST_NAMESPACE_CONTEXT.getNamespaceURI("xmlns");
fail("IllegalArgumentException should be thrown");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), equalTo("Unsupported prefix"));
}
try {
S_3_BUCKET_LIST_NAMESPACE_CONTEXT.getPrefix("http://www.w3.org/2000/xmlns/");
fail("IllegalArgumentException should be thrown");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), equalTo("Unsupported namespace URI"));
}
assertThat(
S_3_BUCKET_LIST_NAMESPACE_CONTEXT.getPrefixes("http://www.w3.org/2000/xmlns/").hasNext(),
is(false)
);
}

private static final class TestWebDriverManager extends WebDriverManager {

@Override
protected NamespaceContext getNamespaceContext() {
return S_3_BUCKET_LIST_NAMESPACE_CONTEXT;
}

@Override
protected List<URL> getDriverUrls() throws IOException {
httpClient = new HttpClient(config());
return getDriversFromXml(getDriverUrl(), "//s3:Contents/s3:Key");
}

@Override
protected Optional<String> getBrowserVersionFromTheShell() {
return Optional.empty();
}

@Override
protected String getDriverName() {
return null;
}

@Override
protected String getDriverVersion() {
return null;
}

@Override
protected void setDriverVersion(String driverVersion) {

}

@Override
protected String getBrowserVersion() {
return null;
}

@Override
protected void setBrowserVersion(String browserVersion) {

}

@Override
protected URL getDriverUrl() {
return getDriverUrlCkeckingMirror(config().getChromeDriverUrl());
}

@Override
protected void setDriverUrl(URL url) {

}

@Override
protected Optional<URL> getMirrorUrl() {
return Optional.empty();
}

@Override
protected Optional<String> getExportParameter() {
return Optional.empty();
}

@Override
public DriverManagerType getDriverManagerType() {
return null;
}

}

}