commit - dc84d4e3207523dfebd9c47b12d2d56c87fb5ee6
commit + 7ce524315f1196f548be7dd412b2a88e8658ff6b
blob - 673a2a9aef5ecaff2c19f0317fa21de8a46d2320
blob + d7f212d12b539192e910de200ea6849244f0e8a0
--- modules/webdav/src/main/java/com/thinkberg/webdav/CopyMoveBase.java
+++ modules/webdav/src/main/java/com/thinkberg/webdav/CopyMoveBase.java
import java.text.ParseException;
/**
+ * The body of all COPY or MOVE requests. As these requests are very similar, they are handles mainly
+ * by this class. Only the actual execution using the underlying VFS backend is done in sub classes.
+ *
* @author Matthias L. Jugel
* @version $Id$
*/
public abstract class CopyMoveBase extends WebdavHandler {
+ /**
+ * Handle a COPY or MOVE request.
+ *
+ * @param request the servlet request
+ * @param response the servlet response
+ * @throws IOException if there is an error executing this request
+ */
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
boolean overwrite = getOverwrite(request);
FileObject object = VFSBackend.resolveFile(request.getPathInfo());
FileObject targetObject = getDestination(request);
-
try {
final LockManager lockManager = LockManager.getInstance();
LockManager.EvaluationResult evaluation = lockManager.evaluateCondition(targetObject, getIf(request));
return;
}
-
if (null == targetObject) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
} else {
FileObject targetParent = targetObject.getParent();
if (!targetParent.exists() ||
- !FileType.FOLDER.equals(targetParent.getType())) {
+ !FileType.FOLDER.equals(targetParent.getType())) {
response.sendError(HttpServletResponse.SC_CONFLICT);
}
response.setStatus(HttpServletResponse.SC_CREATED);
}
+ // delegate the actual execution to a sub class
copyOrMove(object, targetObject, getDepth(request));
}
+ /**
+ * Execute the actual filesystem operation. Must be implemented by sub classes.
+ *
+ * @param object the source object
+ * @param target the target object
+ * @param depth a depth for copy
+ * @throws FileSystemException if there is an error executing the request
+ */
protected abstract void copyOrMove(FileObject object, FileObject target, int depth) throws FileSystemException;
}
blob - d7233be643552cc949f8535d2bdc4aade8257493
blob + 6b9a23b2651b992848161e7e484c1a93ce95c23e
--- modules/webdav/src/main/java/com/thinkberg/webdav/PropFindHandler.java
+++ modules/webdav/src/main/java/com/thinkberg/webdav/PropFindHandler.java
* @version $Id$
*/
public class PropFindHandler extends WebdavHandler {
- private static final String TAG_MULTISTATUS = "multistatus";
- private static final String TAG_HREF = "href";
- private static final String TAG_RESPONSE = "response";
+ private static final Log LOG = LogFactory.getLog(PropFindHandler.class);
- private static final String TAG_ALLPROP = "allprop";
- private static final String TAG_PROPNAMES = "propnames";
- private static final String TAG_PROP = "prop";
-
+ // these tags are valid children elements of <propfind>
private static final List<String> VALID_PROPFIND_TAGS = Arrays.asList(
TAG_ALLPROP, TAG_PROPNAMES, TAG_PROP
);
- private static final Log LOG = LogFactory.getLog(PropFindHandler.class);
+ /**
+ * Handle a PROPFIND request.
+ *
+ * @param request the servlet request
+ * @param response the servlet response
+ * @throws IOException if there is an error that cannot be handled normally
+ */
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
SAXReader saxReader = new SAXReader();
try {
writer.close();
} else {
- LOG.error(object.getName().getPath() + " NOT FOUND");
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
break;
}
}
- private Document getMultiStatusResponse(FileObject object,
- Element propEl,
- URL baseUrl,
- int depth) throws FileSystemException {
+ /**
+ * Create a multistatus response by requesting all properties and writing a response for each
+ * the found and the non-found properties
+ *
+ * @param object the context object the propfind request applies to
+ * @param propEl the <prop> element containing the actual properties
+ * @param baseUrl the base url of this server
+ * @param depth a depth argument for how deep the find will go
+ * @return an XML document that is the response
+ * @throws FileSystemException if there was an error executing the propfind request
+ */
+ private Document getMultiStatusResponse(FileObject object, Element propEl, URL baseUrl, int depth)
+ throws FileSystemException {
Document propDoc = DocumentHelper.createDocument();
propDoc.setXMLEncoding("UTF-8");
- Element multiStatus = propDoc.addElement(TAG_MULTISTATUS, "DAV:");
+ Element multiStatus = propDoc.addElement(TAG_MULTISTATUS, NAMESPACE_DAV);
FileObject[] children = object.findFiles(new DepthFileSelector(depth));
for (FileObject child : children) {
Element responseEl = multiStatus.addElement(TAG_RESPONSE);
blob - 50f915eb7b1c5158cd909b49560628c9b14048a8
blob + 73a27bd2954d3d6a6a64a20998f1e88f6d3b69e4
--- modules/webdav/src/main/java/com/thinkberg/webdav/PropPatchHandler.java
+++ modules/webdav/src/main/java/com/thinkberg/webdav/PropPatchHandler.java
import java.util.List;
/**
- * Handle PROPPATCH requests. This currently a dummy only and will return a
- * forbidden status for any attempt to modify or remove a property.
+ * Handle PROPPATCH requests. This will set, update or remove properties from a resource
+ * or collection. Only works if the underlying VFS backend supports filesystem attributes.
*
* @author Matthias L. Jugel
*/
public class PropPatchHandler extends WebdavHandler {
private static final Log LOG = LogFactory.getLog(PropPatchHandler.class);
- private static final String TAG_MULTISTATUS = "multistatus";
- private static final String TAG_HREF = "href";
- private static final String TAG_RESPONSE = "response";
-
+ /**
+ * Handle a PROPPATCH request.
+ *
+ * @param request the servlet request
+ * @param response the servlet response
+ * @throws IOException if there is an error that cannot be handled normally
+ */
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
FileObject object = VFSBackend.resolveFile(request.getPathInfo());
}
}
- private Document getMultiStatusResponse(FileObject object, List<Element> requestedProperties, URL baseUrl) throws FileSystemException {
+ /**
+ * Get a multistatus response for each of the property set/remove requests.
+ *
+ * @param object the context object the property requests apply to
+ * @param requestedProperties the properties that should be set or removed
+ * @param baseUrl the base url of this server
+ * @return an XML document that is the response
+ * @throws FileSystemException if there is an error setting or removing a property
+ */
+ private Document getMultiStatusResponse(FileObject object, List<Element> requestedProperties, URL baseUrl)
+ throws FileSystemException {
Document propDoc = DocumentHelper.createDocument();
propDoc.setXMLEncoding("UTF-8");
- Element multiStatus = propDoc.addElement(TAG_MULTISTATUS, "DAV:");
+ Element multiStatus = propDoc.addElement(TAG_MULTISTATUS, NAMESPACE_DAV);
Element responseEl = multiStatus.addElement(TAG_RESPONSE);
try {
URL url = new URL(baseUrl, URLEncoder.encode(object.getName().getPath(), "UTF-8"));
blob - c4c58177f10fdcc3fa24ad733291fa87a7f918e5
blob + fff558b8b248571866a3aaee6facf33409cf0949
--- modules/webdav/src/main/java/com/thinkberg/webdav/WebdavHandler.java
+++ modules/webdav/src/main/java/com/thinkberg/webdav/WebdavHandler.java
static final int SC_CREATED = 201;
static final int SC_LOCKED = 423;
static final int SC_MULTI_STATUS = 207;
+ protected static final String TAG_MULTISTATUS = "multistatus";
+ protected static final String TAG_HREF = "href";
+ protected static final String TAG_RESPONSE = "response";
+ protected static final String TAG_ALLPROP = "allprop";
+ protected static final String TAG_PROPNAMES = "propnames";
+ protected static final String TAG_PROP = "prop";
+ protected static final String NAMESPACE_DAV = "DAV:";
protected static URL getBaseUrl(HttpServletRequest request) {
try {
blob - cbb3dd87be7a24c053a38ccaf2ea67fb8008746b
blob + 44d46201240bd840b72b76a41e895411c21ee520
--- modules/webdav/src/main/java/com/thinkberg/webdav/data/AbstractDavResource.java
+++ modules/webdav/src/main/java/com/thinkberg/webdav/data/AbstractDavResource.java
import java.util.List;
/**
+ * This is a DAV resource. This class mainly handles the properties associated with a resource.
+ * Please see <a href="http://www.webdav.org/specs/rfc2518.html#dav.properties">RFC2518</a> for
+ * information about necessary properties and their allowed values.
+ *
* @author Matthias L. Jugel
* @version $Id$
*/
public static final String TAG_PROP_SET = "set";
public static final String TAG_PROP_REMOVE = "remove";
- // @see http://www.webdav.org/specs/rfc2518.html#dav.properties
public static final String PROP_CREATION_DATE = "creationdate";
public static final String PROP_DISPLAY_NAME = "displayname";
public static final String PROP_GET_CONTENT_LANGUAGE = "getcontentlanguage";
public static final String PROP_SUPPORTED_LOCK = "supportedlock";
// non-standard properties
- static final String PROP_QUOTA = "quota";
- static final String PROP_QUOTA_USED = "quotaused";
- static final String PROP_QUOTA_AVAILABLE_BYTES = "quota-available-bytes";
- static final String PROP_QUOTA_USED_BYTES = "quota-used-bytes";
+ public static final String PROP_QUOTA = "quota";
+ public static final String PROP_QUOTA_USED = "quotaused";
+ public static final String PROP_QUOTA_AVAILABLE_BYTES = "quota-available-bytes";
+ public static final String PROP_QUOTA_USED_BYTES = "quota-used-bytes";
// list of standard supported properties (for allprop/propname)
public static final List<String> ALL_PROPERTIES = Arrays.asList(
this.object = object;
}
+ /**
+ * Set or remove a properties. This method expects a list of xml elements that are the
+ * properties to be set or removed. These elements must not be detached from their
+ * original <set> or <remove> parent tags to be able to determine what
+ * should be done with the property.
+ *
+ * @param root the root of the result document
+ * @param requestedProperties the list of properties to work on
+ * @return returns the root of the result document
+ */
public Element setPropertyValues(Element root, List<Element> requestedProperties) {
// initialize the <propstat> element for 200
Element okPropStatEl = root.addElement(TAG_PROPSTAT);
return root;
}
+ /**
+ * Get property values. This method expects one of either <allprop>, <propnames> or
+ * <prop>. If the element is <prop> it will go through the list of it's children
+ * and request the values. For <allprop> it will get values of all known properties and
+ * <propnames> will return the names of all known properties.
+ *
+ * @param root the root of the result document
+ * @param propertyEl the prop, propname or allprop element
+ * @return the root of the result document
+ */
public Element getPropertyValues(Element root, Element propertyEl) {
// initialize the <propstat> for 200
Element okPropStatEl = root.addElement(TAG_PROPSTAT);
return root;
}
+ /**
+ * Return a specially encoded full qualified name for a namespace and name.
+ * As HTTP headers may only contain ascii, the namespace is base64 encoded if
+ * it exists.
+ *
+ * @param nameSpace the namespace
+ * @param name the name of the property
+ * @return the encoded attribute name
+ */
protected String getFQName(String nameSpace, String name) {
String prefix = "";
if (!"DAV:".equals(nameSpace) && null != nameSpace && !"".equals(nameSpace)) {
blob - e4bf2188cc86ff140c5b178f6e57d616f5f50200
blob + b35f1546ce602c3d61da817be48f2173bde2c13d
--- modules/webdav/src/main/java/com/thinkberg/webdav/data/DavCollection.java
+++ modules/webdav/src/main/java/com/thinkberg/webdav/data/DavCollection.java
import org.dom4j.Element;
/**
+ * A DAV collection is similar to a directory.
+ *
* @author Matthias L. Jugel
* @version $Id$
*/
}
protected boolean addQuotaAvailableBytesProperty(Element root, boolean ignoreValue) {
+ // TODO add correct handling of available quota
root.addElement(PROP_QUOTA_AVAILABLE_BYTES).addText(Long.toString(Long.MAX_VALUE));
return true;
}
blob - 1b38af5d0cc408f34529520f0c39c4e41b574af3
blob + 21c179640b6c7713c45fc28e27fce2201aff5be4
--- modules/webdav/src/main/java/com/thinkberg/webdav/data/DavResource.java
+++ modules/webdav/src/main/java/com/thinkberg/webdav/data/DavResource.java
}
protected boolean addGetETagProperty(Element root, boolean ignoreValue) {
- return false;
+ root.addElement(PROP_GET_ETAG, Util.getETag(object));
+ return true;
}
protected boolean addGetLastModifiedProperty(Element root, boolean ignoreValue) {
blob - 3048290ec50e533b9e6bc29c272b59405f156dad
blob + 06d0ba45d0947de8c84d470d4bc1a1fd74c4346a
--- src/main/resources/simplelog.properties
+++ src/main/resources/simplelog.properties
#
org.apache.commons.logging.simplelog.defaultlog=error
-org.apache.commons.logging.simplelog.log.com.thinkberg.vfs.s3=debug
-org.apache.commons.logging.simplelog.log.com.thinkberg.webdav=debug
\ No newline at end of file
+org.apache.commons.logging.simplelog.log.com.thinkberg.vfs.s3=info
+org.apache.commons.logging.simplelog.log.com.thinkberg.webdav=info
\ No newline at end of file