Automated merge with https://gss.googlecode.com/hg/
[pithos] / src / gr / ebs / gss / server / webdav / Webdav.java
index 908abc6..1b29beb 100644 (file)
@@ -31,6 +31,7 @@ import gr.ebs.gss.server.domain.dto.FileBodyDTO;
 import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
 import gr.ebs.gss.server.domain.dto.FolderDTO;
 import gr.ebs.gss.server.ejb.ExternalAPI;
+import gr.ebs.gss.server.ejb.TransactionHelper;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
@@ -63,6 +64,7 @@ import java.util.Stack;
 import java.util.StringTokenizer;
 import java.util.TimeZone;
 import java.util.Vector;
+import java.util.concurrent.Callable;
 
 import javax.naming.Context;
 import javax.naming.InitialContext;
@@ -350,6 +352,23 @@ public class Webdav extends HttpServlet {
                }
        }
 
+       private void updateAccounting(final User user, final Date date, final long bandwidthDiff) {
+               try {
+                       new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                               @Override
+                               public Void call() throws Exception {
+                                       getService().updateAccounting(user, date, bandwidthDiff);
+                                       return null;
+                               }
+                       });
+               } catch (RuntimeException e) {
+                       throw e;
+               } catch (Exception e) {
+                       // updateAccounting() doesn't throw any checked exceptions
+                       assert false;
+               }
+       }
+
        @Override
        public void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
                String method = request.getMethod();
@@ -546,7 +565,7 @@ public class Webdav extends HttpServlet {
                // Create multistatus object
                XMLWriter generatedXML = new XMLWriter(resp.getWriter());
                generatedXML.writeXMLHeader();
-               generatedXML.writeElement(null, "multistatus" + generateNamespaceDeclarations(), XMLWriter.OPENING);
+               generatedXML.writeElement(null, "D:multistatus" + generateNamespaceDeclarations(), XMLWriter.OPENING);
                if (depth == 0)
                        parseProperties(req, generatedXML, path, type, properties, object);
                else {
@@ -610,7 +629,7 @@ public class Webdav extends HttpServlet {
                                generatedXML.sendData();
                        }
                }
-               generatedXML.writeElement(null, "multistatus", XMLWriter.CLOSING);
+               generatedXML.writeElement(null, "D:multistatus", XMLWriter.CLOSING);
                generatedXML.sendData();
        }
 
@@ -629,11 +648,8 @@ public class Webdav extends HttpServlet {
                resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
        }
 
-       /* (non-Javadoc)
-        * @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
-        */
        @Override
-       protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
+       protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
                if (isLocked(req)) {
                        resp.sendError(WebdavStatus.SC_LOCKED);
                        return;
@@ -670,7 +686,7 @@ public class Webdav extends HttpServlet {
                        return;
                }
 
-               User user = getUser(req);
+               final User user = getUser(req);
                String path = getRelativePath(req);
                boolean exists = true;
                Object resource = null;
@@ -722,15 +738,14 @@ public class Webdav extends HttpServlet {
                        resourceInputStream = req.getInputStream();
 
                try {
-                       FolderDTO folder = null;
                        Object parent = getService().getResourceAtPath(user.getId(), getParentPath(path), true);
                        if (!(parent instanceof FolderDTO)) {
                                resp.sendError(HttpServletResponse.SC_CONFLICT);
                                return;
                        }
-                       folder = (FolderDTO) parent;
-                       String name = getLastElement(path);
-                       String mimeType = getServletContext().getMimeType(name);
+                       final FolderDTO folder = (FolderDTO) parent;
+                       final String name = getLastElement(path);
+                       final String mimeType = getServletContext().getMimeType(name);
                File uploadedFile = null;
                try {
                                uploadedFile = getService().uploadFile(resourceInputStream, user.getId());
@@ -739,11 +754,23 @@ public class Webdav extends HttpServlet {
                        }
                        // FIXME: Add attributes
                        FileHeaderDTO fileDTO = null;
+                       final FileHeaderDTO f = file;
+                       final File uf = uploadedFile;
                        if (exists)
-                               fileDTO = getService().updateFileContents(user.getId(), file.getId(), mimeType, uploadedFile.length(), uploadedFile.getAbsolutePath());
+                               fileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
+                                       @Override
+                                       public FileHeaderDTO call() throws Exception {
+                                               return getService().updateFileContents(user.getId(), f.getId(), mimeType, uf.length(), uf.getAbsolutePath());
+                                       }
+                               });
                        else
-                               fileDTO = getService().createFile(user.getId(), folder.getId(), name, mimeType, uploadedFile.length(), uploadedFile.getAbsolutePath());
-                       getService().updateAccounting(user, new Date(), fileDTO.getFileSize());
+                               fileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
+                                       @Override
+                                       public FileHeaderDTO call() throws Exception {
+                                               return getService().createFile(user.getId(), folder.getId(), name, mimeType, uf.length(), uf.getAbsolutePath());
+                                       }
+                               });
+                       updateAccounting(user, new Date(), fileDTO.getFileSize());
                } catch (ObjectNotFoundException e) {
                        result = false;
                } catch (InsufficientPermissionsException e) {
@@ -761,6 +788,9 @@ public class Webdav extends HttpServlet {
                } catch (DuplicateNameException e) {
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
                        return;
+               } catch (Exception e) {
+                       resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
+                       return;
                }
 
                if (result) {
@@ -1061,13 +1091,13 @@ public class Webdav extends HttpServlet {
                        resp.sendError(WebdavStatus.SC_LOCKED);
                        return;
                }
-               String path = getRelativePath(req);
+               final String path = getRelativePath(req);
                if (path.toUpperCase().startsWith("/WEB-INF") || path.toUpperCase().startsWith("/META-INF")) {
                        resp.sendError(WebdavStatus.SC_FORBIDDEN);
                        return;
                }
 
-               User user = getUser(req);
+               final User user = getUser(req);
                boolean exists = true;
                try {
                        getService().getResourceAtPath(user.getId(), path, true);
@@ -1097,6 +1127,7 @@ public class Webdav extends HttpServlet {
                if (req.getInputStream().available() > 0) {
                        DocumentBuilder documentBuilder = getDocumentBuilder();
                        try {
+                               @SuppressWarnings("unused")
                                Document document = documentBuilder.parse(new InputSource(req.getInputStream()));
                                // TODO : Process this request body
                                resp.sendError(WebdavStatus.SC_NOT_IMPLEMENTED);
@@ -1111,17 +1142,23 @@ public class Webdav extends HttpServlet {
                Object parent;
                try {
                        parent = getService().getResourceAtPath(user.getId(), getParentPath(path), true);
-               } catch (ObjectNotFoundException e1) {
+               } catch (ObjectNotFoundException e) {
                        resp.sendError(WebdavStatus.SC_CONFLICT, WebdavStatus.getStatusText(WebdavStatus.SC_CONFLICT));
                        return;
-               } catch (RpcException e1) {
+               } catch (RpcException e) {
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                        return;
                }
                try {
                        if (parent instanceof FolderDTO) {
-                               FolderDTO folder = (FolderDTO) parent;
-                               getService().createFolder(user.getId(), folder.getId(), getLastElement(path));
+                               final FolderDTO folder = (FolderDTO) parent;
+                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                                       @Override
+                                       public Void call() throws Exception {
+                                               getService().createFolder(user.getId(), folder.getId(), getLastElement(path));
+                                               return null;
+                                       }
+                               });
                        } else {
                                resp.sendError(WebdavStatus.SC_FORBIDDEN, WebdavStatus.getStatusText(WebdavStatus.SC_FORBIDDEN));
                                return;
@@ -1141,6 +1178,9 @@ public class Webdav extends HttpServlet {
                } catch (RpcException e) {
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                        return;
+               } catch (Exception e) {
+                       resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
+                       return;
                }
                resp.setStatus(WebdavStatus.SC_CREATED);
        }
@@ -1244,7 +1284,7 @@ public class Webdav extends HttpServlet {
         * @return the namespace declarations
         */
        private String generateNamespaceDeclarations() {
-               return " xmlns=\"" + DEFAULT_NAMESPACE + "\"";
+               return " xmlns:D=\"" + DEFAULT_NAMESPACE + "\"";
        }
 
        /**
@@ -1301,11 +1341,11 @@ public class Webdav extends HttpServlet {
                else
                        modification = file.getAuditInfo().getCreationDate().getTime();
 
-               generatedXML.writeElement(null, "response", XMLWriter.OPENING);
+               generatedXML.writeElement(null, "D:response", XMLWriter.OPENING);
                String status = new String("HTTP/1.1 " + WebdavStatus.SC_OK + " " + WebdavStatus.getStatusText(WebdavStatus.SC_OK));
 
                // Generating href element
-               generatedXML.writeElement(null, "href", XMLWriter.OPENING);
+               generatedXML.writeElement(null, "D:href", XMLWriter.OPENING);
 
                String href = req.getContextPath() + req.getServletPath();
                if (href.endsWith("/") && path.startsWith("/"))
@@ -1317,78 +1357,80 @@ public class Webdav extends HttpServlet {
 
                generatedXML.writeText(rewriteUrl(href));
 
-               generatedXML.writeElement(null, "href", XMLWriter.CLOSING);
+               generatedXML.writeElement(null, "D:href", XMLWriter.CLOSING);
 
                String resourceName = path;
                int lastSlash = path.lastIndexOf('/');
                if (lastSlash != -1)
                        resourceName = resourceName.substring(lastSlash + 1);
+               if (resourceName.isEmpty())
+                       resourceName = "/";
 
                switch (type) {
 
                        case FIND_ALL_PROP:
 
-                               generatedXML.writeElement(null, "propstat", XMLWriter.OPENING);
-                               generatedXML.writeElement(null, "prop", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:propstat", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:prop", XMLWriter.OPENING);
 
-                               generatedXML.writeProperty(null, "creationdate", getISOCreationDate(creation));
-                               generatedXML.writeElement(null, "displayname", XMLWriter.OPENING);
+                               generatedXML.writeProperty(null, "D:creationdate", getISOCreationDate(creation));
+                               generatedXML.writeElement(null, "D:displayname", XMLWriter.OPENING);
                                generatedXML.writeData(resourceName);
-                               generatedXML.writeElement(null, "displayname", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:displayname", XMLWriter.CLOSING);
                                if (file != null) {
-                                       generatedXML.writeProperty(null, "getlastmodified", FastHttpDateFormat.formatDate(modification, null));
-                                       generatedXML.writeProperty(null, "getcontentlength", String.valueOf(file.getFileSize()));
+                                       generatedXML.writeProperty(null, "D:getlastmodified", FastHttpDateFormat.formatDate(modification, null));
+                                       generatedXML.writeProperty(null, "D:getcontentlength", String.valueOf(file.getFileSize()));
                                        String contentType = file.getMimeType();
                                        if (contentType != null)
-                                               generatedXML.writeProperty(null, "getcontenttype", contentType);
-                                       generatedXML.writeProperty(null, "getetag", getETag(file, null));
-                                       generatedXML.writeElement(null, "resourcetype", XMLWriter.NO_CONTENT);
+                                               generatedXML.writeProperty(null, "D:getcontenttype", contentType);
+                                       generatedXML.writeProperty(null, "D:getetag", getETag(file, null));
+                                       generatedXML.writeElement(null, "D:resourcetype", XMLWriter.NO_CONTENT);
                                } else {
-                                       generatedXML.writeElement(null, "resourcetype", XMLWriter.OPENING);
-                                       generatedXML.writeElement(null, "collection", XMLWriter.NO_CONTENT);
-                                       generatedXML.writeElement(null, "resourcetype", XMLWriter.CLOSING);
+                                       generatedXML.writeElement(null, "D:resourcetype", XMLWriter.OPENING);
+                                       generatedXML.writeElement(null, "D:collection", XMLWriter.NO_CONTENT);
+                                       generatedXML.writeElement(null, "D:resourcetype", XMLWriter.CLOSING);
                                }
 
-                               generatedXML.writeProperty(null, "source", "");
+                               generatedXML.writeProperty(null, "D:source", "");
 
-                               String supportedLocks = "<lockentry>" + "<lockscope><exclusive/></lockscope>" + "<locktype><write/></locktype>" + "</lockentry>" + "<lockentry>" + "<lockscope><shared/></lockscope>" + "<locktype><write/></locktype>" + "</lockentry>";
-                               generatedXML.writeElement(null, "supportedlock", XMLWriter.OPENING);
+                               String supportedLocks = "<D:lockentry>" + "<D:lockscope><D:exclusive/></D:lockscope>" + "<D:locktype><D:write/></D:locktype>" + "</D:lockentry>" + "<D:lockentry>" + "<D:lockscope><D:shared/></D:lockscope>" + "<D:locktype><D:write/></D:locktype>" + "</D:lockentry>";
+                               generatedXML.writeElement(null, "D:supportedlock", XMLWriter.OPENING);
                                generatedXML.writeText(supportedLocks);
-                               generatedXML.writeElement(null, "supportedlock", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:supportedlock", XMLWriter.CLOSING);
 
                                generateLockDiscovery(path, generatedXML);
 
-                               generatedXML.writeElement(null, "prop", XMLWriter.CLOSING);
-                               generatedXML.writeElement(null, "status", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:prop", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:status", XMLWriter.OPENING);
                                generatedXML.writeText(status);
-                               generatedXML.writeElement(null, "status", XMLWriter.CLOSING);
-                               generatedXML.writeElement(null, "propstat", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:status", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:propstat", XMLWriter.CLOSING);
 
                                break;
 
                        case FIND_PROPERTY_NAMES:
 
-                               generatedXML.writeElement(null, "propstat", XMLWriter.OPENING);
-                               generatedXML.writeElement(null, "prop", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:propstat", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:prop", XMLWriter.OPENING);
 
-                               generatedXML.writeElement(null, "creationdate", XMLWriter.NO_CONTENT);
-                               generatedXML.writeElement(null, "displayname", XMLWriter.NO_CONTENT);
+                               generatedXML.writeElement(null, "D:creationdate", XMLWriter.NO_CONTENT);
+                               generatedXML.writeElement(null, "D:displayname", XMLWriter.NO_CONTENT);
                                if (file != null) {
-                                       generatedXML.writeElement(null, "getcontentlanguage", XMLWriter.NO_CONTENT);
-                                       generatedXML.writeElement(null, "getcontentlength", XMLWriter.NO_CONTENT);
-                                       generatedXML.writeElement(null, "getcontenttype", XMLWriter.NO_CONTENT);
-                                       generatedXML.writeElement(null, "getetag", XMLWriter.NO_CONTENT);
-                                       generatedXML.writeElement(null, "getlastmodified", XMLWriter.NO_CONTENT);
+                                       generatedXML.writeElement(null, "D:getcontentlanguage", XMLWriter.NO_CONTENT);
+                                       generatedXML.writeElement(null, "D:getcontentlength", XMLWriter.NO_CONTENT);
+                                       generatedXML.writeElement(null, "D:getcontenttype", XMLWriter.NO_CONTENT);
+                                       generatedXML.writeElement(null, "D:getetag", XMLWriter.NO_CONTENT);
+                                       generatedXML.writeElement(null, "D:getlastmodified", XMLWriter.NO_CONTENT);
                                }
-                               generatedXML.writeElement(null, "resourcetype", XMLWriter.NO_CONTENT);
-                               generatedXML.writeElement(null, "source", XMLWriter.NO_CONTENT);
-                               generatedXML.writeElement(null, "lockdiscovery", XMLWriter.NO_CONTENT);
+                               generatedXML.writeElement(null, "D:resourcetype", XMLWriter.NO_CONTENT);
+                               generatedXML.writeElement(null, "D:source", XMLWriter.NO_CONTENT);
+                               generatedXML.writeElement(null, "D:lockdiscovery", XMLWriter.NO_CONTENT);
 
-                               generatedXML.writeElement(null, "prop", XMLWriter.CLOSING);
-                               generatedXML.writeElement(null, "status", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:prop", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:status", XMLWriter.OPENING);
                                generatedXML.writeText(status);
-                               generatedXML.writeElement(null, "status", XMLWriter.CLOSING);
-                               generatedXML.writeElement(null, "propstat", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:status", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:propstat", XMLWriter.CLOSING);
 
                                break;
 
@@ -1398,8 +1440,8 @@ public class Webdav extends HttpServlet {
 
                                // Parse the list of properties
 
-                               generatedXML.writeElement(null, "propstat", XMLWriter.OPENING);
-                               generatedXML.writeElement(null, "prop", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:propstat", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:prop", XMLWriter.OPENING);
 
                                Enumeration<String> properties = propertiesVector.elements();
 
@@ -1407,66 +1449,66 @@ public class Webdav extends HttpServlet {
 
                                        String property = properties.nextElement();
 
-                                       if (property.equals("creationdate"))
-                                               generatedXML.writeProperty(null, "creationdate", getISOCreationDate(creation));
-                                       else if (property.equals("displayname")) {
-                                               generatedXML.writeElement(null, "displayname", XMLWriter.OPENING);
+                                       if (property.equals("D:creationdate"))
+                                               generatedXML.writeProperty(null, "D:creationdate", getISOCreationDate(creation));
+                                       else if (property.equals("D:displayname")) {
+                                               generatedXML.writeElement(null, "D:displayname", XMLWriter.OPENING);
                                                generatedXML.writeData(resourceName);
-                                               generatedXML.writeElement(null, "displayname", XMLWriter.CLOSING);
-                                       } else if (property.equals("getcontentlanguage")) {
+                                               generatedXML.writeElement(null, "D:displayname", XMLWriter.CLOSING);
+                                       } else if (property.equals("D:getcontentlanguage")) {
                                                if (folder != null)
                                                        propertiesNotFound.addElement(property);
                                                else
-                                                       generatedXML.writeElement(null, "getcontentlanguage", XMLWriter.NO_CONTENT);
-                                       } else if (property.equals("getcontentlength")) {
+                                                       generatedXML.writeElement(null, "D:getcontentlanguage", XMLWriter.NO_CONTENT);
+                                       } else if (property.equals("D:getcontentlength")) {
                                                if (folder != null)
                                                        propertiesNotFound.addElement(property);
                                                else
-                                                       generatedXML.writeProperty(null, "getcontentlength", String.valueOf(file.getFileSize()));
-                                       } else if (property.equals("getcontenttype")) {
+                                                       generatedXML.writeProperty(null, "D:getcontentlength", String.valueOf(file.getFileSize()));
+                                       } else if (property.equals("D:getcontenttype")) {
                                                if (folder != null)
                                                        propertiesNotFound.addElement(property);
                                                else
                                                        // XXX Once we properly store the MIME type in the
                                                        // file,
                                                        // retrieve it from there.
-                                                       generatedXML.writeProperty(null, "getcontenttype", getServletContext().getMimeType(file.getName()));
-                                       } else if (property.equals("getetag")) {
+                                                       generatedXML.writeProperty(null, "D:getcontenttype", getServletContext().getMimeType(file.getName()));
+                                       } else if (property.equals("D:getetag")) {
                                                if (folder != null)
                                                        propertiesNotFound.addElement(property);
                                                else
-                                                       generatedXML.writeProperty(null, "getetag", getETag(file, null));
-                                       } else if (property.equals("getlastmodified")) {
+                                                       generatedXML.writeProperty(null, "D:getetag", getETag(file, null));
+                                       } else if (property.equals("D:getlastmodified")) {
                                                if (folder != null)
                                                        propertiesNotFound.addElement(property);
                                                else
-                                                       generatedXML.writeProperty(null, "getlastmodified", FastHttpDateFormat.formatDate(modification, null));
-                                       } else if (property.equals("resourcetype")) {
+                                                       generatedXML.writeProperty(null, "D:getlastmodified", FastHttpDateFormat.formatDate(modification, null));
+                                       } else if (property.equals("D:resourcetype")) {
                                                if (folder != null) {
-                                                       generatedXML.writeElement(null, "resourcetype", XMLWriter.OPENING);
-                                                       generatedXML.writeElement(null, "collection", XMLWriter.NO_CONTENT);
-                                                       generatedXML.writeElement(null, "resourcetype", XMLWriter.CLOSING);
+                                                       generatedXML.writeElement(null, "D:resourcetype", XMLWriter.OPENING);
+                                                       generatedXML.writeElement(null, "D:collection", XMLWriter.NO_CONTENT);
+                                                       generatedXML.writeElement(null, "D:resourcetype", XMLWriter.CLOSING);
                                                } else
-                                                       generatedXML.writeElement(null, "resourcetype", XMLWriter.NO_CONTENT);
-                                       } else if (property.equals("source"))
-                                               generatedXML.writeProperty(null, "source", "");
-                                       else if (property.equals("supportedlock")) {
-                                               supportedLocks = "<lockentry>" + "<lockscope><exclusive/></lockscope>" + "<locktype><write/></locktype>" + "</lockentry>" + "<lockentry>" + "<lockscope><shared/></lockscope>" + "<locktype><write/></locktype>" + "</lockentry>";
-                                               generatedXML.writeElement(null, "supportedlock", XMLWriter.OPENING);
+                                                       generatedXML.writeElement(null, "D:resourcetype", XMLWriter.NO_CONTENT);
+                                       } else if (property.equals("D:source"))
+                                               generatedXML.writeProperty(null, "D:source", "");
+                                       else if (property.equals("D:supportedlock")) {
+                                               supportedLocks = "<D:lockentry>" + "<D:lockscope><D:exclusive/></D:lockscope>" + "<D:locktype><D:write/></D:locktype>" + "</D:lockentry>" + "<D:lockentry>" + "<D:lockscope><D:shared/></D:lockscope>" + "<D:locktype><D:write/></D:locktype>" + "</D:lockentry>";
+                                               generatedXML.writeElement(null, "D:supportedlock", XMLWriter.OPENING);
                                                generatedXML.writeText(supportedLocks);
-                                               generatedXML.writeElement(null, "supportedlock", XMLWriter.CLOSING);
-                                       } else if (property.equals("lockdiscovery")) {
+                                               generatedXML.writeElement(null, "D:supportedlock", XMLWriter.CLOSING);
+                                       } else if (property.equals("D:lockdiscovery")) {
                                                if (!generateLockDiscovery(path, generatedXML))
                                                        propertiesNotFound.addElement(property);
                                        } else
                                                propertiesNotFound.addElement(property);
                                }
 
-                               generatedXML.writeElement(null, "prop", XMLWriter.CLOSING);
-                               generatedXML.writeElement(null, "status", XMLWriter.OPENING);
+                               generatedXML.writeElement(null, "D:prop", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:status", XMLWriter.OPENING);
                                generatedXML.writeText(status);
-                               generatedXML.writeElement(null, "status", XMLWriter.CLOSING);
-                               generatedXML.writeElement(null, "propstat", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:status", XMLWriter.CLOSING);
+                               generatedXML.writeElement(null, "D:propstat", XMLWriter.CLOSING);
 
                                Enumeration propertiesNotFoundList = propertiesNotFound.elements();
 
@@ -1474,23 +1516,23 @@ public class Webdav extends HttpServlet {
 
                                        status = new String("HTTP/1.1 " + WebdavStatus.SC_NOT_FOUND + " " + WebdavStatus.getStatusText(WebdavStatus.SC_NOT_FOUND));
 
-                                       generatedXML.writeElement(null, "propstat", XMLWriter.OPENING);
-                                       generatedXML.writeElement(null, "prop", XMLWriter.OPENING);
+                                       generatedXML.writeElement(null, "D:propstat", XMLWriter.OPENING);
+                                       generatedXML.writeElement(null, "D:prop", XMLWriter.OPENING);
 
                                        while (propertiesNotFoundList.hasMoreElements())
                                                generatedXML.writeElement(null, (String) propertiesNotFoundList.nextElement(), XMLWriter.NO_CONTENT);
-                                       generatedXML.writeElement(null, "prop", XMLWriter.CLOSING);
-                                       generatedXML.writeElement(null, "status", XMLWriter.OPENING);
+                                       generatedXML.writeElement(null, "D:prop", XMLWriter.CLOSING);
+                                       generatedXML.writeElement(null, "D:status", XMLWriter.OPENING);
                                        generatedXML.writeText(status);
-                                       generatedXML.writeElement(null, "status", XMLWriter.CLOSING);
-                                       generatedXML.writeElement(null, "propstat", XMLWriter.CLOSING);
+                                       generatedXML.writeElement(null, "D:status", XMLWriter.CLOSING);
+                                       generatedXML.writeElement(null, "D:propstat", XMLWriter.CLOSING);
                                }
 
                                break;
 
                }
 
-               generatedXML.writeElement(null, "response", XMLWriter.CLOSING);
+               generatedXML.writeElement(null, "D:response", XMLWriter.CLOSING);
 
        }
 
@@ -1513,7 +1555,7 @@ public class Webdav extends HttpServlet {
         * @param path Path which has to be rewritten
         * @return the rewritten URL
         */
-       private String rewriteUrl(String path) {
+       protected String rewriteUrl(String path) {
                return urlEncoder.encode(path);
        }
 
@@ -1577,7 +1619,7 @@ public class Webdav extends HttpServlet {
                String path = getRelativePath(req);
                if (user == null && "/".equals(path))
                        // Special case: OPTIONS request before authentication
-                       return new StringBuffer("OPTIONS, GET, HEAD, POST, DELETE, TRACE, PROPPATCH, COPY, MOVE, LOCK, UNLOCK, PROPFIND, PUT");
+                       return new StringBuffer("OPTIONS, GET, HEAD, POST, DELETE, TRACE, PROPPATCH, COPY, MOVE, LOCK, UNLOCK, PROPFIND, PUT, MKCOL");
                try {
                        object = getService().getResourceAtPath(user.getId(), path, true);
                } catch (ObjectNotFoundException e) {
@@ -1892,7 +1934,7 @@ public class Webdav extends HttpServlet {
                                        copy(file, renderResult, ostream, req, null);
                                else
                                        copy(file, renderResult, writer, req, null);
-                               getService().updateAccounting(user, new Date(), contentLength);
+                               updateAccounting(user, new Date(), contentLength);
                        }
                } else {
                        if (ranges == null || ranges.isEmpty())
@@ -1926,7 +1968,7 @@ public class Webdav extends HttpServlet {
                                                copy(file, ostream, range, req, null);
                                        else
                                                copy(file, writer, range, req, null);
-                                       getService().updateAccounting(user, new Date(), contentLength);
+                                       updateAccounting(user, new Date(), contentLength);
                                }
 
                        } else {
@@ -2269,9 +2311,6 @@ public class Webdav extends HttpServlet {
                IOException exception = null;
                InputStream resourceInputStream = null;
                User user = getUser(req);
-               // Files open for all will not have specified a calling user in the request.
-               if (user == null)
-                       user = getOwner(req);
                if (user == null)
                        throw new ObjectNotFoundException("No user or owner specified");
                if (file != null)
@@ -2339,7 +2378,7 @@ public class Webdav extends HttpServlet {
                                HttpServletRequest req, FileBodyDTO oldBody) throws IOException,
                                ObjectNotFoundException, InsufficientPermissionsException, RpcException {
                IOException exception = null;
-
+               
                User user = getUser(req);
                InputStream resourceInputStream = null;
                if (file != null)
@@ -2813,7 +2852,7 @@ public class Webdav extends HttpServlet {
         * @param size File size (in bytes)
         * @return the size as a string
         */
-       private String renderSize(long size) {
+       protected String renderSize(long size) {
                long leftSide = size / 1024;
                long rightSide = size % 1024 / 103; // Makes 1 digit
                if (leftSide == 0 && rightSide == 0 && size > 0)
@@ -2974,7 +3013,7 @@ public class Webdav extends HttpServlet {
                if (logger.isDebugEnabled())
                        logger.debug("Copy: " + source + " To: " + dest);
 
-               User user = getUser(req);
+               final User user = getUser(req);
                Object object = null;
                try {
                        object = getService().getResourceAtPath(user.getId(), source, true);
@@ -2982,9 +3021,16 @@ public class Webdav extends HttpServlet {
                }
 
                if (object instanceof FolderDTO) {
-                       FolderDTO folder = (FolderDTO) object;
+                       final FolderDTO folder = (FolderDTO) object;
                        try {
-                               getService().copyFolder(user.getId(), folder.getId(), dest);
+                               final String des = dest;
+                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                                       @Override
+                                       public Void call() throws Exception {
+                                               getService().copyFolder(user.getId(), folder.getId(), des);
+                                               return null;
+                                       }
+                               });
                        } catch (ObjectNotFoundException e) {
                                errorList.put(dest, new Integer(WebdavStatus.SC_CONFLICT));
                                return false;
@@ -2994,6 +3040,9 @@ public class Webdav extends HttpServlet {
                        } catch (InsufficientPermissionsException e) {
                                errorList.put(dest, new Integer(WebdavStatus.SC_FORBIDDEN));
                                return false;
+                       } catch (Exception e) {
+                               errorList.put(dest, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
+                               return false;
                        }
 
                        try {
@@ -3029,9 +3078,16 @@ public class Webdav extends HttpServlet {
                        }
 
                } else if (object instanceof FileHeaderDTO) {
-                       FileHeaderDTO file = (FileHeaderDTO) object;
+                       final FileHeaderDTO file = (FileHeaderDTO) object;
                        try {
-                               getService().copyFile(user.getId(), file.getId(), dest);
+                               final String des = dest;
+                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                                       @Override
+                                       public Void call() throws Exception {
+                                               getService().copyFile(user.getId(), file.getId(), des);
+                                               return null;
+                                       }
+                               });
                        } catch (ObjectNotFoundException e) {
                                errorList.put(source, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
                                return false;
@@ -3047,6 +3103,9 @@ public class Webdav extends HttpServlet {
                        } catch (GSSIOException e) {
                                errorList.put(source, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
                                return false;
+                       } catch (Exception e) {
+                               errorList.put(dest, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
+                               return false;
                        }
                } else {
                        errorList.put(source, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
@@ -3097,7 +3156,7 @@ public class Webdav extends HttpServlet {
                        return false;
                }
 
-               User user = getUser(req);
+               final User user = getUser(req);
                boolean exists = true;
                Object object = null;
                try {
@@ -3123,7 +3182,14 @@ public class Webdav extends HttpServlet {
 
                if (file != null)
                        try {
-                               getService().deleteFile(user.getId(), file.getId());
+                               final FileHeaderDTO f = file;
+                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                                       @Override
+                                       public Void call() throws Exception {
+                                               getService().deleteFile(user.getId(), f.getId());
+                                               return null;
+                                       }
+                               });
                        } catch (InsufficientPermissionsException e) {
                                resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
                                return false;
@@ -3135,18 +3201,30 @@ public class Webdav extends HttpServlet {
                        } catch (RpcException e) {
                                resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                                return false;
+                       } catch (Exception e) {
+                               resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
+                               return false;
                        }
                else if (folder != null) {
                        Hashtable<String, Integer> errorList = new Hashtable<String, Integer>();
                        deleteCollection(req, folder, path, errorList);
                        try {
-                               getService().deleteFolder(user.getId(), folder.getId());
+                               final FolderDTO f = folder;
+                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                                       @Override
+                                       public Void call() throws Exception {
+                                               getService().deleteFolder(user.getId(), f.getId());
+                                               return null;
+                                       }
+                               });
                        } catch (InsufficientPermissionsException e) {
                                errorList.put(path, new Integer(WebdavStatus.SC_METHOD_NOT_ALLOWED));
                        } catch (ObjectNotFoundException e) {
                                errorList.put(path, new Integer(WebdavStatus.SC_NOT_FOUND));
                        } catch (RpcException e) {
                                errorList.put(path, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
+                       } catch (Exception e) {
+                               errorList.put(path, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
                        }
 
                        if (!errorList.isEmpty()) {
@@ -3197,7 +3275,7 @@ public class Webdav extends HttpServlet {
                                errorList.put(childName, new Integer(WebdavStatus.SC_LOCKED));
                        else
                                try {
-                                       User user = getUser(req);
+                                       final User user = getUser(req);
                                        Object object = getService().getResourceAtPath(user.getId(), childName, true);
                                        FolderDTO childFolder = null;
                                        FileHeaderDTO childFile = null;
@@ -3206,16 +3284,33 @@ public class Webdav extends HttpServlet {
                                        else
                                                childFile = (FileHeaderDTO) object;
                                        if (childFolder != null) {
+                                               final FolderDTO cf = childFolder;
                                                deleteCollection(req, childFolder, childName, errorList);
-                                               getService().deleteFolder(user.getId(), childFolder.getId());
-                                       } else if (childFile != null)
-                                               getService().deleteFile(user.getId(), childFile.getId());
+                                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                                                       @Override
+                                                       public Void call() throws Exception {
+                                                               getService().deleteFolder(user.getId(), cf.getId());
+                                                               return null;
+                                                       }
+                                               });
+                                       } else if (childFile != null) {
+                                               final FileHeaderDTO cf = childFile;
+                                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                                                       @Override
+                                                       public Void call() throws Exception {
+                                                               getService().deleteFile(user.getId(), cf.getId());
+                                                               return null;
+                                                       }
+                                               });
+                                       }
                                } catch (ObjectNotFoundException e) {
                                        errorList.put(childName, new Integer(WebdavStatus.SC_NOT_FOUND));
                                } catch (InsufficientPermissionsException e) {
                                        errorList.put(childName, new Integer(WebdavStatus.SC_FORBIDDEN));
                                } catch (RpcException e) {
                                        errorList.put(childName, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
+                               } catch (Exception e) {
+                                       errorList.put(childName, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
                                }
                }
        }
@@ -3294,6 +3389,7 @@ public class Webdav extends HttpServlet {
                        context = theContext;
                }
 
+               @Override
                public InputSource resolveEntity(String publicId, String systemId) {
                        context.log("The request included a reference to an external entity with PublicID " + publicId + " and SystemID " + systemId + " which was ignored");
                        return new InputSource(new StringReader("Ignored external entity"));
@@ -3322,4 +3418,34 @@ public class Webdav extends HttpServlet {
                return (User) req.getAttribute(OWNER_ATTRIBUTE);
        }
 
+       /**
+        * Check if the if-modified-since condition is satisfied.
+        *
+        * @param request The servlet request we are processing
+        * @param response The servlet response we are creating
+        * @param folder the folder object
+        * @return boolean true if the resource meets the specified condition, and
+        *         false if the condition is not satisfied, in which case request
+        *         processing is stopped
+        */
+       public boolean checkIfModifiedSince(HttpServletRequest request,
+                               HttpServletResponse response, FolderDTO folder) {
+               try {
+                       long headerValue = request.getDateHeader("If-Modified-Since");
+                       long lastModified = folder.getAuditInfo().getModificationDate().getTime();
+                       if (headerValue != -1)
+                               // If an If-None-Match header has been specified, if modified
+                               // since is ignored.
+                               if (request.getHeader("If-None-Match") == null && lastModified < headerValue + 1000) {
+                                       // The entity has not been modified since the date
+                                       // specified by the client. This is not an error case.
+                                       response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                                       return false;
+                               }
+               } catch (IllegalArgumentException illegalArgument) {
+                       return true;
+               }
+               return true;
+       }
+
 }