diff --git a/pom.xml b/pom.xml
index 413a21f4..cbfe106e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
com.github.lookfirst
sardine
jar
- 5.13-SNAPSHOT
+ 5.14-SNAPSHOT
An easy to use WebDAV client for Java
Sardine WebDAV client
https://github.com/lookfirst/sardine
@@ -53,6 +53,18 @@
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 3.3.0
+
+
+ org.codehaus.mojo
+ extra-enforcer-rules
+ 1.7.0
+
+
+
org.apache.maven.plugins
maven-jar-plugin
@@ -121,6 +133,29 @@
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ enforce-bytecode-version
+
+ enforce
+
+
+
+
+ ${maven.compiler.target}
+
+ test
+
+
+
+ true
+
+
+
+
org.apache.maven.plugins
maven-jar-plugin
@@ -260,8 +295,8 @@
- 8
- 8
+ 11
+ 11
false
4.5.14
diff --git a/src/main/java/com/github/sardine/DavResource.java b/src/main/java/com/github/sardine/DavResource.java
index cb104681..ddc955aa 100644
--- a/src/main/java/com/github/sardine/DavResource.java
+++ b/src/main/java/com/github/sardine/DavResource.java
@@ -147,6 +147,18 @@ public DavResource(Response response) throws URISyntaxException
*/
private int getStatusCode(Response response)
{
+ List list = response.getPropstat();
+ for(Propstat propstat : list) {
+ if(propstat.getStatus() != null) {
+ try {
+ return BasicLineParser.parseStatusLine(propstat.getStatus(), null).getStatusCode();
+ }
+ catch(ParseException e) {
+ log.warning(String.format("Failed to parse status line: %s", propstat.getStatus()));
+ return -1;
+ }
+ }
+ }
String status = response.getStatus();
if (status == null || status.isEmpty())
{
diff --git a/src/main/java/com/github/sardine/Sardine.java b/src/main/java/com/github/sardine/Sardine.java
index d8ef72b3..d00731ee 100644
--- a/src/main/java/com/github/sardine/Sardine.java
+++ b/src/main/java/com/github/sardine/Sardine.java
@@ -86,6 +86,37 @@ public interface Sardine
*/
List list(String url, int depth, boolean allProp) throws IOException;
+ /**
+ * Gets versions listing of resource.
+ *
+ * @param url Path to the resource including protocol and hostname
+ * @throws IOException I/O error or HTTP response validation failure
+ */
+ List versionsList(String url) throws IOException;
+
+ /**
+ * Gets versions listing of resource.
+ *
+ * @param url Path to the resource including protocol and hostname
+ * @param depth The depth to look at (use 0 for single resource, 1 for directory listing,
+ * -1 for infinite recursion)
+ * @throws IOException I/O error or HTTP response validation failure
+ *
+ */
+ List versionsList(String url, int depth) throws IOException;
+
+ /**
+ * Gets versions listing of resource.
+ *
+ * @param url Path to the resource including protocol and hostname
+ * @param depth The depth to look at (use 0 for single resource, 1 for directory listing,
+ * -1 for infinite recursion)
+ * @param props Set of properties to be requested
+ * @throws IOException I/O error or HTTP response validation failure
+ *
+ */
+ List versionsList(String url, int depth, Set props) throws IOException;
+
/**
* Fetches a resource using WebDAV PROPFIND
. Only the specified properties
* are retrieved.
@@ -180,6 +211,17 @@ public interface Sardine
*/
InputStream get(String url) throws IOException;
+ /**
+ * Uses HTTP GET
to download specific version of data from a server.
+ * The stream must be closed after reading.
+ *
+ * @param url Path to the resource including protocol and hostname
+ * @param version version of resource
+ * @return Data stream to read from
+ * @throws IOException I/O error or HTTP response validation failure
+ */
+ InputStream get(String url, String version) throws IOException;
+
/**
* Uses HTTP GET
to download data from a server. The stream must be closed after reading.
*
@@ -432,6 +474,33 @@ public interface Sardine
*/
void unlock(String url, String token) throws IOException;
+ /**
+ * Put the resource under version control.
+ *
+ * @param url Path to the resource including protocol and hostname
+ * @throws IOException I/O error or HTTP response validation failure
+ */
+ void addToVersionControl(String url) throws IOException;
+
+ /**
+ * CHECKOUT request can be applied only to a checked-in version-controlled resource
+ * to allow modifications to the content and properties of that version-controlled resource.
+ *
+ * @param url Path to the checked-in, version-controlled resource including protocol and hostname
+ * @throws IOException I/O error or HTTP response validation failure
+ */
+ void checkout(String url) throws IOException;
+
+ /**
+ * CHECKIN request can be applied to a checked-out version-controlled
+ * resource to produce a new version whose content and properties
+ * are copied from the checked-out resource.
+ *
+ * @param url Path to the checked-out, version-controlled resource including protocol and hostname
+ * @throws IOException I/O error or HTTP response validation failure
+ */
+ void checkin(String url) throws IOException;
+
/**
* Read access control list for resource
*
diff --git a/src/main/java/com/github/sardine/impl/SardineImpl.java b/src/main/java/com/github/sardine/impl/SardineImpl.java
index f057640b..9decb0fa 100644
--- a/src/main/java/com/github/sardine/impl/SardineImpl.java
+++ b/src/main/java/com/github/sardine/impl/SardineImpl.java
@@ -16,64 +16,19 @@
package com.github.sardine.impl;
-import com.github.sardine.DavAce;
-import com.github.sardine.DavAcl;
-import com.github.sardine.DavPrincipal;
-import com.github.sardine.DavQuota;
-import com.github.sardine.DavResource;
-import com.github.sardine.Sardine;
-import com.github.sardine.Version;
+import com.github.sardine.*;
import com.github.sardine.impl.handler.ExistsResponseHandler;
import com.github.sardine.impl.handler.LockResponseHandler;
import com.github.sardine.impl.handler.MultiStatusResponseHandler;
import com.github.sardine.impl.handler.VoidResponseHandler;
import com.github.sardine.impl.io.ContentLengthInputStream;
import com.github.sardine.impl.io.HttpMethodReleaseInputStream;
-import com.github.sardine.impl.methods.HttpAcl;
-import com.github.sardine.impl.methods.HttpCopy;
-import com.github.sardine.impl.methods.HttpLock;
-import com.github.sardine.impl.methods.HttpMkCol;
-import com.github.sardine.impl.methods.HttpMove;
-import com.github.sardine.impl.methods.HttpPropFind;
-import com.github.sardine.impl.methods.HttpPropPatch;
-import com.github.sardine.impl.methods.HttpReport;
-import com.github.sardine.impl.methods.HttpSearch;
-import com.github.sardine.impl.methods.HttpUnlock;
-import com.github.sardine.model.Ace;
-import com.github.sardine.model.Acl;
-import com.github.sardine.model.Allprop;
-import com.github.sardine.model.Displayname;
-import com.github.sardine.model.Exclusive;
-import com.github.sardine.model.Group;
-import com.github.sardine.model.Lockinfo;
-import com.github.sardine.model.Lockscope;
-import com.github.sardine.model.Locktype;
-import com.github.sardine.model.Multistatus;
-import com.github.sardine.model.ObjectFactory;
-import com.github.sardine.model.Owner;
-import com.github.sardine.model.PrincipalCollectionSet;
-import com.github.sardine.model.PrincipalURL;
-import com.github.sardine.model.Prop;
-import com.github.sardine.model.Propertyupdate;
-import com.github.sardine.model.Propfind;
-import com.github.sardine.model.Propstat;
-import com.github.sardine.model.QuotaAvailableBytes;
-import com.github.sardine.model.QuotaUsedBytes;
-import com.github.sardine.model.Remove;
-import com.github.sardine.model.Resourcetype;
-import com.github.sardine.model.Response;
-import com.github.sardine.model.SearchRequest;
-import com.github.sardine.model.Set;
-import com.github.sardine.model.Write;
+import com.github.sardine.impl.methods.*;
+import com.github.sardine.model.*;
import com.github.sardine.report.SardineReport;
+import com.github.sardine.report.VersionTreeReport;
import com.github.sardine.util.SardineUtil;
-import org.apache.http.Consts;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHeaders;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
+import org.apache.http.*;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.NTCredentials;
@@ -84,12 +39,7 @@
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpHead;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.methods.*;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.protocol.RequestAcceptEncoding;
import org.apache.http.client.protocol.ResponseContentEncoding;
@@ -108,11 +58,7 @@
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.BasicAuthCache;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.DefaultSchemePortResolver;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SystemDefaultRoutePlanner;
@@ -139,6 +85,8 @@
import java.util.Map.Entry;
import java.util.logging.Logger;
+import static com.github.sardine.util.SardineUtil.createQNameWithDefaultNamespace;
+
/**
* Implementation of the Sardine interface. This is where the meat of the Sardine library lives.
*
@@ -414,6 +362,21 @@ public List list(String url, int depth, boolean allProp) throws IOE
}
}
+ @Override
+ public List versionsList(String url) throws IOException {
+ return versionsList(url, 0);
+ }
+
+ @Override
+ public List versionsList(String url, int depth) throws IOException {
+ return versionsList(url, depth, Collections.emptySet());
+ }
+
+ @Override
+ public List versionsList(String url, int depth, java.util.Set props) throws IOException {
+ return report(url, depth, new VersionTreeReport(props));
+ }
+
@Override
public List list(String url, int depth, java.util.Set props) throws IOException
{
@@ -643,6 +606,21 @@ public void unlock(String url, String token) throws IOException
this.execute(entity, new VoidResponseHandler());
}
+ @Override
+ public void addToVersionControl(String url) throws IOException {
+ this.execute(new HttpVersionControl(url), new VoidResponseHandler());
+ }
+
+ @Override
+ public void checkout(String url) throws IOException {
+ this.execute(new HttpCheckout(url), new VoidResponseHandler());
+ }
+
+ @Override
+ public void checkin(String url) throws IOException {
+ this.execute(new HttpCheckin(url), new VoidResponseHandler());
+ }
+
@Override
public void setAcl(String url, List aces) throws IOException
{
@@ -806,6 +784,13 @@ public ContentLengthInputStream get(String url) throws IOException
return this.get(url, Collections.emptyMap());
}
+ @Override
+ public ContentLengthInputStream get(String url, String version) throws IOException {
+ List versionHistory = propfind(url, 0, Collections.singleton(createQNameWithDefaultNamespace("version-history")));
+ String storageUrl = versionHistory.get(0).getCustomProps().get("version-history");
+ return this.get(storageUrl + version);
+ }
+
@Override
public ContentLengthInputStream get(String url, Map headers) throws IOException
{
diff --git a/src/main/java/com/github/sardine/impl/methods/HttpCheckin.java b/src/main/java/com/github/sardine/impl/methods/HttpCheckin.java
new file mode 100644
index 00000000..afba8f99
--- /dev/null
+++ b/src/main/java/com/github/sardine/impl/methods/HttpCheckin.java
@@ -0,0 +1,26 @@
+package com.github.sardine.impl.methods;
+
+import org.apache.http.client.methods.HttpRequestBase;
+
+import java.net.URI;
+
+/**
+ * Simple class for making WebDAV CHECKIN
requests.
+ */
+public class HttpCheckin extends HttpRequestBase {
+
+ public static final String METHOD_NAME = "CHECKIN";
+
+ public HttpCheckin(String uri) {
+ this(URI.create(uri));
+ }
+
+ public HttpCheckin(URI uri) {
+ this.setURI(uri);
+ }
+
+ @Override
+ public String getMethod() {
+ return METHOD_NAME;
+ }
+}
diff --git a/src/main/java/com/github/sardine/impl/methods/HttpCheckout.java b/src/main/java/com/github/sardine/impl/methods/HttpCheckout.java
new file mode 100644
index 00000000..47b5d668
--- /dev/null
+++ b/src/main/java/com/github/sardine/impl/methods/HttpCheckout.java
@@ -0,0 +1,26 @@
+package com.github.sardine.impl.methods;
+
+import org.apache.http.client.methods.HttpRequestBase;
+
+import java.net.URI;
+
+/**
+ * Simple class for making WebDAV CHECKOUT
requests.
+ */
+public class HttpCheckout extends HttpRequestBase {
+
+ public static final String METHOD_NAME = "CHECKOUT";
+
+ public HttpCheckout(String uri) {
+ this(URI.create(uri));
+ }
+
+ public HttpCheckout(URI uri) {
+ this.setURI(uri);
+ }
+
+ @Override
+ public String getMethod() {
+ return METHOD_NAME;
+ }
+}
diff --git a/src/main/java/com/github/sardine/impl/methods/HttpVersionControl.java b/src/main/java/com/github/sardine/impl/methods/HttpVersionControl.java
new file mode 100644
index 00000000..d41e8fd5
--- /dev/null
+++ b/src/main/java/com/github/sardine/impl/methods/HttpVersionControl.java
@@ -0,0 +1,26 @@
+package com.github.sardine.impl.methods;
+
+import org.apache.http.client.methods.HttpRequestBase;
+
+import java.net.URI;
+
+/**
+ * Simple class for making WebDAV VERSION-CONTROL
requests.
+ */
+public class HttpVersionControl extends HttpRequestBase {
+
+ public static final String METHOD_NAME = "VERSION-CONTROL";
+
+ public HttpVersionControl(String uri) {
+ this(URI.create(uri));
+ }
+
+ public HttpVersionControl(URI uri) {
+ this.setURI(uri);
+ }
+
+ @Override
+ public String getMethod() {
+ return METHOD_NAME;
+ }
+}
diff --git a/src/main/java/com/github/sardine/model/ObjectFactory.java b/src/main/java/com/github/sardine/model/ObjectFactory.java
index cdca00a6..1fb04008 100644
--- a/src/main/java/com/github/sardine/model/ObjectFactory.java
+++ b/src/main/java/com/github/sardine/model/ObjectFactory.java
@@ -282,6 +282,10 @@ public SyncCollection createSyncCollection() {
return new SyncCollection();
}
+ public VersionTree createVersionTree() {
+ return new VersionTree();
+ }
+
/**
* Create an instance of {@link Limit }
*
diff --git a/src/main/java/com/github/sardine/model/VersionTree.java b/src/main/java/com/github/sardine/model/VersionTree.java
new file mode 100644
index 00000000..a7cdf7b4
--- /dev/null
+++ b/src/main/java/com/github/sardine/model/VersionTree.java
@@ -0,0 +1,38 @@
+package com.github.sardine.model;
+
+import javax.xml.bind.annotation.*;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+ "prop"
+})
+@XmlRootElement(name = "version-tree")
+public class VersionTree {
+
+ @XmlElement
+ protected Prop prop;
+
+ /**
+ * Gets the value of the prop property.
+ *
+ * @return
+ * possible object is
+ * {@link Prop }
+ *
+ */
+ public Prop getProp() {
+ return prop;
+ }
+
+ /**
+ * Sets the value of the prop property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Prop }
+ *
+ */
+ public void setProp(Prop value) {
+ this.prop = value;
+ }
+}
diff --git a/src/main/java/com/github/sardine/report/VersionTreeReport.java b/src/main/java/com/github/sardine/report/VersionTreeReport.java
new file mode 100644
index 00000000..04b66870
--- /dev/null
+++ b/src/main/java/com/github/sardine/report/VersionTreeReport.java
@@ -0,0 +1,59 @@
+package com.github.sardine.report;
+
+import com.github.sardine.DavResource;
+import com.github.sardine.model.*;
+import com.github.sardine.util.SardineUtil;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+
+public class VersionTreeReport extends SardineReport>
+{
+
+ private static final Logger log = Logger.getLogger(SardineReport.class.getName());
+
+ private final Set properties;
+
+ public VersionTreeReport(Set properties)
+ {
+ this.properties = properties;
+ }
+
+ @Override
+ public Object toJaxb()
+ {
+ Prop prop = new Prop();
+ List any = prop.getAny();
+ for (QName entry : properties)
+ {
+ any.add(SardineUtil.createElement(entry));
+ }
+
+ VersionTree versionTree = new VersionTree();
+ versionTree.setProp(prop);
+ return versionTree;
+ }
+
+ @Override
+ public List fromMultistatus(Multistatus multistatus)
+ {
+ List responses = multistatus.getResponse();
+ List resources = new ArrayList(responses.size());
+ for (Response response : responses) {
+ try
+ {
+ resources.add(new DavResource(response));
+ }
+ catch (URISyntaxException e)
+ {
+ log.warning(String.format("Ignore resource with invalid URI %s", response.getHref().get(0)));
+ }
+ }
+ return resources;
+ }
+}
diff --git a/src/test/java/com/github/sardine/FunctionalSardineTest.java b/src/test/java/com/github/sardine/FunctionalSardineTest.java
index fae24e45..f1a66822 100644
--- a/src/test/java/com/github/sardine/FunctionalSardineTest.java
+++ b/src/test/java/com/github/sardine/FunctionalSardineTest.java
@@ -222,8 +222,7 @@ public void getDavQuota() throws IOException
Sardine sardine = SardineFactory.begin();
sardine.createDirectory(url);
DavQuota davQuota = sardine.getQuota(url);
- assertTrue(davQuota.getQuotaAvailableBytes() > 0);
- assertEquals(0, davQuota.getQuotaUsedBytes());
+ assertNull(davQuota);
}
@Test(expected = SardineException.class)
diff --git a/webdav.xsd b/webdav.xsd
index e7443f71..e9c3c8cf 100644
--- a/webdav.xsd
+++ b/webdav.xsd
@@ -400,6 +400,14 @@
+
+
+
+
+
+
+
+