You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2008/09/29 14:32:29 UTC
svn commit: r700097 [1/2] - in /jackrabbit/trunk: jackrabbit-jcr-server/
jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/
jackrabbit-webapp/src/main/webapp/ jackrabbit-webdav/
jackrabbit-webdav/src/main/java/org/apache/jackrabbi...
Author: reschke
Date: Mon Sep 29 05:32:28 2008
New Revision: 700097
URL: http://svn.apache.org/viewvc?rev=700097&view=rev
Log:
JCR-1733: add support for WebDAV BIND protocol to simple webdav servlet, includes client compontents and test cases (requires the o.a.j.api.jsr283 extensions for shareable node support as defined in JSR-283)
Added:
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindConstants.java (with props)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindInfo.java (with props)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindableResource.java (with props)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentElement.java (with props)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentSet.java (with props)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/RebindInfo.java (with props)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/UnbindInfo.java (with props)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/BindMethod.java (with props)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/UnbindMethod.java (with props)
Modified:
jackrabbit/trunk/jackrabbit-jcr-server/pom.xml
jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java (contents, props changed)
jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DeltaVResourceImpl.java
jackrabbit/trunk/jackrabbit-webapp/src/main/webapp/webdav-simple.jsp
jackrabbit/trunk/jackrabbit-webdav/README.txt
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavMethods.java (contents, props changed)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequest.java (contents, props changed)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java (contents, props changed)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/property/DavPropertyName.java (contents, props changed)
jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java
jackrabbit/trunk/jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/server/BindTest.java
Modified: jackrabbit/trunk/jackrabbit-jcr-server/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/pom.xml?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/pom.xml (original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/pom.xml Mon Sep 29 05:32:28 2008
@@ -66,6 +66,11 @@
<artifactId>jcr</artifactId>
</dependency>
<dependency>
+ <!-- temporarily added dependency, needed as long as JCR2 interfaces are contained in jackrabbit-api -->
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-jcr-commons</artifactId>
</dependency>
Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java Mon Sep 29 05:32:28 2008
@@ -39,6 +39,10 @@
import org.apache.jackrabbit.webdav.DavServletResponse;
import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
+import org.apache.jackrabbit.webdav.bind.BindConstants;
+import org.apache.jackrabbit.webdav.bind.BindableResource;
+import org.apache.jackrabbit.webdav.bind.ParentSet;
+import org.apache.jackrabbit.webdav.bind.ParentElement;
import org.apache.jackrabbit.webdav.io.InputContext;
import org.apache.jackrabbit.webdav.io.OutputContext;
import org.apache.jackrabbit.webdav.jcr.JcrDavException;
@@ -69,6 +73,7 @@
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import javax.jcr.Workspace;
import javax.jcr.lock.Lock;
import java.io.IOException;
import java.io.OutputStream;
@@ -78,17 +83,22 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
/**
* DavResourceImpl implements a DavResource.
*/
-public class DavResourceImpl implements DavResource, JcrConstants {
+public class DavResourceImpl implements DavResource, BindableResource, JcrConstants {
/**
* the default logger
*/
private static final Logger log = LoggerFactory.getLogger(DavResourceImpl.class);
+ public static final String METHODS = DavResource.METHODS + ", " + BindConstants.METHODS;
+ public static final String COMPLIANCE_CLASS = DavResource.COMPLIANCE_CLASS + ", " + BindConstants.COMPLIANCE_CLASS;
+
private DavResourceFactory factory;
private LockManager lockManager;
private JcrDavSession session;
@@ -196,7 +206,7 @@
*/
private void initRfc4122Uri() {
try {
- if (node.isNodeType("mix:referenceable")) {
+ if (node.isNodeType(MIX_REFERENCEABLE)) {
String uuid = node.getUUID();
try {
UUID.fromString(uuid);
@@ -215,7 +225,7 @@
* @see org.apache.jackrabbit.webdav.DavResource#getComplianceClass()
*/
public String getComplianceClass() {
- return DavResource.COMPLIANCE_CLASS;
+ return COMPLIANCE_CLASS;
}
/**
@@ -223,7 +233,7 @@
* @see org.apache.jackrabbit.webdav.DavResource#getSupportedMethods()
*/
public String getSupportedMethods() {
- return DavResource.METHODS;
+ return METHODS;
}
/**
@@ -369,7 +379,12 @@
}
if (rfc4122Uri != null) {
- properties.add(new HrefProperty(DavPropertyName.RESOURCEID, rfc4122Uri, true));
+ properties.add(new HrefProperty(BindConstants.RESOURCEID, rfc4122Uri, true));
+ }
+
+ Set parentElements = this.getParentElements();
+ if (!parentElements.isEmpty()) {
+ properties.add(new ParentSet(parentElements));
}
/* set current lock information. If no lock is set to this resource,
@@ -612,7 +627,13 @@
try {
String itemPath = member.getLocator().getRepositoryPath();
Item memItem = getJcrSession().getItem(itemPath);
- memItem.remove();
+ //TODO once jcr2 is out: simply call removeShare()
+ if (memItem instanceof org.apache.jackrabbit.api.jsr283.Node) {
+ org.apache.jackrabbit.api.jsr283.Node n = (org.apache.jackrabbit.api.jsr283.Node) memItem;
+ n.removeShare();
+ } else {
+ memItem.remove();
+ }
getJcrSession().save();
// make sure, non-jcr locks are removed, once the removal is completed
@@ -836,6 +857,98 @@
return session;
}
+
+ /**
+ * @see BindableResource#rebind(DavResource, DavResource)
+ */
+ public void bind(DavResource collection, DavResource newBinding) throws DavException {
+ if (!exists()) {
+ //DAV:bind-source-exists
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED);
+ }
+ if (isLocked(collection)) {
+ //DAV:locked-update-allowed?
+ throw new DavException(DavServletResponse.SC_LOCKED);
+ }
+ if (isFilteredResource(newBinding)) {
+ throw new DavException(DavServletResponse.SC_FORBIDDEN);
+ }
+ checkSameWorkspace(collection.getLocator());
+ try {
+ if (!this.node.isNodeType(MIX_SHAREABLE)) {
+ if (!this.node.canAddMixin(MIX_SHAREABLE)) {
+ //DAV:binding-allowed
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED);
+ }
+ this.node.addMixin(MIX_SHAREABLE);
+ this.node.save();
+ }
+ Workspace workspace = this.session.getRepositorySession().getWorkspace();
+ workspace.clone(workspace.getName(), this.node.getPath(), newBinding.getLocator().getRepositoryPath(), false);
+
+ } catch (RepositoryException e) {
+ throw new JcrDavException(e);
+ }
+
+ }
+
+ /**
+ * @see BindableResource#rebind(DavResource, DavResource)
+ */
+ public void rebind(DavResource collection, DavResource newBinding) throws DavException {
+ if (!exists()) {
+ //DAV:rebind-source-exists
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED);
+ }
+ if (isLocked(this)) {
+ //DAV:protected-source-url-deletion.allowed
+ throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED);
+ }
+ if (isLocked(collection)) {
+ //DAV:locked-update-allowed?
+ throw new DavException(DavServletResponse.SC_LOCKED);
+ }
+ if (isFilteredResource(newBinding)) {
+ throw new DavException(DavServletResponse.SC_FORBIDDEN);
+ }
+ checkSameWorkspace(collection.getLocator());
+ try {
+ if (!this.node.isNodeType(MIX_REFERENCEABLE)) {
+ throw new DavException(this.node.canAddMixin(MIX_REFERENCEABLE)?
+ DavServletResponse.SC_CONFLICT : DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ }
+ getJcrSession().getWorkspace().move(locator.getRepositoryPath(), newBinding.getLocator().getRepositoryPath());
+ } catch (RepositoryException e) {
+ throw new JcrDavException(e);
+ }
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.bind.BindableResource#getParentElements()
+ */
+ public Set getParentElements() {
+ try {
+ //TODO remove this check once jcr2 is out
+ if (!(this.node instanceof org.apache.jackrabbit.api.jsr283.Node)) {
+ DavResourceLocator loc = this.locator.getFactory().createResourceLocator(
+ this.locator.getPrefix(), this.locator.getWorkspacePath(), this.node.getParent().getPath(), false);
+ return Collections.singleton(new ParentElement(loc.getHref(true), this.node.getName()));
+ }
+ Set ps = new HashSet();
+ NodeIterator sharedSetIterator = ((org.apache.jackrabbit.api.jsr283.Node) this.node).getSharedSet();
+ while (sharedSetIterator.hasNext()) {
+ Node sharednode = sharedSetIterator.nextNode();
+ DavResourceLocator loc = this.locator.getFactory().createResourceLocator(
+ this.locator.getPrefix(), this.locator.getWorkspacePath(), sharednode.getParent().getPath(), false);
+ ps.add(new ParentElement(loc.getHref(true), sharednode.getName()));
+ }
+ return ps;
+ } catch (RepositoryException e) {
+ log.warn("unable to calculate parent set", e);
+ return Collections.EMPTY_SET;
+ }
+ }
+
/**
* Returns the node that is wrapped by this resource.
*
Propchange: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java
('svn' removed)
Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DeltaVResourceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DeltaVResourceImpl.java?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DeltaVResourceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DeltaVResourceImpl.java Mon Sep 29 05:32:28 2008
@@ -32,6 +32,7 @@
import org.apache.jackrabbit.webdav.DavServletResponse;
import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.DavCompliance;
+import org.apache.jackrabbit.webdav.bind.BindConstants;
import org.apache.jackrabbit.webdav.property.DavProperty;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.HrefProperty;
@@ -77,7 +78,8 @@
DavCompliance._2_,
DavCompliance.VERSION_CONTROL,
DavCompliance.VERSION_HISTORY,
- DavCompliance.LABEL
+ DavCompliance.LABEL,
+ BindConstants.COMPLIANCE_CLASS,
});
}
Modified: jackrabbit/trunk/jackrabbit-webapp/src/main/webapp/webdav-simple.jsp
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webapp/src/main/webapp/webdav-simple.jsp?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-webapp/src/main/webapp/webdav-simple.jsp (original)
+++ jackrabbit/trunk/jackrabbit-webapp/src/main/webapp/webdav-simple.jsp Mon Sep 29 05:32:28 2008
@@ -28,7 +28,7 @@
<p>
The default WebDAV server (aka: Simple Server) is a
- <a href="http://www.ietf.org/rfc/rfc2518.txt">DAV1,2</a> and
+ <a href="http://www.ietf.org/rfc/rfc2518.txt">DAV 1,2</a> and
<a href="http://www.ietf.org/rfc/rfc3253.txt">DeltaV</a>
compliant WebDAV server implementation. It offers a file-based view to
the JCR repository, suitable for everybody looking for standard WebDAV
@@ -71,6 +71,7 @@
<ul>
<li><a href="http://www.ietf.org/rfc/rfc2518.txt">RFC 2518</a> (WebDAV 1,2)</li>
<li><a href="http://www.ietf.org/rfc/rfc3253.txt">RFC 3253</a> (DeltaV)</li>
+<li>Experimental: <a href="http://greenbytes.de/tech/webdav/draft-ietf-webdav-bind-latest.html">draft-ietf-webdav-bind</a> (WebDAV BIND)</li>
</ul>
<h3>Configuration</h3>
Modified: jackrabbit/trunk/jackrabbit-webdav/README.txt
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/README.txt?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/README.txt (original)
+++ jackrabbit/trunk/jackrabbit-webdav/README.txt Mon Sep 29 05:32:28 2008
@@ -11,6 +11,7 @@
* RFC 3648 (Ordered Collections Protocol)
* RFC 3744 (Access Control Protocol)
* DAV Searching and Locating (DASL)
+ * Binding Extensions to Web Distributed Authoring and Versioning (WebDAV) (experimental)
In addition this library defines (unspecified)
@@ -82,9 +83,9 @@
================
Q: Which WebDAV features are supported?
-A: DAV1,2, DeltaV, Ordering, Access Control, Search
+A: DAV 1, 2, DeltaV, Ordering, Access Control, Search, Bind
-Q: This this WebDAV libarary provide a full dav server?
+Q: This this WebDAV library provide a full dav server?
A: This library only defines interfaces, utilities and common
classes used for a dav server/client.
A JCR specific implementation can be found in the 'jcr-server'
Modified: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavMethods.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavMethods.java?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavMethods.java (original)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavMethods.java Mon Sep 29 05:32:28 2008
@@ -262,6 +262,27 @@
public static final String METHOD_ACL = "ACL";
/**
+ * The webdav REBIND method and public constant defined by
+ * the BIND specification
+ */
+ public static final int DAV_REBIND = DAV_ACL + 1;
+ public static final String METHOD_REBIND = "REBIND";
+
+ /**
+ * The webdav UNBIND method and public constant defined by
+ * the BIND specification
+ */
+ public static final int DAV_UNBIND = DAV_REBIND + 1;
+ public static final String METHOD_UNBIND = "UNBIND";
+
+ /**
+ * The webdav BIND method and public constant defined by
+ * the BIND specification
+ */
+ public static final int DAV_BIND = DAV_UNBIND + 1;
+ public static final String METHOD_BIND = "BIND";
+
+ /**
* Returns webdav method type code, error result <= 0
* Valid type codes > 0
*/
@@ -314,6 +335,9 @@
addMethodCode(METHOD_BASELINE_CONTROL, DAV_BASELINE_CONTROL);
addMethodCode(METHOD_MKACTIVITY, DAV_MKACTIVITY);
addMethodCode(METHOD_ACL, DAV_ACL);
+ addMethodCode(METHOD_REBIND, DAV_REBIND);
+ addMethodCode(METHOD_UNBIND, DAV_UNBIND);
+ addMethodCode(METHOD_BIND, DAV_BIND);
labelMethods = new int[] { DAV_GET, DAV_HEAD, DAV_OPTIONS, DAV_PROPFIND,
DAV_LABEL, DAV_COPY };
@@ -381,4 +405,4 @@
}
return false;
}
-}
\ No newline at end of file
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavMethods.java
('svn' removed)
Modified: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequest.java?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequest.java (original)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequest.java Mon Sep 29 05:32:28 2008
@@ -20,6 +20,7 @@
import org.apache.jackrabbit.webdav.ordering.OrderingDavServletRequest;
import org.apache.jackrabbit.webdav.transaction.TransactionDavServletRequest;
import org.apache.jackrabbit.webdav.version.DeltaVServletRequest;
+import org.apache.jackrabbit.webdav.bind.BindServletRequest;
/**
* The empty <code>WebdavRequest</code> interface collects the functionality
@@ -30,5 +31,6 @@
*/
public interface WebdavRequest extends DavServletRequest,
ObservationDavServletRequest, OrderingDavServletRequest,
- TransactionDavServletRequest, DeltaVServletRequest {
-}
\ No newline at end of file
+ TransactionDavServletRequest, DeltaVServletRequest,
+ BindServletRequest {
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequest.java
('svn' removed)
Modified: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java Mon Sep 29 05:32:28 2008
@@ -45,6 +45,9 @@
import org.apache.jackrabbit.webdav.version.report.ReportInfo;
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.apache.jackrabbit.webdav.bind.RebindInfo;
+import org.apache.jackrabbit.webdav.bind.UnbindInfo;
+import org.apache.jackrabbit.webdav.bind.BindInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
@@ -189,6 +192,59 @@
}
/**
+ * Parse a href and return the path of the resource.
+ *
+ * @return path of the resource identified by the href.
+ * @see org.apache.jackrabbit.webdav.bind.BindServletRequest#getHrefLocator
+ */
+ public DavResourceLocator getHrefLocator(String href) throws DavException {
+ String ref = href;
+ if (ref != null) {
+ //href should be a Simple-ref production as defined in RFC4918, so it is either an absolute URI
+ //or an absoltute path
+ try {
+ URI uri = new URI(ref);
+ String auth = uri.getAuthority();
+ ref = uri.getRawPath();
+ if (auth == null) {
+ //verify that href is an absolute path
+ if (ref.startsWith("//") || !ref.startsWith("/")) {
+ log.warn("expected absolute path but found " + ref);
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ } else if (!auth.equals(httpRequest.getHeader("Host"))) {
+ //this looks like an unsupported cross-server operation, but of course a reverse-proxy
+ //might have rewritten the Host header. Since we can't find out, we have to reject anyway.
+ //Better use absolute paths in DAV:href elements!
+ throw new DavException(DavServletResponse.SC_FORBIDDEN);
+ }
+ } catch (URISyntaxException e) {
+ log.warn("malformed uri: " + href, e);
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ // cut off the context path
+ String contextPath = httpRequest.getContextPath();
+ if (ref.startsWith(contextPath)) {
+ ref = ref.substring(contextPath.length());
+ } else {
+ //absolute path has to start with contextpath
+ throw new DavException(DavServletResponse.SC_FORBIDDEN);
+ }
+ }
+ return factory.createResourceLocator(hrefPrefix, ref);
+ }
+
+ /**
+ * Returns the path of the member resource of the request resource which is identified by the segment parameter.
+ *
+ * @return path of internal member resource.
+ */
+ public DavResourceLocator getMemberLocator(String segment) {
+ String path = (this.getRequestLocator().getHref(true) + segment).substring(hrefPrefix.length());
+ return factory.createResourceLocator(hrefPrefix, path);
+ }
+
+ /**
* Return true if the overwrite header does not inhibit overwriting.
*
* @return true if the overwrite header requests 'overwriting'
@@ -726,6 +782,42 @@
return info;
}
+ /**
+ * @see org.apache.jackrabbit.webdav.bind.BindServletRequest#getRebindInfo()
+ */
+ public RebindInfo getRebindInfo() throws DavException {
+ RebindInfo info = null;
+ Document requestDocument = getRequestDocument();
+ if (requestDocument != null) {
+ info = RebindInfo.createFromXml(requestDocument.getDocumentElement());
+ }
+ return info;
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.bind.BindServletRequest#getUnbindInfo()
+ */
+ public UnbindInfo getUnbindInfo() throws DavException {
+ UnbindInfo info = null;
+ Document requestDocument = getRequestDocument();
+ if (requestDocument != null) {
+ info = UnbindInfo.createFromXml(requestDocument.getDocumentElement());
+ }
+ return info;
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.bind.BindServletRequest#getBindInfo()
+ */
+ public BindInfo getBindInfo() throws DavException {
+ BindInfo info = null;
+ Document requestDocument = getRequestDocument();
+ if (requestDocument != null) {
+ info = BindInfo.createFromXml(requestDocument.getDocumentElement());
+ }
+ return info;
+ }
+
//---------------------------------------< HttpServletRequest interface >---
public String getAuthType() {
return httpRequest.getAuthType();
@@ -926,4 +1018,4 @@
public String getRealPath(String s) {
return httpRequest.getRealPath(s);
}
-}
\ No newline at end of file
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java
('svn' removed)
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindConstants.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindConstants.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindConstants.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.bind;
+
+import org.apache.jackrabbit.webdav.xml.Namespace;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+
+/**
+ * <code>BindConstants</code> provide constants for request and response
+ * headers, Xml elements and property names defined by
+ * the BIND specification.
+ */
+public interface BindConstants {
+
+ /**
+ * The namespace
+ */
+ public static final Namespace NAMESPACE = DavConstants.NAMESPACE;
+
+ /**
+ * local names of XML elements used in the request bodies of the methods BIND, REBIND and UNBIND.
+ */
+ public static final String XML_BIND = "bind";
+ public static final String XML_REBIND = "rebind";
+ public static final String XML_UNBIND = "unbind";
+ public static final String XML_SEGMENT = "segment";
+ public static final String XML_HREF = "href";
+ public static final String XML_PARENT = "parent";
+
+ public static final String METHODS = "BIND, REBIND, UNBIND";
+
+ public static final String COMPLIANCE_CLASS = "bind";
+
+ /*
+ * Webdav properties defined by the BIND specification.
+ */
+ public static final DavPropertyName RESOURCEID = DavPropertyName.create("resource-id");
+ public static final DavPropertyName PARENTSET = DavPropertyName.create("parent-set");
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindInfo.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindInfo.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindInfo.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.bind;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+public class BindInfo implements XmlSerializable {
+
+ private static Logger log = LoggerFactory.getLogger(BindInfo.class);
+
+ private String segment;
+ private String href;
+
+ public BindInfo(String href, String segment) {
+ this.href = href;
+ this.segment = segment;
+ }
+
+ public String getHref() {
+ return this.href;
+ }
+
+ public String getSegment() {
+ return this.segment;
+ }
+
+ /**
+ * Build an <code>BindInfo</code> object from the root element present
+ * in the request body.
+ *
+ * @param root the root element of the request body
+ * @return a BindInfo object containing segment and href
+ * @throws org.apache.jackrabbit.webdav.DavException if the BIND request is malformed
+ */
+ public static BindInfo createFromXml(Element root) throws DavException {
+ if (!DomUtil.matches(root, BindConstants.XML_BIND, BindConstants.NAMESPACE)) {
+ log.warn("DAV:bind element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ String href = null;
+ String segment = null;
+ ElementIterator it = DomUtil.getChildren(root);
+ while (it.hasNext()) {
+ Element elt = it.nextElement();
+ if (DomUtil.matches(elt, BindConstants.XML_SEGMENT, BindConstants.NAMESPACE)) {
+ if (segment == null) {
+ segment = DomUtil.getText(elt);
+ } else {
+ log.warn("unexpected multiple occurence of DAV:segment element");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ } else if (DomUtil.matches(elt, BindConstants.XML_HREF, BindConstants.NAMESPACE)) {
+ if (href == null) {
+ href = DomUtil.getText(elt);
+ } else {
+ log.warn("unexpected multiple occurence of DAV:href element");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ } else {
+ log.warn("unexpected element " + elt.getLocalName());
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ }
+ if (href == null) {
+ log.warn("DAV:href element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ if (segment == null) {
+ log.warn("DAV:segment element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ return new BindInfo(href, segment);
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.xml.XmlSerializable#toXml(org.w3c.dom.Document)
+ */
+ public Element toXml(Document document) {
+ Element bindElt = DomUtil.createElement(document, BindConstants.XML_BIND, BindConstants.NAMESPACE);
+ Element hrefElt = DomUtil.createElement(document, BindConstants.XML_HREF, BindConstants.NAMESPACE, this.href);
+ Element segElt = DomUtil.createElement(document, BindConstants.XML_SEGMENT, BindConstants.NAMESPACE, this.segment);
+ bindElt.appendChild(hrefElt);
+ bindElt.appendChild(segElt);
+ return bindElt;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindableResource.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindableResource.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindableResource.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindableResource.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.bind;
+
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavResource;
+
+import java.util.Collection;
+import java.util.Set;
+
+public interface BindableResource {
+
+ /**
+ * Will add a new binding to the given collection referencing this resource.
+ *
+ * @param collection the collection to create the new binding in.
+ * @param newBinding the new binding
+ */
+ public void bind(DavResource collection, DavResource newBinding) throws DavException;
+
+ /**
+ * Will rebind the resource to the given collection. By definition, this is an atomic move operation.
+ *
+ * @param collection the collection to create the new binding in.
+ * @param newBinding the new binding
+ */
+ public void rebind(DavResource collection, DavResource newBinding) throws DavException;
+
+ /**
+ * Will retrieve a collection of parent elements of the bindable resource representing the parent set.
+ *
+ * @return newBinding the new binding
+ */
+ public Set getParentElements();
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/BindableResource.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentElement.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentElement.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentElement.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentElement.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.bind;
+
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <code>ParentElement</code> wraps en element of the parent set of a resource. A <code>java.util.Set</code> of
+ * <code>ParentElement</code> objects may serve as the value object of the <code>ParentSet</code> DavProperty.
+ */
+public class ParentElement implements XmlSerializable {
+
+ private static Logger log = LoggerFactory.getLogger(ParentElement.class);
+
+ private final String href;
+ private final String segment;
+
+ public ParentElement(String href, String segment) {
+ this.href = href;
+ this.segment = segment;
+ }
+
+ public String getHref() {
+ return this.href;
+ }
+
+ public String getSegment() {
+ return this.segment;
+ }
+
+ /**
+ * Build an <code>ParentElement</code> object from an XML element DAV:parent
+ *
+ * @param root the DAV:parent element
+ * @return a ParentElement object
+ * @throws org.apache.jackrabbit.webdav.DavException if the DAV:parent element is malformed
+ */
+ public static ParentElement createFromXml(Element root) throws DavException {
+ if (!DomUtil.matches(root, BindConstants.XML_PARENT, BindConstants.NAMESPACE)) {
+ log.warn("DAV:paret element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ String href = null;
+ String segment = null;
+ ElementIterator it = DomUtil.getChildren(root);
+ while (it.hasNext()) {
+ Element elt = it.nextElement();
+ if (DomUtil.matches(elt, BindConstants.XML_SEGMENT, BindConstants.NAMESPACE)) {
+ if (segment == null) {
+ segment = DomUtil.getText(elt);
+ } else {
+ log.warn("unexpected multiple occurence of DAV:segment element");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ } else if (DomUtil.matches(elt, BindConstants.XML_HREF, BindConstants.NAMESPACE)) {
+ if (href == null) {
+ href = DomUtil.getText(elt);
+ } else {
+ log.warn("unexpected multiple occurence of DAV:href element");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ } else {
+ log.warn("unexpected element " + elt.getLocalName());
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ }
+ if (href == null) {
+ log.warn("DAV:href element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ if (segment == null) {
+ log.warn("DAV:segment element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ return new ParentElement(href, segment);
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.xml.XmlSerializable#toXml(org.w3c.dom.Document)
+ */
+ public Element toXml(Document document) {
+ Element parentElt = DomUtil.createElement(document, BindConstants.XML_PARENT, BindConstants.NAMESPACE);
+ Element hrefElt = DomUtil.createElement(document, BindConstants.XML_HREF, BindConstants.NAMESPACE, this.href);
+ Element segElt = DomUtil.createElement(document, BindConstants.XML_SEGMENT, BindConstants.NAMESPACE, this.segment);
+ parentElt.appendChild(hrefElt);
+ parentElt.appendChild(segElt);
+ return parentElt;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentElement.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentSet.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentSet.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentSet.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentSet.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.bind;
+
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <code>ParentSet</code> represents a DAV:parent-set property.
+ */
+public class ParentSet extends AbstractDavProperty {
+
+ private final Collection parents;
+
+ /**
+ * Creates a new ParentSet from a collection of <code>ParentElement</code> objects.
+ * @param parents
+ */
+ public ParentSet(Collection parents) {
+ super(BindConstants.PARENTSET, true);
+ this.parents = parents;
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.property.AbstractDavProperty#getValue()
+ */
+ public Object getValue() {
+ return this.parents;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/ParentSet.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/RebindInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/RebindInfo.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/RebindInfo.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/RebindInfo.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.bind;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+public class RebindInfo implements XmlSerializable {
+
+ private static Logger log = LoggerFactory.getLogger(RebindInfo.class);
+
+ private String segment;
+ private String href;
+
+ public RebindInfo(String href, String segment) {
+ this.href = href;
+ this.segment = segment;
+ }
+
+ public String getHref() {
+ return this.href;
+ }
+
+ public String getSegment() {
+ return this.segment;
+ }
+
+ /**
+ * Build an <code>RebindInfo</code> object from the root element present
+ * in the request body.
+ *
+ * @param root the root element of the request body
+ * @return a RebindInfo object containing segment and href
+ * @throws org.apache.jackrabbit.webdav.DavException if the REBIND request is malformed
+ */
+ public static RebindInfo createFromXml(Element root) throws DavException {
+ if (!DomUtil.matches(root, BindConstants.XML_REBIND, BindConstants.NAMESPACE)) {
+ log.warn("DAV:rebind element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ String href = null;
+ String segment = null;
+ ElementIterator it = DomUtil.getChildren(root);
+ while (it.hasNext()) {
+ Element elt = it.nextElement();
+ if (DomUtil.matches(elt, BindConstants.XML_SEGMENT, BindConstants.NAMESPACE)) {
+ if (segment == null) {
+ segment = DomUtil.getText(elt);
+ } else {
+ log.warn("unexpected multiple occurence of DAV:segment element");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ } else if (DomUtil.matches(elt, BindConstants.XML_HREF, BindConstants.NAMESPACE)) {
+ if (href == null) {
+ href = DomUtil.getText(elt);
+ } else {
+ log.warn("unexpected multiple occurence of DAV:href element");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ } else {
+ log.warn("unexpected element " + elt.getLocalName());
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ }
+ if (href == null) {
+ log.warn("DAV:href element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ if (segment == null) {
+ log.warn("DAV:segment element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ return new RebindInfo(href, segment);
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.xml.XmlSerializable#toXml(org.w3c.dom.Document)
+ */
+ public Element toXml(Document document) {
+ Element rebindElt = DomUtil.createElement(document, BindConstants.XML_REBIND, BindConstants.NAMESPACE);
+ Element hrefElt = DomUtil.createElement(document, BindConstants.XML_HREF, BindConstants.NAMESPACE, this.href);
+ Element segElt = DomUtil.createElement(document, BindConstants.XML_SEGMENT, BindConstants.NAMESPACE, this.segment);
+ rebindElt.appendChild(hrefElt);
+ rebindElt.appendChild(segElt);
+ return rebindElt;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/RebindInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/UnbindInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/UnbindInfo.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/UnbindInfo.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/UnbindInfo.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.bind;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+public class UnbindInfo implements XmlSerializable {
+
+ private static Logger log = LoggerFactory.getLogger(UnbindInfo.class);
+
+ private String segment;
+
+ private UnbindInfo() {}
+
+ public UnbindInfo(String segment) {
+ this.segment = segment;
+ }
+
+ public String getSegment() {
+ return this.segment;
+ }
+
+ /**
+ * Build an <code>UnbindInfo</code> object from the root element present
+ * in the request body.
+ *
+ * @param root the root element of the request body
+ * @return a UnbindInfo object containing a segment identifier
+ * @throws org.apache.jackrabbit.webdav.DavException if the UNBIND request is malformed
+ */
+ public static UnbindInfo createFromXml(Element root) throws DavException {
+ if (!DomUtil.matches(root, BindConstants.XML_UNBIND, BindConstants.NAMESPACE)) {
+ log.warn("DAV:unbind element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ String segment = null;
+ ElementIterator it = DomUtil.getChildren(root);
+ while (it.hasNext()) {
+ Element elt = it.nextElement();
+ if (DomUtil.matches(elt, BindConstants.XML_SEGMENT, BindConstants.NAMESPACE)) {
+ if (segment == null) {
+ segment = DomUtil.getText(elt);
+ } else {
+ log.warn("unexpected multiple occurence of DAV:segment element");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ } else {
+ log.warn("unexpected element " + elt.getLocalName());
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ }
+ if (segment == null) {
+ log.warn("DAV:segment element expected");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ }
+ return new UnbindInfo(segment);
+ }
+
+ /**
+ * @see org.apache.jackrabbit.webdav.xml.XmlSerializable#toXml(org.w3c.dom.Document)
+ */
+ public Element toXml(Document document) {
+ Element unbindElt = DomUtil.createElement(document, BindConstants.XML_UNBIND, BindConstants.NAMESPACE);
+ Element segElt = DomUtil.createElement(document, BindConstants.XML_SEGMENT, BindConstants.NAMESPACE, this.segment);
+ unbindElt.appendChild(segElt);
+ return unbindElt;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/bind/UnbindInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/BindMethod.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/BindMethod.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/BindMethod.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/BindMethod.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.client.methods;
+
+import org.apache.jackrabbit.webdav.bind.BindInfo;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+
+import java.io.IOException;
+
+/**
+ * <code>BindMethod</code> creates a new binding to a resource.
+ */
+public class BindMethod extends DavMethodBase {
+
+ public BindMethod(String uri, BindInfo info) throws IOException {
+ super(uri);
+ setRequestBody(info);
+ }
+
+ //---------------------------------------------------------< HttpMethod >---
+ /**
+ * @see org.apache.commons.httpclient.HttpMethod#getName()
+ */
+ public String getName() {
+ return "BIND";
+ }
+
+ //------------------------------------------------------< DavMethodBase >---
+ /**
+ *
+ * @param statusCode
+ * @return true if status code is 200 (existing binding was overwritten) or 201 (new binding created).
+ */
+ protected boolean isSuccess(int statusCode) {
+ return statusCode == DavServletResponse.SC_CREATED || statusCode == DavServletResponse.SC_OK;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/BindMethod.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/UnbindMethod.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/UnbindMethod.java?rev=700097&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/UnbindMethod.java (added)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/UnbindMethod.java Mon Sep 29 05:32:28 2008
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.webdav.client.methods;
+
+import org.apache.jackrabbit.webdav.bind.UnbindInfo;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+
+import java.io.IOException;
+
+/**
+ * <code>UnbindMethod</code> removes a binding to a resource (semantically equivalent to delete).
+ */
+public class UnbindMethod extends DavMethodBase {
+
+ public UnbindMethod(String uri, UnbindInfo info) throws IOException {
+ super(uri);
+ setRequestBody(info);
+ }
+
+ //---------------------------------------------------------< HttpMethod >---
+ /**
+ * @see org.apache.commons.httpclient.HttpMethod#getName()
+ */
+ public String getName() {
+ return "UNBIND";
+ }
+
+ //------------------------------------------------------< DavMethodBase >---
+ /**
+ *
+ * @param statusCode
+ * @return true if status code is 200 (binding was removed).
+ */
+ protected boolean isSuccess(int statusCode) {
+ return statusCode == DavServletResponse.SC_OK;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/client/methods/UnbindMethod.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/property/DavPropertyName.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/property/DavPropertyName.java?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/property/DavPropertyName.java (original)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/property/DavPropertyName.java Mon Sep 29 05:32:28 2008
@@ -49,9 +49,6 @@
public static final DavPropertyName SOURCE = DavPropertyName.create(PROPERTY_SOURCE);
public static final DavPropertyName SUPPORTEDLOCK = DavPropertyName.create(PROPERTY_SUPPORTEDLOCK);
- /* webdav properties defined by the BIND specification */
- public static final DavPropertyName RESOURCEID = DavPropertyName.create(PROPERTY_RESOURCEID);
-
/* property use by microsoft that are not specified in the RFC 2518 */
public static final DavPropertyName ISCOLLECTION = DavPropertyName.create("iscollection");
Propchange: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/property/DavPropertyName.java
('svn' removed)
Modified: jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java?rev=700097&r1=700096&r2=700097&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java (original)
+++ jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java Mon Sep 29 05:32:28 2008
@@ -32,6 +32,10 @@
import org.apache.jackrabbit.webdav.WebdavRequestImpl;
import org.apache.jackrabbit.webdav.WebdavResponse;
import org.apache.jackrabbit.webdav.WebdavResponseImpl;
+import org.apache.jackrabbit.webdav.bind.RebindInfo;
+import org.apache.jackrabbit.webdav.bind.UnbindInfo;
+import org.apache.jackrabbit.webdav.bind.BindableResource;
+import org.apache.jackrabbit.webdav.bind.BindInfo;
import org.apache.jackrabbit.webdav.io.InputContext;
import org.apache.jackrabbit.webdav.io.InputContextImpl;
import org.apache.jackrabbit.webdav.io.OutputContext;
@@ -311,6 +315,15 @@
case DavMethods.DAV_ACL:
doAcl(request, response, resource);
break;
+ case DavMethods.DAV_REBIND:
+ doRebind(request, response, resource);
+ break;
+ case DavMethods.DAV_UNBIND:
+ doUnbind(request, response, resource);
+ break;
+ case DavMethods.DAV_BIND:
+ doBind(request, response, resource);
+ break;
default:
// any other method
return false;
@@ -575,7 +588,7 @@
}
DavResource destResource = getResourceFactory().createResource(request.getDestinationLocator(), request, response);
- int status = validateDestination(destResource, request);
+ int status = validateDestination(destResource, request, true);
if (status > DavServletResponse.SC_NO_CONTENT) {
response.sendError(status);
return;
@@ -598,7 +611,7 @@
DavResource resource) throws IOException, DavException {
DavResource destResource = getResourceFactory().createResource(request.getDestinationLocator(), request, response);
- int status = validateDestination(destResource, request);
+ int status = validateDestination(destResource, request, true);
if (status > DavServletResponse.SC_NO_CONTENT) {
response.sendError(status);
return;
@@ -609,6 +622,85 @@
}
/**
+ * The BIND method
+ *
+ * @param request
+ * @param response
+ * @param resource the collection resource to which a new member will be added
+ * @throws IOException
+ * @throws DavException
+ */
+ protected void doBind(WebdavRequest request, WebdavResponse response,
+ DavResource resource) throws IOException, DavException {
+
+ if (!resource.exists()) {
+ response.sendError(DavServletResponse.SC_NOT_FOUND);
+ }
+ BindInfo bindInfo = request.getBindInfo();
+ DavResource oldBinding = getResourceFactory().createResource(request.getHrefLocator(bindInfo.getHref()), request, response);
+ if (!(oldBinding instanceof BindableResource)) {
+ response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ return;
+ }
+ DavResource newBinding = getResourceFactory().createResource(request.getMemberLocator(bindInfo.getSegment()), request, response);
+ int status = validateDestination(newBinding, request, false);
+ if (status > DavServletResponse.SC_NO_CONTENT) {
+ response.sendError(status);
+ return;
+ }
+ ((BindableResource) oldBinding).bind(resource, newBinding);
+ response.setStatus(status);
+ }
+
+ /**
+ * The REBIND method
+ *
+ * @param request
+ * @param response
+ * @param resource the collection resource to which a new member will be added
+ * @throws IOException
+ * @throws DavException
+ */
+ protected void doRebind(WebdavRequest request, WebdavResponse response,
+ DavResource resource) throws IOException, DavException {
+
+ if (!resource.exists()) {
+ response.sendError(DavServletResponse.SC_NOT_FOUND);
+ }
+ RebindInfo rebindInfo = request.getRebindInfo();
+ DavResource oldBinding = getResourceFactory().createResource(request.getHrefLocator(rebindInfo.getHref()), request, response);
+ if (!(oldBinding instanceof BindableResource)) {
+ response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
+ return;
+ }
+ DavResource newBinding = getResourceFactory().createResource(request.getMemberLocator(rebindInfo.getSegment()), request, response);
+ int status = validateDestination(newBinding, request, false);
+ if (status > DavServletResponse.SC_NO_CONTENT) {
+ response.sendError(status);
+ return;
+ }
+ ((BindableResource) oldBinding).rebind(resource, newBinding);
+ response.setStatus(status);
+ }
+
+ /**
+ * The UNBIND method
+ *
+ * @param request
+ * @param response
+ * @param resource the collection resource from which a member will be removed
+ * @throws IOException
+ * @throws DavException
+ */
+ protected void doUnbind(WebdavRequest request, WebdavResponse response,
+ DavResource resource) throws IOException, DavException {
+
+ UnbindInfo unbindInfo = request.getUnbindInfo();
+ DavResource srcResource = getResourceFactory().createResource(request.getMemberLocator(unbindInfo.getSegment()), request, response);
+ resource.removeMember(srcResource);
+ }
+
+ /**
* Validate the given destination resource and return the proper status
* code: Any return value greater/equal than {@link DavServletResponse#SC_NO_CONTENT}
* indicates an error.
@@ -617,12 +709,14 @@
* @param request
* @return status code indicating whether the destination is valid.
*/
- private int validateDestination(DavResource destResource, WebdavRequest request)
+ private int validateDestination(DavResource destResource, WebdavRequest request, boolean checkHeader)
throws DavException {
- String destHeader = request.getHeader(HEADER_DESTINATION);
- if (destHeader == null || "".equals(destHeader)) {
- return DavServletResponse.SC_BAD_REQUEST;
+ if (checkHeader) {
+ String destHeader = request.getHeader(HEADER_DESTINATION);
+ if (destHeader == null || "".equals(destHeader)) {
+ return DavServletResponse.SC_BAD_REQUEST;
+ }
}
if (destResource.getLocator().equals(request.getRequestLocator())) {
return DavServletResponse.SC_FORBIDDEN;