Skip to content

Instantly share code, notes, and snippets.

@uphy
Last active November 23, 2017 07:25
Show Gist options
  • Save uphy/bc1d4586273faf1d547b72a84ef74944 to your computer and use it in GitHub Desktop.
Save uphy/bc1d4586273faf1d547b72a84ef74944 to your computer and use it in GitHub Desktop.
/**
* Copyright (C) 2016 uphy.jp
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.net.ssl.HttpsURLConnection;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* @author Yuhi Ishikura
*/
public class WebDavExample {
public static void main(String[] args) throws Throwable {
final URL url = new URL("http://localhost:8000");
final WebDavClient client = new WebDavClient();
for (WebDavLink link : client.list(url)) {
System.out.println(link);
}
}
static class WebDavClient {
List<WebDavLink> list(URL url) throws IOException {
final HttpURLConnection con = (HttpURLConnection)url.openConnection();
//con.setRequestMethod("PROPFIND"); // not supported
setHttpRequestMethod(con, "PROPFIND");
final List<WebDavLink> links = new ArrayList<>();
try {
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(con.getInputStream());
final XPath xpath = XPathFactory.newInstance().newXPath();
final NodeList responseList = (NodeList)xpath.evaluate("//multistatus/response", doc, XPathConstants.NODESET);
for (int i = 0; i < responseList.getLength(); i++) {
final Element response = (Element)responseList.item(i);
final String href = (String)xpath.evaluate("href/text()", response, XPathConstants.STRING);
final Element propstat = (Element)xpath.evaluate("propstat", response, XPathConstants.NODE);
final Element prop = (Element)xpath.evaluate("prop", propstat, XPathConstants.NODE);
final Element collectionResourceTypeNode = (Element)xpath.evaluate("resourcetype/collection", prop, XPathConstants.NODE);
final String lastModified = (String)xpath.evaluate("getlastmodified/text()", prop, XPathConstants.STRING);
final String status = (String)xpath.evaluate("status/text()", propstat, XPathConstants.STRING);
final boolean isDirectory = collectionResourceTypeNode != null;
if (isDirectory) {
links.add(WebDavLink.createDirectory(url, href, lastModified, status));
} else {
final long contentLength = ((Number)xpath.evaluate("getcontentlength/text()", prop, XPathConstants.NUMBER)).longValue();
final String contentType = (String)xpath.evaluate("getcontenttype/text()", prop, XPathConstants.STRING);
links.add(WebDavLink.createFile(url, href, lastModified, status, contentType, contentLength));
}
}
} catch (ParserConfigurationException e) {
throw new IOException(e);
} catch (IOException e) {
throw new IOException(e);
} catch (XPathExpressionException e) {
throw new IOException(e);
} catch (SAXException e) {
throw new IOException(e);
} finally {
con.disconnect();
}
return links;
}
private static void setHttpRequestMethod(HttpURLConnection httpURLConnection, String method) {
try {
httpURLConnection.setRequestMethod(method);
} catch (final ProtocolException pe) {
try {
final Class<?> httpURLConnectionClass = httpURLConnection
.getClass();
final Class<?> parentClass = httpURLConnectionClass
.getSuperclass();
final Field methodField;
if (parentClass == HttpsURLConnection.class) {
methodField = parentClass.getSuperclass().getDeclaredField(
"method");
} else {
methodField = parentClass.getDeclaredField("method");
}
methodField.setAccessible(true);
methodField.set(httpURLConnection, method);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}
}
static class WebDavLink {
private URL parent;
private String href;
private String lastModified;
private String status;
private boolean directory;
private long contentLength;
private String contentType;
static WebDavLink createDirectory(URL parent, String href, String lastModified, String status) {
final WebDavLink link = new WebDavLink(parent, href, lastModified, status);
link.directory = true;
return link;
}
static WebDavLink createFile(URL parent, String href, String lastModified, String status, String contentType, long contentLength) {
final WebDavLink link = new WebDavLink(parent, href, lastModified, status);
link.directory = false;
link.contentLength = contentLength;
link.contentType = contentType;
return link;
}
private WebDavLink(final URL parent, final String href, final String lastModified, final String status) {
this.parent = parent;
this.href = href;
this.lastModified = lastModified;
this.status = status;
}
public String getStatus() {
return status;
}
public String getHref() {
return href;
}
public URL getLink() {
try {
return new URL(this.parent, this.href);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public String getLastModified() {
return lastModified;
}
public boolean isDirectory() {
return directory;
}
public long getContentLength() {
return contentLength;
}
public String getContentType() {
return contentType;
}
@Override
public String toString() {
return String.format("WebDavLink[href='%s', lastModified='%s', status='%s', directory=%s, contentLength=%d, contentType='%s']", href, lastModified, status, directory, contentLength, contentType);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment