From: Wolfgang M. M. <wol...@us...> - 2004-08-06 17:36:48
|
Update of /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11150/src/org/exist/http/webdav/methods Modified Files: Copy.java Delete.java Get.java Options.java Mkcol.java Move.java Put.java Head.java Propfind.java Added Files: AbstractWebDAVMethod.java Log Message: Modified WebDAV implementation classes to have better control over collection and resource locks. Index: Get.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Get.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Get.java 2 Jul 2004 16:53:55 -0000 1.2 --- Get.java 6 Aug 2004 17:36:36 -0000 1.3 *************** *** 31,84 **** import org.exist.EXistException; - import org.exist.collections.Collection; import org.exist.dom.BinaryDocument; import org.exist.dom.DocumentImpl; import org.exist.http.webdav.WebDAV; - import org.exist.http.webdav.WebDAVMethod; import org.exist.security.Permission; import org.exist.security.User; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; import org.exist.storage.serializers.Serializer; import org.xml.sax.SAXException; /** * @author wolf */ ! public class Get implements WebDAVMethod { ! private BrokerPool pool; public Get(BrokerPool pool) { ! this.pool = pool; } - /* (non-Javadoc) - * @see org.exist.http.webdav.WebDAVMethod#process(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.exist.collections.Collection, org.exist.dom.DocumentImpl) - */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, Collection collection, ! DocumentImpl resource) throws ServletException, IOException { ! if(resource == null) { ! // GET is not available on collections ! response.sendError(HttpServletResponse.SC_FORBIDDEN, "GET is not available on collections"); ! return; ! } ! if(!resource.getPermissions().validate(user, Permission.READ)) { ! response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not allowed to read resource"); ! return; ! } ! String contentType; ! if(resource.getResourceType() == DocumentImpl.XML_FILE) ! contentType = WebDAV.XML_CONTENT; ! else ! contentType = WebDAV.BINARY_CONTENT; ! response.setContentType(contentType); ! response.addDateHeader("Last-Modified", resource.getLastModified()); ! ! byte[] contentData = null; DBBroker broker = null; try { broker = pool.get(); if(resource.getResourceType() == DocumentImpl.XML_FILE) { Serializer serializer = broker.getSerializer(); --- 31,84 ---- import org.exist.EXistException; import org.exist.dom.BinaryDocument; import org.exist.dom.DocumentImpl; import org.exist.http.webdav.WebDAV; import org.exist.security.Permission; + import org.exist.security.PermissionDeniedException; import org.exist.security.User; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; import org.exist.storage.serializers.Serializer; + import org.exist.util.Lock; import org.xml.sax.SAXException; /** + * Implements the WebDAV GET method. + * * @author wolf */ ! public class Get extends AbstractWebDAVMethod { ! private final static String SERIALIZE_ERROR = "Error while serializing document: "; public Get(BrokerPool pool) { ! super(pool); } public void process(User user, HttpServletRequest request, ! HttpServletResponse response, String path) throws ServletException, IOException { DBBroker broker = null; + byte[] contentData = null; + DocumentImpl resource = null; try { broker = pool.get(); + resource = broker.openDocument(path, Lock.READ_LOCK); + if(resource == null) { + // GET is not available on collections + response.sendError(HttpServletResponse.SC_FORBIDDEN, "GET is not available on collections"); + return; + } + if(!resource.getPermissions().validate(user, Permission.READ)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, READ_PERMISSION_DENIED); + return; + } + String contentType; + if(resource.getResourceType() == DocumentImpl.XML_FILE) + contentType = WebDAV.XML_CONTENT; + else + contentType = WebDAV.BINARY_CONTENT; + response.setContentType(contentType); + response.addDateHeader("Last-Modified", resource.getLastModified()); + if(resource.getResourceType() == DocumentImpl.XML_FILE) { Serializer serializer = broker.getSerializer(); *************** *** 89,99 **** contentData = content.getBytes("UTF-8"); } catch (SAXException e) { ! throw new ServletException("Error while serializing document: " + e.getMessage(), e); } } else contentData = broker.getBinaryResourceData((BinaryDocument)resource); } catch (EXistException e) { ! throw new ServletException("Error while serializing document: " + e.getMessage(), e); } finally { pool.release(broker); } --- 89,103 ---- contentData = content.getBytes("UTF-8"); } catch (SAXException e) { ! throw new ServletException(SERIALIZE_ERROR + e.getMessage(), e); } } else contentData = broker.getBinaryResourceData((BinaryDocument)resource); } catch (EXistException e) { ! throw new ServletException(SERIALIZE_ERROR + e.getMessage(), e); ! } catch (PermissionDeniedException e) { ! response.sendError(HttpServletResponse.SC_FORBIDDEN, READ_PERMISSION_DENIED); } finally { + if(resource != null) + resource.getUpdateLock().release(Lock.READ_LOCK); pool.release(broker); } --- NEW FILE: AbstractWebDAVMethod.java --- /* * eXist Open Source Native XML Database * Copyright (C) 2000-04, Wolfgang M. Meier (wol...@ex...) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Id: AbstractWebDAVMethod.java,v 1.1 2004/08/06 17:36:36 wolfgang_m Exp $ */ package org.exist.http.webdav.methods; import org.apache.log4j.Logger; import org.exist.http.webdav.WebDAVMethod; import org.exist.storage.BrokerPool; /** * Abstract base class for all WebDAV methods. * * @author wolf */ public abstract class AbstractWebDAVMethod implements WebDAVMethod { final static Logger LOG = Logger.getLogger(AbstractWebDAVMethod.class); // common error messages final static String READ_PERMISSION_DENIED = "Not allowed to read resource"; final static String NOT_FOUND_ERR = "No resource or collection found"; protected BrokerPool pool; public AbstractWebDAVMethod(BrokerPool pool) { this.pool = pool; } } Index: Mkcol.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Mkcol.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Mkcol.java 5 Aug 2004 12:09:42 -0000 1.4 --- Mkcol.java 6 Aug 2004 17:36:36 -0000 1.5 *************** *** 31,89 **** import org.exist.EXistException; import org.exist.collections.Collection; - import org.exist.dom.DocumentImpl; - import org.exist.http.webdav.WebDAVMethod; import org.exist.security.PermissionDeniedException; import org.exist.security.User; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; /** * @author wolf */ ! public class Mkcol implements WebDAVMethod { - private BrokerPool pool; - - /** - * - */ public Mkcol(BrokerPool pool) { ! super(); ! this.pool = pool; } - /* (non-Javadoc) - * @see org.exist.http.webdav.WebDAVMethod#process(org.exist.security.User, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.exist.collections.Collection, org.exist.dom.DocumentImpl) - */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, Collection collection, ! DocumentImpl resource) throws ServletException, IOException { ! if(collection != null) { ! response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, ! "collection " + request.getPathInfo() + " already exists"); ! return; ! } ! if(resource != null) { ! response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, ! "path conflicts with an existing resource"); ! return; ! } ! String path = request.getPathInfo(); ! if(path == null || path.equals("")) { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "no path specified"); return; } ! if(path.endsWith("/")) ! path = path.substring(0, path.length() - 1); ! int p = path.lastIndexOf('/'); ! String parentPath = -1 < p ? path.substring(0, p) : "/db"; ! String newCollection = -1 < p ? path.substring(p + 1) : path; ! DBBroker broker = null; ! try { ! broker = pool.get(user); ! Collection parent = broker.getCollection(parentPath); ! if(parent == null) { LOG.debug("Parent collection " + parentPath + " not found"); response.sendError(HttpServletResponse.SC_CONFLICT, --- 31,76 ---- import org.exist.EXistException; import org.exist.collections.Collection; import org.exist.security.PermissionDeniedException; import org.exist.security.User; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; + import org.exist.util.Lock; /** + * Implements the WebDAV MKCOL method. + * * @author wolf */ ! public class Mkcol extends AbstractWebDAVMethod { public Mkcol(BrokerPool pool) { ! super(pool); } public void process(User user, HttpServletRequest request, ! HttpServletResponse response, String path) throws ServletException, IOException { ! String origPath = request.getPathInfo(); ! if(path == null || path.equals("")) { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "no path specified"); return; } ! DBBroker broker = null; ! Collection collection = null; ! try { ! broker = pool.get(user); ! collection = broker.openCollection(path, Lock.READ_LOCK); ! if(collection != null) { ! collection.release(); ! response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, ! "collection " + request.getPathInfo() + " already exists"); ! return; ! } ! int p = path.lastIndexOf('/'); ! String parentPath = -1 < p ? path.substring(0, p) : "/db"; ! String newCollection = -1 < p ? path.substring(p + 1) : path; ! collection = broker.openCollection(parentPath, Lock.WRITE_LOCK); ! if(collection == null) { LOG.debug("Parent collection " + parentPath + " not found"); response.sendError(HttpServletResponse.SC_CONFLICT, *************** *** 91,94 **** --- 78,89 ---- return; } + if(collection.hasDocument(newCollection)) { + collection.release(); + response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, + "path conflicts with an existing resource"); + return; + } + // TODO: releasing the lock here is dangerous, but we may get into deadlocks otherwise. + collection.release(); Collection created = broker.getOrCreateCollection(path); broker.saveCollection(created); Index: Copy.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Copy.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Copy.java 5 Aug 2004 12:09:42 -0000 1.4 --- Copy.java 6 Aug 2004 17:36:36 -0000 1.5 *************** *** 34,38 **** import org.exist.collections.Collection; import org.exist.dom.DocumentImpl; - import org.exist.http.webdav.WebDAVMethod; import org.exist.security.PermissionDeniedException; import org.exist.security.User; --- 34,37 ---- *************** *** 48,54 **** * @author wolf */ ! public class Copy implements WebDAVMethod { ! ! private BrokerPool pool; /** --- 47,51 ---- * @author wolf */ ! public class Copy extends AbstractWebDAVMethod { /** *************** *** 56,61 **** */ public Copy(BrokerPool pool) { ! super(); ! this.pool = pool; } --- 53,57 ---- */ public Copy(BrokerPool pool) { ! super(pool); } *************** *** 64,100 **** */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, Collection collection, ! DocumentImpl resource) throws ServletException, IOException { ! if(collection == null) { ! response.sendError(HttpServletResponse.SC_NOT_FOUND, "Resource or collection not found"); ! return; ! } ! String destination = request.getHeader("Destination"); ! String path = null; ! try { ! URI uri = new URI(destination); ! String host = uri.getHost(); ! int port = uri.getPort(); ! if(!(host.equals(request.getServerName()) && port == request.getServerPort())) { ! response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, ! "Copying to a different server is not yet implemented"); ! return; ! } ! path = uri.getPath(); ! if(path.startsWith(request.getContextPath())) ! path = path.substring(request.getContextPath().length()); ! if(path.startsWith(request.getServletPath())) ! path = path.substring(request.getServletPath().length()); ! } catch (URISyntaxException e) { ! response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Malformed URL in destination header"); ! } ! if(resource != null) ! copyResource(user, request, response, resource, path); ! else ! response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, ! "Copying collections is not yet implemented"); } ! private void copyResource(User user, HttpServletRequest request, HttpServletResponse response, DocumentImpl resource, String destination) throws ServletException, IOException { --- 60,125 ---- */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, String path) throws ServletException, IOException { ! DBBroker broker = null; ! Collection collection = null; ! DocumentImpl resource = null; ! try { ! broker = pool.get(user); ! collection = broker.openCollection(path, Lock.READ_LOCK); ! if(collection == null) { ! int pos = path.lastIndexOf('/'); ! String collName = path.substring(0, pos); ! String docName = path.substring(pos + 1); ! collection = broker.openCollection(collName, Lock.READ_LOCK); ! if(collection == null) { ! LOG.debug("No resource or collection found for path: " + path); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, NOT_FOUND_ERR); ! return; ! } ! resource = collection.getDocumentWithLock(broker, docName, Lock.READ_LOCK); ! if(resource == null) { ! LOG.debug("No resource found for path: " + path); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, NOT_FOUND_ERR); ! return; ! } ! } ! String destination = request.getHeader("Destination"); ! String destPath = null; ! try { ! URI uri = new URI(destination); ! String host = uri.getHost(); ! int port = uri.getPort(); ! if(!(host.equals(request.getServerName()) && port == request.getServerPort())) { ! response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, ! "Copying to a different server is not yet implemented"); ! return; ! } ! destPath = uri.getPath(); ! if(destPath.startsWith(request.getContextPath())) ! destPath = destPath.substring(request.getContextPath().length()); ! if(destPath.startsWith(request.getServletPath())) ! destPath = destPath.substring(request.getServletPath().length()); ! } catch (URISyntaxException e) { ! response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Malformed URL in destination header"); ! } ! if(resource != null) ! copyResource(user, broker, request, response, collection, resource, destPath); ! else ! copyCollection(user, broker, request, response, collection, destPath); ! } catch (EXistException e) { ! throw new ServletException("Failed to copy: " + e.getMessage(), e); ! } catch (LockException e) { ! throw new ServletException("Failed to copy: " + e.getMessage(), e); ! } finally { ! if(collection != null) ! collection.release(); ! if(resource != null) ! resource.getUpdateLock().release(Lock.READ_LOCK); ! pool.release(broker); ! } } ! private void copyResource(User user, DBBroker broker, HttpServletRequest request, HttpServletResponse response, ! Collection sourceCollection, DocumentImpl resource, String destination) throws ServletException, IOException { *************** *** 108,116 **** destination = destination.substring(0, p); boolean replaced = false; - DBBroker broker = null; Collection destCollection = null; - Collection sourceCollection = null; try { - broker = pool.get(user); destCollection = broker.openCollection(destination, Lock.WRITE_LOCK); if(destCollection == null) { --- 133,138 ---- *************** *** 119,127 **** return; } - String sourcePath = resource.getName(); - int pos = sourcePath.lastIndexOf('/'); - String collName = sourcePath.substring(0, pos); - String docName = sourcePath.substring(pos + 1); - sourceCollection = broker.openCollection(collName, Lock.READ_LOCK); DocumentImpl oldDoc = destCollection.getDocument(broker, newResourceName); --- 141,144 ---- *************** *** 140,145 **** else response.setStatus(HttpServletResponse.SC_CREATED); - } catch (EXistException e) { - throw new ServletException(e.getMessage(), e); } catch (PermissionDeniedException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); --- 157,160 ---- *************** *** 147,159 **** response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } finally { - if(sourceCollection != null) - sourceCollection.release(); if(destCollection != null) destCollection.release(); - pool.release(broker); } } ! private void copyCollection(User user, HttpServletRequest request, HttpServletResponse response, Collection collection, String destination) throws ServletException, IOException { --- 162,171 ---- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } finally { if(destCollection != null) destCollection.release(); } } ! private void copyCollection(User user, DBBroker broker, HttpServletRequest request, HttpServletResponse response, Collection collection, String destination) throws ServletException, IOException { *************** *** 167,174 **** destination = destination.substring(0, p); boolean replaced = false; - DBBroker broker = null; Collection destCollection = null; try { - broker = pool.get(user); destCollection = broker.openCollection(destination, Lock.WRITE_LOCK); if(destCollection == null) { --- 179,184 ---- *************** *** 192,197 **** else response.setStatus(HttpServletResponse.SC_CREATED); - } catch (EXistException e) { - throw new ServletException(e.getMessage(), e); } catch (PermissionDeniedException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); --- 202,205 ---- *************** *** 201,205 **** if(destCollection != null) destCollection.release(); - pool.release(broker); } } --- 209,212 ---- Index: Move.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Move.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Move.java 3 Aug 2004 15:25:58 -0000 1.4 --- Move.java 6 Aug 2004 17:36:36 -0000 1.5 *************** *** 34,42 **** import org.exist.collections.Collection; import org.exist.dom.DocumentImpl; - import org.exist.http.webdav.WebDAVMethod; import org.exist.security.PermissionDeniedException; import org.exist.security.User; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; import org.exist.util.LockException; --- 34,42 ---- import org.exist.collections.Collection; import org.exist.dom.DocumentImpl; import org.exist.security.PermissionDeniedException; import org.exist.security.User; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; + import org.exist.util.Lock; import org.exist.util.LockException; *************** *** 45,54 **** * @author wolf */ ! public class Move implements WebDAVMethod { - private BrokerPool pool; public Move(BrokerPool pool) { ! this.pool = pool; } --- 45,53 ---- * @author wolf */ ! public class Move extends AbstractWebDAVMethod { public Move(BrokerPool pool) { ! super(pool); } *************** *** 57,92 **** */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, Collection collection, ! DocumentImpl resource) throws ServletException, IOException { ! if(collection == null) { ! response.sendError(HttpServletResponse.SC_NOT_FOUND, "Resource or collection not found"); ! return; ! } ! String destination = request.getHeader("Destination"); ! String path = null; ! try { ! URI uri = new URI(destination); ! String host = uri.getHost(); ! int port = uri.getPort(); ! if(!(host.equals(request.getServerName()) && port == request.getServerPort())) { ! response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, ! "Moving to a different server is not yet implemented"); ! return; ! } ! path = uri.getPath(); ! if(path.startsWith(request.getContextPath())) ! path = path.substring(request.getContextPath().length()); ! if(path.startsWith(request.getServletPath())) ! path = path.substring(request.getServletPath().length()); ! } catch (URISyntaxException e) { ! response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Malformed URL in destination header"); ! } ! if(resource != null) ! moveResource(user, request, response, resource, path); ! else ! moveCollection(user, request, response, collection, path); } ! private void moveCollection(User user, HttpServletRequest request, HttpServletResponse response, Collection collection, String destination) throws ServletException, IOException { if(collection.getName().equals(destination)) { --- 56,120 ---- */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, String path) throws ServletException, IOException { ! DBBroker broker = null; ! Collection collection = null; ! DocumentImpl resource = null; ! try { ! broker = pool.get(user); ! collection = broker.openCollection(path, Lock.WRITE_LOCK); ! if(collection == null) { ! int pos = path.lastIndexOf('/'); ! String collName = path.substring(0, pos); ! String docName = path.substring(pos + 1); ! collection = broker.openCollection(collName, Lock.WRITE_LOCK); ! if(collection == null) { ! LOG.debug("No resource or collection found for path: " + path); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, NOT_FOUND_ERR); ! return; ! } ! resource = collection.getDocumentWithLock(broker, docName, Lock.WRITE_LOCK); ! if(resource == null) { ! LOG.debug("No resource found for path: " + path); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, NOT_FOUND_ERR); ! return; ! } ! } ! String destination = request.getHeader("Destination"); ! String destPath = null; ! try { ! URI uri = new URI(destination); ! String host = uri.getHost(); ! int port = uri.getPort(); ! if(!(host.equals(request.getServerName()) && port == request.getServerPort())) { ! response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, ! "Copying to a different server is not yet implemented"); ! return; ! } ! destPath = uri.getPath(); ! if(destPath.startsWith(request.getContextPath())) ! destPath = destPath.substring(request.getContextPath().length()); ! if(destPath.startsWith(request.getServletPath())) ! destPath = destPath.substring(request.getServletPath().length()); ! } catch (URISyntaxException e) { ! response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Malformed URL in destination header"); ! } ! if(resource != null) ! moveResource(user, broker, request, response, resource, destPath); ! else ! moveCollection(user, broker, request, response, collection, destPath); ! } catch (EXistException e) { ! throw new ServletException("Failed to copy: " + e.getMessage(), e); ! } catch (LockException e) { ! throw new ServletException("Failed to copy: " + e.getMessage(), e); ! } finally { ! if(collection != null) ! collection.release(); ! if(resource != null) ! resource.getUpdateLock().release(Lock.WRITE_LOCK); ! pool.release(broker); ! } } ! private void moveCollection(User user, DBBroker broker, HttpServletRequest request, HttpServletResponse response, Collection collection, String destination) throws ServletException, IOException { if(collection.getName().equals(destination)) { *************** *** 95,135 **** return; } ! DBBroker broker = null; try { - broker = pool.get(user); boolean replaced = false; ! Collection destCollection = broker.getCollection(destination); ! if(destCollection != null) { ! boolean overwrite = overwrite(request); ! if(!overwrite) { ! response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, ! "Destination collection exists"); ! return; ! } ! broker.removeCollection(destCollection); ! replaced = true; ! } ! int p = destination.lastIndexOf('/'); ! if(p < 0) { ! response.sendError(HttpServletResponse.SC_BAD_REQUEST, ! "Bad destination: " + destination); ! return; ! } String parentPath = destination.substring(0, p); String newCollectionName = destination.substring(p + 1); LOG.debug("parent = " + parentPath + "; new name = " + newCollectionName); ! Collection parent = broker.getCollection(parentPath); ! if(parent == null) { response.sendError(HttpServletResponse.SC_CONFLICT, "No parent collection: " + parentPath); return; } ! broker.moveCollection(collection, parent, newCollectionName); if(replaced) response.setStatus(HttpServletResponse.SC_NO_CONTENT); else response.setStatus(HttpServletResponse.SC_CREATED); - } catch (EXistException e) { - throw new ServletException(e.getMessage(), e); } catch (PermissionDeniedException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); --- 123,161 ---- return; } ! int p = destination.lastIndexOf('/'); ! if(p < 0) { ! response.sendError(HttpServletResponse.SC_BAD_REQUEST, ! "Bad destination: " + destination); ! return; ! } ! Collection destCollection = null; try { boolean replaced = false; ! destCollection = broker.openCollection(destination, Lock.WRITE_LOCK); ! if(destCollection != null) { ! boolean overwrite = overwrite(request); ! if(!overwrite) { ! response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, ! "Destination collection exists and overwrite is not allowed"); ! return; ! } ! broker.removeCollection(destCollection); ! replaced = true; ! } ! String parentPath = destination.substring(0, p); String newCollectionName = destination.substring(p + 1); LOG.debug("parent = " + parentPath + "; new name = " + newCollectionName); ! destCollection = broker.openCollection(parentPath, Lock.WRITE_LOCK); ! if(destCollection == null) { response.sendError(HttpServletResponse.SC_CONFLICT, "No parent collection: " + parentPath); return; } ! broker.moveCollection(collection, destCollection, newCollectionName); if(replaced) response.setStatus(HttpServletResponse.SC_NO_CONTENT); else response.setStatus(HttpServletResponse.SC_CREATED); } catch (PermissionDeniedException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); *************** *** 137,148 **** response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } finally { pool.release(broker); } } ! private void moveResource(User user, HttpServletRequest request, HttpServletResponse response, DocumentImpl resource, ! String destination) throws ServletException, IOException { ! int p = destination.lastIndexOf('/'); if(p < 0) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, --- 163,176 ---- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } finally { + if(destCollection != null) + destCollection.release(); pool.release(broker); } } ! private void moveResource(User user, DBBroker broker, HttpServletRequest request, HttpServletResponse response, ! DocumentImpl resource, String destination) throws ServletException, IOException { ! int p = destination.lastIndexOf('/'); if(p < 0) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, *************** *** 153,160 **** destination = destination.substring(0, p); boolean replaced = false; ! DBBroker broker = null; try { ! broker = pool.get(user); ! Collection destCollection = broker.getCollection(destination); if(destCollection == null) { response.sendError(HttpServletResponse.SC_CONFLICT, --- 181,187 ---- destination = destination.substring(0, p); boolean replaced = false; ! Collection destCollection = null; try { ! destCollection = broker.openCollection(destination, Lock.WRITE_LOCK); if(destCollection == null) { response.sendError(HttpServletResponse.SC_CONFLICT, *************** *** 162,165 **** --- 189,193 ---- return; } + DocumentImpl oldDoc = destCollection.getDocument(broker, newResourceName); if(oldDoc != null) { *************** *** 177,182 **** else response.setStatus(HttpServletResponse.SC_CREATED); - } catch (EXistException e) { - throw new ServletException(e.getMessage(), e); } catch (PermissionDeniedException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); --- 205,208 ---- *************** *** 184,188 **** response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } finally { ! pool.release(broker); } } --- 210,215 ---- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } finally { ! if(destCollection != null) ! destCollection.release(); } } Index: Put.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Put.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Put.java 5 Aug 2004 12:09:42 -0000 1.4 --- Put.java 6 Aug 2004 17:36:36 -0000 1.5 *************** *** 40,46 **** import org.exist.EXistException; import org.exist.collections.Collection; import org.exist.collections.triggers.TriggerException; - import org.exist.dom.DocumentImpl; - import org.exist.http.webdav.WebDAVMethod; import org.exist.security.PermissionDeniedException; import org.exist.security.User; --- 40,45 ---- import org.exist.EXistException; import org.exist.collections.Collection; + import org.exist.collections.IndexInfo; import org.exist.collections.triggers.TriggerException; import org.exist.security.PermissionDeniedException; import org.exist.security.User; *************** *** 55,64 **** * @author wolf */ ! public class Put implements WebDAVMethod { ! ! private BrokerPool pool; public Put(BrokerPool pool) { ! this.pool = pool; } --- 54,61 ---- * @author wolf */ ! public class Put extends AbstractWebDAVMethod { public Put(BrokerPool pool) { ! super(pool); } *************** *** 67,72 **** */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, Collection collection, ! DocumentImpl resource) throws ServletException, IOException { File tempFile = saveRequestContent(request); String url; --- 64,68 ---- */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, String path) throws ServletException, IOException { File tempFile = saveRequestContent(request); String url; *************** *** 77,114 **** } String contentType = request.getContentType(); - String path = request.getPathInfo(); DBBroker broker = null; try { broker = pool.get(user); if(collection == null) { ! if(path == null) ! path = ""; ! if(path.endsWith("/")) ! path = path.substring(0, path.length() - 1); ! int p = path.lastIndexOf('/'); ! if(p < 1) { ! response.sendError(HttpServletResponse.SC_CONFLICT, "No collection specified for PUT"); ! return; ! } ! String collectionName = path.substring(0, p); ! path = path.substring(p + 1); ! collection = broker.openCollection(collectionName, Lock.WRITE_LOCK); ! if(collection == null) { ! response.sendError(HttpServletResponse.SC_CONFLICT, "Parent collection " + collectionName + ! " not found"); ! return; ! } ! } else { ! collection.getLock().acquire(Lock.WRITE_LOCK); ! path = path.substring(collection.getName().length() + 1); } if(contentType == null) { ! contentType = URLConnection.guessContentTypeFromName(path); } LOG.debug("storing document " + path + "; content-type = " + contentType); if(contentType == null || contentType.equalsIgnoreCase("text/xml") || ! contentType.equals("application/xml")) { ! DocumentImpl doc = collection.addDocument(broker, path, ! new InputSource(url)); } else { byte[] chunk = new byte[4096]; --- 73,114 ---- } String contentType = request.getContentType(); DBBroker broker = null; + Collection collection = null; + boolean collectionLocked = true; try { broker = pool.get(user); + if(path == null) + path = ""; + if(path.endsWith("/")) + path = path.substring(0, path.length() - 1); + int p = path.lastIndexOf('/'); + if(p < 1) { + response.sendError(HttpServletResponse.SC_CONFLICT, "No collection specified for PUT"); + return; + } + String collectionName = path.substring(0, p); + path = path.substring(p + 1); + + collection = broker.openCollection(collectionName, Lock.WRITE_LOCK); if(collection == null) { ! response.sendError(HttpServletResponse.SC_CONFLICT, "Parent collection " + collectionName + ! " not found"); ! return; ! } ! if(collection.hasChildCollection(path)) { ! response.sendError(HttpServletResponse.SC_CONFLICT, "Cannot overwrite an existing collection with a resource"); ! return; } if(contentType == null) { ! contentType = URLConnection.guessContentTypeFromName(path); } LOG.debug("storing document " + path + "; content-type = " + contentType); if(contentType == null || contentType.equalsIgnoreCase("text/xml") || ! contentType.equals("application/xml")) { ! InputSource is = new InputSource(url); ! IndexInfo info = collection.validate(broker, path, is); ! collection.release(); ! collectionLocked = false; ! collection.store(broker, info, is, false); } else { byte[] chunk = new byte[4096]; *************** *** 132,136 **** response.sendError(HttpServletResponse.SC_CONFLICT); } finally { ! collection.release(); pool.release(broker); } --- 132,137 ---- response.sendError(HttpServletResponse.SC_CONFLICT); } finally { ! if(collectionLocked) ! collection.release(); pool.release(broker); } Index: Options.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Options.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Options.java 3 May 2004 13:03:34 -0000 1.2 --- Options.java 6 Aug 2004 17:36:36 -0000 1.3 *************** *** 29,34 **** import javax.servlet.http.HttpServletResponse; - import org.exist.collections.Collection; - import org.exist.dom.DocumentImpl; import org.exist.http.webdav.WebDAVMethod; import org.exist.security.User; --- 29,32 ---- *************** *** 39,48 **** public class Options implements WebDAVMethod { - /* (non-Javadoc) - * @see org.exist.http.webdav.WebDAVMethod#process(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.exist.collections.Collection, org.exist.dom.DocumentImpl) - */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, Collection collection, ! DocumentImpl resource) throws ServletException, IOException { response.addHeader("DAV", "1"); response.addHeader("Allow", "OPTIONS, GET, HEAD, PUT, PROPFIND,MKCOL"); --- 37,42 ---- public class Options implements WebDAVMethod { public void process(User user, HttpServletRequest request, ! HttpServletResponse response, String path) throws ServletException, IOException { response.addHeader("DAV", "1"); response.addHeader("Allow", "OPTIONS, GET, HEAD, PUT, PROPFIND,MKCOL"); Index: Head.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Head.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Head.java 7 Jul 2004 20:54:44 -0000 1.3 --- Head.java 6 Aug 2004 17:36:36 -0000 1.4 *************** *** 29,42 **** import javax.servlet.http.HttpServletResponse; ! import org.exist.collections.Collection; import org.exist.dom.DocumentImpl; import org.exist.http.webdav.WebDAV; ! import org.exist.http.webdav.WebDAVMethod; import org.exist.security.User; /** * @author wolf */ ! public class Head implements WebDAVMethod { /* (non-Javadoc) --- 29,50 ---- import javax.servlet.http.HttpServletResponse; ! import org.exist.EXistException; import org.exist.dom.DocumentImpl; import org.exist.http.webdav.WebDAV; ! import org.exist.security.Permission; ! import org.exist.security.PermissionDeniedException; import org.exist.security.User; + import org.exist.storage.BrokerPool; + import org.exist.storage.DBBroker; + import org.exist.util.Lock; /** * @author wolf */ ! public class Head extends AbstractWebDAVMethod { ! ! public Head(BrokerPool pool) { ! super(pool); ! } /* (non-Javadoc) *************** *** 44,61 **** */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, Collection collection, ! DocumentImpl resource) throws ServletException, IOException { ! if(resource == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } - String contentType; - if(resource.getResourceType() == DocumentImpl.XML_FILE) - contentType = WebDAV.XML_CONTENT; - else - contentType = WebDAV.BINARY_CONTENT; - response.setContentType(contentType); - response.setContentLength(resource.getContentLength()); - response.addDateHeader("Last-Modified", resource.getLastModified()); } } --- 52,92 ---- */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, String path) throws ServletException, IOException { ! DBBroker broker = null; ! byte[] contentData = null; ! DocumentImpl resource = null; ! try { ! broker = pool.get(); ! resource = broker.openDocument(path, Lock.READ_LOCK); ! if(resource == null) { ! // GET is not available on collections ! response.sendError(HttpServletResponse.SC_FORBIDDEN, "GET is not available on collections"); ! return; ! } ! if(!resource.getPermissions().validate(user, Permission.READ)) { ! response.sendError(HttpServletResponse.SC_FORBIDDEN, READ_PERMISSION_DENIED); ! return; ! } ! String contentType; ! if(resource.getResourceType() == DocumentImpl.XML_FILE) ! contentType = WebDAV.XML_CONTENT; ! else ! contentType = WebDAV.BINARY_CONTENT; ! response.setContentType(contentType); ! response.setContentLength(resource.getContentLength()); ! response.addDateHeader("Last-Modified", resource.getLastModified()); ! } catch (EXistException e) { ! throw new ServletException(e.getMessage(), e); ! } catch (PermissionDeniedException e) { ! response.sendError(HttpServletResponse.SC_FORBIDDEN, READ_PERMISSION_DENIED); ! } finally { ! if(resource != null) ! resource.getUpdateLock().release(Lock.READ_LOCK); ! pool.release(broker); ! } ! if(contentData == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } } } Index: Delete.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Delete.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Delete.java 5 Aug 2004 12:09:42 -0000 1.5 --- Delete.java 6 Aug 2004 17:36:36 -0000 1.6 *************** *** 33,37 **** import org.exist.collections.triggers.TriggerException; import org.exist.dom.DocumentImpl; ! import org.exist.http.webdav.WebDAVMethod; import org.exist.security.PermissionDeniedException; import org.exist.security.User; --- 33,37 ---- import org.exist.collections.triggers.TriggerException; import org.exist.dom.DocumentImpl; ! import org.exist.security.Permission; import org.exist.security.PermissionDeniedException; import org.exist.security.User; *************** *** 44,53 **** * @author wolf */ ! public class Delete implements WebDAVMethod { ! ! private BrokerPool pool; public Delete(BrokerPool pool) { ! this.pool = pool; } --- 44,51 ---- * @author wolf */ ! public class Delete extends AbstractWebDAVMethod { public Delete(BrokerPool pool) { ! super(pool); } *************** *** 56,69 **** */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, Collection collection, ! DocumentImpl resource) throws ServletException, IOException { ! if(collection == null) { ! response.sendError(HttpServletResponse.SC_NOT_FOUND); ! return; ! } DBBroker broker = null; try { broker = pool.get(user); ! collection.getLock().acquire(Lock.WRITE_LOCK); if(resource == null) { broker.removeCollection(collection); --- 54,87 ---- */ public void process(User user, HttpServletRequest request, ! HttpServletResponse response, String path) throws ServletException, IOException { DBBroker broker = null; + Collection collection = null; + DocumentImpl resource = null; try { broker = pool.get(user); ! collection = broker.openCollection(path, Lock.WRITE_LOCK); ! if(collection == null) { ! int pos = path.lastIndexOf('/'); ! String collName = path.substring(0, pos); ! String docName = path.substring(pos + 1); ! LOG.debug("collection = " + collName + "; doc = " + docName); ! collection = broker.openCollection(collName, Lock.WRITE_LOCK); ! if(collection == null) { ! LOG.debug("No resource or collection found for path: " + path); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, NOT_FOUND_ERR); ! return; ! } ! resource = collection.getDocument(broker, docName); ! if(resource == null) { ! LOG.debug("No resource found for path: " + path); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, NOT_FOUND_ERR); ! return; ! } ! } ! if(!collection.getPermissions().validate(user, Permission.READ)) { ! LOG.debug("Permission denied to read collection"); ! response.sendError(HttpServletResponse.SC_FORBIDDEN); ! return; ! } if(resource == null) { broker.removeCollection(collection); *************** *** 83,87 **** response.sendError(HttpServletResponse.SC_CONFLICT, e.getMessage()); } finally { ! collection.release(); pool.release(broker); } --- 101,106 ---- response.sendError(HttpServletResponse.SC_CONFLICT, e.getMessage()); } finally { ! if(collection != null) ! collection.release(); pool.release(broker); } Index: Propfind.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/http/webdav/methods/Propfind.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Propfind.java 8 Jun 2004 08:16:07 -0000 1.4 --- Propfind.java 6 Aug 2004 17:36:36 -0000 1.5 *************** *** 48,52 **** import org.exist.dom.QName; import org.exist.http.webdav.WebDAV; - import org.exist.http.webdav.WebDAVMethod; import org.exist.http.webdav.WebDAVUtil; import org.exist.security.Permission; --- 48,51 ---- *************** *** 54,57 **** --- 53,58 ---- import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; + import org.exist.util.Lock; + import org.exist.util.LockException; import org.exist.util.serializer.SAXSerializer; import org.exist.util.serializer.SAXSerializerPool; *************** *** 68,75 **** * @author wolf */ ! public class Propfind implements WebDAVMethod { ! ! // error messages ! // search types --- 69,73 ---- * @author wolf */ ! public class Propfind extends AbstractWebDAVMethod { // search types *************** *** 121,225 **** SUPPORTED_LOCK_PROP }; - - private BrokerPool pool; public Propfind(BrokerPool pool) { ! this.pool = pool; } ! /* (non-Javadoc) ! * @see org.exist.http.webdav.WebDAVMethod#process(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) ! */ ! public void process(User user, HttpServletRequest request, HttpServletResponse response, ! Collection collection, DocumentImpl resource) throws ServletException, IOException { ! if(collection == null) { ! LOG.debug("No resource or collection found"); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, "No resource or collection found"); ! return; ! } ! if(!collection.getPermissions().validate(user, Permission.READ)) { ! response.sendError(HttpServletResponse.SC_FORBIDDEN); ! return; ! } ! DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); ! docFactory.setNamespaceAware(true); ! DocumentBuilder docBuilder; ! try { ! docBuilder = docFactory.newDocumentBuilder(); ! } catch (ParserConfigurationException e1) { ! throw new ServletException(WebDAVUtil.XML_CONFIGURATION_ERR, e1); ! } ! Document doc = WebDAVUtil.parseRequestContent(request, response, docBuilder); ! int type = FIND_ALL_PROPERTIES; ! DAVProperties searchedProperties = new DAVProperties(); ! if(doc != null) { ! Element propfind = doc.getDocumentElement(); ! if(!(propfind.getLocalName().equals("propfind") && ! propfind.getNamespaceURI().equals(WebDAV.DAV_NS))) { ! LOG.debug(WebDAVUtil.UNEXPECTED_ELEMENT_ERR + propfind.getNodeName()); ! response.sendError(HttpServletResponse.SC_BAD_REQUEST, ! WebDAVUtil.UNEXPECTED_ELEMENT_ERR + propfind.getNodeName()); ! return; ! } ! ! NodeList childNodes = propfind.getChildNodes(); ! for(int i = 0; i < childNodes.getLength(); i++) { ! Node currentNode = childNodes.item(i); ! if(currentNode.getNodeType() == Node.ELEMENT_NODE) { ! if(currentNode.getNamespaceURI().equals(WebDAV.DAV_NS)) { ! if(currentNode.getLocalName().equals("prop")) { ! type = FIND_BY_PROPERTY; ! getPropertyNames(currentNode, searchedProperties); ! } ! if(currentNode.getLocalName().equals("allprop")) ! type = FIND_ALL_PROPERTIES; ! if(currentNode.getLocalName().equals("propname")) ! type = FIND_PROPERTY_NAMES; ! } else { ! // Found an unknown element: return with 400 Bad Request ! LOG.debug("Unexpected child: " + currentNode.getNodeName()); response.sendError(HttpServletResponse.SC_BAD_REQUEST, ! WebDAVUtil.UNEXPECTED_ELEMENT_ERR + currentNode.getNodeName()); return; } } ! } ! } ! ! String servletPath = getServletPath(request); ! int depth = getDepth(request); ! StringWriter os = new StringWriter(); ! SAXSerializer serializer = SAXSerializerPool.getInstance().borrowSAXSerializer(); ! try { ! serializer.setWriter(os); ! serializer.setOutputProperties(WebDAV.OUTPUT_PROPERTIES); ! AttributesImpl attrs = new AttributesImpl(); ! serializer.startDocument(); ! serializer.startPrefixMapping(PREFIX, WebDAV.DAV_NS); ! serializer.startElement(WebDAV.DAV_NS, "multistatus", "D:multistatus", attrs); ! ! if(type == FIND_ALL_PROPERTIES || type == FIND_BY_PROPERTY) { if(resource != null) ! writeResourceProperties(user, searchedProperties, type, collection, resource, serializer, servletPath); ! else ! writeCollectionProperties(user, searchedProperties, type, collection, serializer, servletPath, depth, 0); ! } else if(type == FIND_PROPERTY_NAMES) ! writePropertyNames(collection, resource, serializer, servletPath); ! ! serializer.endElement(WebDAV.DAV_NS, "multistatus", "D:multistatus"); ! serializer.endPrefixMapping(PREFIX); ! serializer.endDocument(); ! } catch (SAXException e) { ! throw new ServletException("Exception while writing multistatus response: " + e.getMessage(), e); ! } finally { ! SAXSerializerPool.getInstance().returnSAXSerializer(serializer); } - String content = os.toString(); - LOG.debug("response:\n" + content); - writeResponse(response, content); } ! private void writeCollectionProperties(User user, DAVProperties searchedProperties, int type, Collection collection, SAXSerializer serializer, String servletPath, int maxDepth, int currentDepth) throws SAXException { --- 119,251 ---- SUPPORTED_LOCK_PROP }; public Propfind(BrokerPool pool) { ! super(pool); } ! public void process(User user, HttpServletRequest request, HttpServletResponse response, String path) throws ServletException, IOException { ! DBBroker broker = null; ! Collection collection = null; ! DocumentImpl resource = null; ! synchronized (pool.getCollectionsCache()) { ! try { ! broker = pool.get(user); ! // open the collection or resource specified in the path ! collection = broker.openCollection(path, Lock.READ_LOCK); ! if(collection == null) { ! // no collection found: check for a resource ! int pos = path.lastIndexOf('/'); ! String collName = path.substring(0, pos); ! String docName = path.substring(pos + 1); ! collection = broker.openCollection(collName, Lock.READ_LOCK); ! if(collection == null) { ! LOG.debug("No resource or collection found for path: " + path); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, NOT_FOUND_ERR); ! return; ! } ! resource = collection.getDocumentWithLock(broker, docName, Lock.READ_LOCK); ! if(resource == null) { ! LOG.debug("No resource found for path: " + path); ! response.sendError(HttpServletResponse.SC_NOT_FOUND, NOT_FOUND_ERR); ! return; ! } ! } ! if(!collection.getPermissions().validate(user, Permission.READ)) { ! response.sendError(HttpServletResponse.SC_FORBIDDEN); ! return; ! } ! ! // parse the request contents ! DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); ! docFactory.setNamespaceAware(true); ! DocumentBuilder docBuilder; ! try { ! docBuilder = docFactory.newDocumentBuilder(); ! } catch (ParserConfigurationException e1) { ! throw new ServletException(WebDAVUtil.XML_CONFIGURATION_ERR, e1); ! } ! Document doc = WebDAVUtil.parseRequestContent(request, response, docBuilder); ! int type = FIND_ALL_PROPERTIES; ! DAVProperties searchedProperties = new DAVProperties(); ! if(doc != null) { ! Element propfind = doc.getDocumentElement(); ! if(!(propfind.getLocalName().equals("propfind") && ! propfind.getNamespaceURI().equals(WebDAV.DAV_NS))) { ! LOG.debug(WebDAVUtil.UNEXPECTED_ELEMENT_ERR + propfind.getNodeName()); response.sendError(HttpServletResponse.SC_BAD_REQUEST, ! WebDAVUtil.UNEXPECTED_ELEMENT_ERR + propfind.getNodeName()); return; } + + NodeList childNodes = propfind.getChildNodes(); + for(int i = 0; i < childNodes.getLength(); i++) { + Node currentNode = childNodes.item(i); + if(currentNode.getNodeType() == Node.ELEMENT_NODE) { + if(currentNode.getNamespaceURI().equals(WebDAV.DAV_NS)) { + if(currentNode.getLocalName().equals("prop")) { + type = FIND_BY_PROPERTY; + getPropertyNames(currentNode, searchedProperties); + } + if(currentNode.getLocalName().equals("allprop")) + type = FIND_ALL_PROPERTIES; + if(currentNode.getLocalName().equals("propname")) + type = FIND_PROPERTY_NAMES; + } else { + // Found an unknown element: return with 400 Bad Request + LOG.debug("Unexpected child: " + currentNode.getNodeName()); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, + WebDAVUtil.UNEXPECTED_ELEMENT_ERR + currentNode.getNodeName()); + return; + } + } + } } ! String servletPath = getServletPath(request); ! int depth = getDepth(request); ! StringWriter os = new StringWriter(); ! SAXSerializer serializer = SAXSerializerPool.getInstance().borrowSAXSerializer(); ! try { ! serializer.setWriter(os); ! serializer.setOutputProperties(WebDAV.OUTPUT_PROPERTIES); ! AttributesImpl attrs = new AttributesImpl(); ! serializer.startDocument(); ! serializer.startPrefixMapping(PREFIX, WebDAV.DAV_NS); ! serializer.startElement(WebDAV.DAV_NS, "multistatus", "D:multistatus", attrs); ! ! if(type == FIND_ALL_PROPERTIES || type == FIND_BY_PROPERTY) { ! if(resource != null) ! writeResourceProperties(user, searchedProperties, type, collection, resource, serializer, servletPath); ! else ! writeCollectionProperties(user, broker, searchedProperties, type, collection, serializer, servletPath, depth, 0); ! } else if(type == FIND_PROPERTY_NAMES) ! writePropertyNames(collection, resource, serializer, servletPath); ! ! serializer.endElement(WebDAV.DAV_NS, "multistatus", "D:multistatus"); ! serializer.endPrefixMapping(PREFIX); ! serializer.endDocument(); ! } catch (SAXException e) { ! throw new ServletException("Exception while writing multistatus response: " + e.getMessage(), e); ! } finally { ! SAXSerializerPool.getInstance().returnSAXSerializer(serializer); ! } ! String content = os.toString(); ! LOG.debug("response:\n" + content); ! writeResponse(response, content); ! } catch (EXistException e) { ! throw new ServletException(e.getMessage(), e); ! } catch (LockException e) { ! response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); ! } finally { if(resource != null) ! resource.getUpdateLock().release(Lock.READ_LOCK); ! if(collection != null) ! collection.release(); ! pool.release(broker); ! } } } ! private void writeCollectionProperties(User user, DBBroker broker, DAVProperties searchedProperties, int type, Collection collection, SAXSerializer serializer, String servletPath, int maxDepth, int currentDepth) throws SAXException { *************** *** 287,300 **** if(currentDepth++ < maxDepth) { if(collection.getDocumentCount() > 0) { ! DBBroker broker = null; ! try { ! broker = pool.get(user); ! for(Iterator i = collection.iterator(broker); i.hasNext(); ) { ! DocumentImpl doc = (DocumentImpl)i.next(); writeResourceProperties(user, searchedProperties, type, collection, doc, serializer, servletPath); } - } catch (EXistException e) { - } finally { - pool.release(broker); } } --- 313,326 ---- if(currentDepth++ < maxDepth) { if(collection.getDocumentCount() > 0) { ! for(Iter... [truncated message content] |