From 23207fbf7fbd42b88e20c46627cf9d05b218d5a5 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Mon, 6 Jun 2011 18:31:52 +0000 Subject: [PATCH] Merged DEV/SWIFT to HEAD 25960: RepoBM: improve configurability - add option to configure base folder path - enable params (base urls, threads, base folder path, ...) to be configured via ant build.properties 25961: Merged BRANCHES/DEV/BM to BRANCHES/DEV/SWIFT: 24568: WebDAV - use fileInfo props (instead of nodeRef + getProp(s)) - resolve conflict 24727: SPP/WebDAV - compile fix (follow-on to r24568) 24855: BM - WebDAV - fix litmus -> locks -> 7. discover FAIL (fallout from r24568) + ran litmus 0.12.1 25963: Merged BRANCHES/DEV/BM to BRANCHES/DEV/SWIFT: 24784: Log stack trace when reporting exception 25966: Merged BRANCHES/DEV/BM to BRANCHES/DEV/SWIFT: 24725: BM - tweak validate (to use read-only txn) 25968: Merged BRANCHES/DEV/BM to BRANCHES/DEV/SWIFT: 24736: BM - getChildByName optimisation (add reverse-lookup for parentAssocs) 25992: RepoBM: add TPS - extend default ant-jmeter report to show approx/rounded test Time & TPS (note: not done for detailed report) - comment out detailed report - also expose "duration" param in ant build.xml / build.properties 26035: RepoBM: ALF-6796 - fix perf of report generation (switch from xalan to saxon) - also do not fail on error 26042: RepoBM: update readme (for ALF-6796) + add zip target 26045: (RECORD ONLY) Merged DEV/BM to DEV/SWIFT (RECORD ONLY) - already resolved for V3.4 & SWIFT Merged BRANCHES/V3.4 to BRANCHES/DEV/BM: 23613: Merged BRANCHES/DEV/BELARUS/HEAD_2010_10_21 to BRANCHES/V3.4: 23601: ALF-5447: It's impossible to save the MS Office 2010 document via webdav. Merged BRANCHES/V3.4 to BRANCHES/DEV/BM: 23618: Merged BRANCHES/DEV/V3.3-BUG-FIX to BRANCHES/V3.4: 23617: Merged BRANCHES/DEV/BELARUS/V3.3-2010_11_10 to BRANCHES/DEV/V3.3-BUG-FIX: 23602: ALF-5517: Webdav "supportedlock" propfind request fails if locking enabled Merged BRANCHES/V3.4 to BRANCHES/DEV/BM: 23997: Fix ALF-5731: Saving a doc from Office 2003 via WebDAV fails 26049: RepoBM: add "folder create" unit test - ALF-7309 (WebDAV) - ALF-7310 (CMIS) 26147: RepoBM: update WebDAV test - add patched sardine (thanks Florian) - adds "getResources(String url, int depth, boolean allProps)" 26219: RepoBM: test additions & improvements - add "itemRename" (document or folder) - for CMIS (ALF-7362) and WebDAV (ALF-7630) - update mixed scenario (add "folderCreate" & "itemRename") - for CMIS (ALF-7546) and WebDAV (ALF-7545) - cleanup of common code 26269: RepoBM: fix mixed scenarios (# of threads & weighted distribution) - use single thread group and interleave controllers - for CMIS (ALF-7546) and WebDAV (ALF-7545) 26271: (RECORD ONLY) Merged BRANCHES/DEV/BM to BRANCHES/DEV/SWIFT (RECORD-ONLY) - NOTE: verified w/ florian - NOTE: OpenCMIS and cmis-client-api are already on SWIFT - NOTE: cmis-bm has been superceded by repository-bm 26273: (RECORD ONLY) Merged BRANCHES/DEV/BM to BRANCHES/DEV/SWIFT (RECORD-ONLY) 24326: OpenCMIS update 26395: ALF-7755: add "system-build-test" project (and related RepoBM updates) - add ability to run "remote" tests (ie. selected *SystemTest) against embedded Jetty - initially run sanity builds test for RepoBM (RepositoryBenchmarkWebDAVSystemTest + RepositoryBenchmarkCMISSystemTest) & also SiteActivitySystemTest - RepoBM enhanced to import test data if not present (also added additional testItemDelete unit test) - using local copy of Spring 3.0.5 (requires at least 3.0.2) - can be rationalised once rest of Alfresco (ie. 3rd-party libs) moves up to a higher Spring version 26420: ALF-7755: tweak "system-build-test" for build box - also includes minor fixes to RepoBM (+ readme) 26448: ALF-7755: tweak "system-build-test" - for ant scripts (eg. running on build box) 26457: ALF-7898 - Alfresco Web Services: fix-up broken/regressed tests (WebServiceSuiteSystemTest) - revert default url context ... from "contentspaces" -> "alfresco" (broken during merge from ADB LC branch) - fix AuthoringServiceSystemTest.testVersionMethods() - when deleting version history - fix RepositoryServiceSystemTest.testPropertySetGet() - when creating dynamic model 26462: ALF-7898 / ALF-7755: add additional 'system' tests - effectively runs Alf Web Service build sanity tests (~= WebServiceSuiteSystemTest) 26478: ALF-7898 / ALF-7755: additional classpath fiddling (to get around limitation on Windows) - see also r26093 26487: Build fix: cut-and-paste formatting issue 26502: RepoBM: add "itemUpdate" (update props for doc or folder) - for CMIS (ALF-7633) - use Alfresco OpenCMIS Extension to update aspect props - for WebDAV (ALF-7631) - patch Sardine to allow custom namespaces 26526: ALF-7755: use temp classpaths 26528: ALF-7755: comment out for now - seems to work locally and on build boxes when run separately, but fails during full build - pending further investigation and testing (eg. when bamboo agents become free) 26567: ALF-7755: remove test-repository-bm since not used - was breaking the test classpath (for following tests) 26571: ALF-7755: re-enable RepoBenchmarkSystemTestSuite 26600: ALF-7755: test-system-build-test - add user.home (for build box env) - re-enable MiscSystemTestSuite (includes Alf WS* tests) 26609: ALF-7755: fix build/test (RepositoryServiceSystemTest.testPropertySetGet) - due to earlier MT test git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28217 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/repo/webdav/GetMethod.java | 11 +- .../org/alfresco/repo/webdav/LockMethod.java | 11 +- .../alfresco/repo/webdav/PropFindMethod.java | 45 +- .../alfresco/repo/webdav/WebDAVHelper.java | 14 +- .../alfresco/repo/webdav/WebDAVMethod.java | 39 +- .../alfresco/repo/webdav/WebDAVServlet.java | 774 +++++++++--------- 6 files changed, 448 insertions(+), 446 deletions(-) diff --git a/source/java/org/alfresco/repo/webdav/GetMethod.java b/source/java/org/alfresco/repo/webdav/GetMethod.java index 6733a5d9b4..2d02c8d1c1 100644 --- a/source/java/org/alfresco/repo/webdav/GetMethod.java +++ b/source/java/org/alfresco/repo/webdav/GetMethod.java @@ -29,7 +29,6 @@ import java.util.StringTokenizer; import javax.servlet.http.HttpServletResponse; -import org.springframework.extensions.surf.util.I18NUtil; import org.alfresco.repo.content.filestore.FileContentReader; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; @@ -40,6 +39,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.repository.datatype.TypeConverter; +import org.springframework.extensions.surf.util.I18NUtil; /** * Implements the WebDAV GET method @@ -50,8 +50,8 @@ public class GetMethod extends WebDAVMethod { // Request parameters - private ArrayList ifMatchTags = null; - private ArrayList ifNoneMatchTags = null; + private ArrayList ifMatchTags = null; + private ArrayList ifNoneMatchTags = null; private Date m_ifModifiedSince = null; private Date m_ifUnModifiedSince = null; @@ -188,13 +188,12 @@ public class GetMethod extends WebDAVMethod } else { - NodeRef pathNodeRef = realNodeInfo.getNodeRef(); // Return the node details, and content if requested, check that the node passes the pre-conditions checkPreConditions(realNodeInfo); // Build the response header - m_response.setHeader(WebDAV.HEADER_ETAG, getDAVHelper().makeQuotedETag(pathNodeRef)); + m_response.setHeader(WebDAV.HEADER_ETAG, getDAVHelper().makeQuotedETag(nodeInfo)); Date modifiedDate = realNodeInfo.getModifiedDate(); if (modifiedDate != null) @@ -231,7 +230,7 @@ public class GetMethod extends WebDAVMethod { // Make an etag for the node - String strETag = getDAVHelper().makeQuotedETag(nodeInfo.getNodeRef()); + String strETag = getDAVHelper().makeQuotedETag(nodeInfo); TypeConverter typeConv = DefaultTypeConverter.INSTANCE; // Check the If-Match header, don't send any content back if none of the tags in diff --git a/source/java/org/alfresco/repo/webdav/LockMethod.java b/source/java/org/alfresco/repo/webdav/LockMethod.java index e606278487..3f700e5752 100644 --- a/source/java/org/alfresco/repo/webdav/LockMethod.java +++ b/source/java/org/alfresco/repo/webdav/LockMethod.java @@ -291,7 +291,7 @@ public class LockMethod extends WebDAVMethod m_response.setHeader(WebDAV.HEADER_CONTENT_TYPE, WebDAV.XML_CONTENT_TYPE); // We either created a new lock or refreshed an existing lock, send back the lock details - generateResponse(lockNodeInfo.getNodeRef(), userName); + generateResponse(lockNodeInfo, userName); } /** @@ -326,6 +326,9 @@ public class LockMethod extends WebDAVMethod { // Lock the node lockService.lock(lockNode.getNodeRef(), LockType.WRITE_LOCK, getLockTimeout()); + + // update local cache (will be read back when generating the response) + lockNode.getProperties().put(ContentModel.PROP_LOCK_OWNER, userName); //this.lockInfo.setToken(lockToken); getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_OPAQUE_LOCK_TOKEN, lockToken); @@ -366,7 +369,7 @@ public class LockMethod extends WebDAVMethod /** * Generates the XML lock discovery response body */ - protected void generateResponse(NodeRef lockNode, String userName) throws Exception + protected void generateResponse(FileInfo lockNodeInfo, String userName) throws Exception { String scope; String lt; @@ -384,7 +387,7 @@ public class LockMethod extends WebDAVMethod // Output refreshed lock lt = this.lockInfo.getToken(); } - String owner = (String) getNodeService().getProperty(lockNode, ContentModel.PROP_LOCK_OWNER); + String owner = (String) lockNodeInfo.getProperties().get(ContentModel.PROP_LOCK_OWNER); XMLWriter xml = createXMLWriter(); @@ -394,7 +397,7 @@ public class LockMethod extends WebDAVMethod xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROP + nsdec, WebDAV.XML_NS_PROP + nsdec, getDAVHelper().getNullAttributes()); // Output the lock details - generateLockDiscoveryXML(xml, lockNode, false, scope, WebDAV.getDepthName(m_depth), lt, owner); + generateLockDiscoveryXML(xml, lockNodeInfo, false, scope, WebDAV.getDepthName(m_depth), lt, owner); // Close off the XML xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP); diff --git a/source/java/org/alfresco/repo/webdav/PropFindMethod.java b/source/java/org/alfresco/repo/webdav/PropFindMethod.java index 913c8b3769..4cceb68b3a 100644 --- a/source/java/org/alfresco/repo/webdav/PropFindMethod.java +++ b/source/java/org/alfresco/repo/webdav/PropFindMethod.java @@ -36,7 +36,6 @@ import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.repository.datatype.TypeConverter; @@ -370,7 +369,6 @@ public class PropFindMethod extends WebDAVMethod */ protected void generateResponseForNode(XMLWriter xml, FileInfo nodeInfo, String path) throws Exception { - NodeRef nodeRef = nodeInfo.getNodeRef(); boolean isFolder = nodeInfo.isFolder(); // Output the response block for the current node @@ -411,10 +409,10 @@ public class PropFindMethod extends WebDAVMethod generateNamedPropertiesResponse(xml, nodeInfo, isFolder); break; case GET_ALL_PROPS: - generateAllPropertiesResponse(xml, nodeRef, isFolder); + generateAllPropertiesResponse(xml, nodeInfo, isFolder); break; case FIND_PROPS: - generateFindPropertiesResponse(xml, nodeRef, isFolder); + generateFindPropertiesResponse(xml, nodeInfo, isFolder); break; } @@ -432,10 +430,8 @@ public class PropFindMethod extends WebDAVMethod */ private void generateNamedPropertiesResponse(XMLWriter xml, FileInfo nodeInfo, boolean isDir) throws Exception { - NodeRef nodeRef = nodeInfo.getNodeRef(); - // Get the properties for the node - Map props = getNodeService().getProperties(nodeRef); + Map props = nodeInfo.getProperties(); // Output the start of the properties element Attributes nullAttr = getDAVHelper().getNullAttributes(); @@ -454,7 +450,6 @@ public class PropFindMethod extends WebDAVMethod String propName = property.getName(); String propNamespaceUri = property.getNamespaceUri(); -// String propNamespaceName = property.getNamespaceName(); // Check if the property is a standard WebDAV property @@ -465,7 +460,7 @@ public class PropFindMethod extends WebDAVMethod // Check if the client is requesting lock information if (propName.equals(WebDAV.XML_LOCK_DISCOVERY)) // && metaData.isLocked()) { - generateLockDiscoveryResponse(xml, nodeRef, isDir); + generateLockDiscoveryResponse(xml, nodeInfo, isDir); } else if (propName.equals(WebDAV.XML_SUPPORTED_LOCK)) { @@ -489,7 +484,7 @@ public class PropFindMethod extends WebDAVMethod else if (propName.equals(WebDAV.XML_DISPLAYNAME)) { // Get the node name - if (getRootNodeRef().equals(nodeRef)) + if (getRootNodeRef().equals(nodeInfo.getNodeRef())) { // Output an empty name for the root node xml.write(DocumentHelper.createElement(WebDAV.XML_NS_SOURCE)); @@ -506,7 +501,7 @@ public class PropFindMethod extends WebDAVMethod String name = typeConv.convert(String.class, davValue); if (name == null || name.length() == 0) { - logger.error("WebDAV name is null, value=" + davValue.getClass().getName() + ", node=" + nodeRef); + logger.error("WebDAV name is null, value=" + davValue.getClass().getName() + ", node=" + nodeInfo.getNodeRef()); } xml.write(name); } @@ -563,7 +558,7 @@ public class PropFindMethod extends WebDAVMethod // Output the etag xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_ETAG, WebDAV.XML_NS_GET_ETAG, nullAttr); - xml.write(getDAVHelper().makeETag(nodeRef)); + xml.write(getDAVHelper().makeETag(nodeInfo)); xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_ETAG, WebDAV.XML_NS_GET_ETAG); } else if (propName.equals(WebDAV.XML_GET_CONTENT_LENGTH)) @@ -616,11 +611,11 @@ public class PropFindMethod extends WebDAVMethod else { // Look in the custom properties - + // TODO: Custom properties lookup -// String qualifiedName = propNamespaceUri + WebDAV.NAMESPACE_SEPARATOR + propName; - - String value = (String) getNodeService().getProperty(nodeRef, property.createQName()); + // String qualifiedName = propNamespaceUri + WebDAV.NAMESPACE_SEPARATOR + propName; + + String value = (String) nodeInfo.getProperties().get(property.createQName()); if (value == null) { propertiesNotFound.add(property); @@ -699,11 +694,11 @@ public class PropFindMethod extends WebDAVMethod * @param node NodeRef * @param isDir boolean */ - protected void generateAllPropertiesResponse(XMLWriter xml, NodeRef node, boolean isDir) throws Exception + protected void generateAllPropertiesResponse(XMLWriter xml, FileInfo nodeInfo, boolean isDir) throws Exception { // Get the properties for the node - Map props = getNodeService().getProperties(node); + Map props = nodeInfo.getProperties(); // Output the start of the properties element @@ -714,7 +709,7 @@ public class PropFindMethod extends WebDAVMethod // Generate a lock status report, if locked - generateLockDiscoveryResponse(xml, node, isDir); + generateLockDiscoveryResponse(xml, nodeInfo, isDir); // Output the supported lock types @@ -741,7 +736,7 @@ public class PropFindMethod extends WebDAVMethod String name = typeConv.convert(String.class, davValue); if (name == null || name.length() == 0) { - logger.error("WebDAV name is null, value=" + davValue.getClass().getName() + ", node=" + node); + logger.error("WebDAV name is null, value=" + davValue.getClass().getName() + ", node=" + nodeInfo.getNodeRef()); } xml.write(name); } @@ -801,7 +796,7 @@ public class PropFindMethod extends WebDAVMethod // Output the etag xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_ETAG, WebDAV.XML_NS_GET_ETAG, nullAttr); - xml.write(getDAVHelper().makeETag(node)); + xml.write(getDAVHelper().makeETag(nodeInfo)); xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_ETAG, WebDAV.XML_NS_GET_ETAG); } @@ -850,7 +845,7 @@ public class PropFindMethod extends WebDAVMethod * @param node NodeRef * @param isDir boolean */ - protected void generateFindPropertiesResponse(XMLWriter xml, NodeRef node, boolean isDir) + protected void generateFindPropertiesResponse(XMLWriter xml, FileInfo nodeInfo, boolean isDir) { try { @@ -908,14 +903,14 @@ public class PropFindMethod extends WebDAVMethod * @param node NodeRef * @param isDir boolean */ - protected void generateLockDiscoveryResponse(XMLWriter xml, NodeRef node, boolean isDir) throws Exception + protected void generateLockDiscoveryResponse(XMLWriter xml, FileInfo nodeInfo, boolean isDir) throws Exception { // Output the lock status response - LockInfo lockInfo = getNodeLockInfo(node); + LockInfo lockInfo = getNodeLockInfo(nodeInfo); if (lockInfo.isLocked()) { - generateLockDiscoveryXML(xml, node, lockInfo); + generateLockDiscoveryXML(xml, nodeInfo, lockInfo); } } diff --git a/source/java/org/alfresco/repo/webdav/WebDAVHelper.java b/source/java/org/alfresco/repo/webdav/WebDAVHelper.java index 5c0e11d602..934ad89489 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAVHelper.java +++ b/source/java/org/alfresco/repo/webdav/WebDAVHelper.java @@ -353,24 +353,24 @@ public class WebDAVHelper /** * Make an ETag value for a node using the GUID and modify date/time */ - public final String makeETag(NodeRef node) + public final String makeETag(FileInfo nodeInfo) { // Get the modify date/time property for the node StringBuilder etag = new StringBuilder(); - makeETagString(node, etag); + makeETagString(nodeInfo, etag); return etag.toString(); } /** * Make an ETag value for a node using the GUID and modify date/time */ - public final String makeQuotedETag(NodeRef node) + public final String makeQuotedETag(FileInfo nodeInfo) { StringBuilder etag = new StringBuilder(); etag.append("\""); - makeETagString(node, etag); + makeETagString(nodeInfo, etag); etag.append("\""); return etag.toString(); } @@ -378,13 +378,13 @@ public class WebDAVHelper /** * Make an ETag value for a node using the GUID and modify date/time */ - protected final void makeETagString(NodeRef node, StringBuilder etag) + protected final void makeETagString(FileInfo nodeInfo, StringBuilder etag) { // Get the modify date/time property for the node - Object modVal = getNodeService().getProperty(node, ContentModel.PROP_MODIFIED); + Object modVal = nodeInfo.getProperties().get(ContentModel.PROP_MODIFIED); - etag.append(node.getId()); + etag.append(nodeInfo.getNodeRef().getId()); if ( modVal != null) { diff --git a/source/java/org/alfresco/repo/webdav/WebDAVMethod.java b/source/java/org/alfresco/repo/webdav/WebDAVMethod.java index e8940bdbd1..78923ca192 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAVMethod.java +++ b/source/java/org/alfresco/repo/webdav/WebDAVMethod.java @@ -737,10 +737,10 @@ public abstract class WebDAVMethod * @param xml XMLWriter * @param lockNode NodeRef */ - protected void generateLockDiscoveryXML(XMLWriter xml, NodeRef lockNode, LockInfo lockInfo) throws Exception + protected void generateLockDiscoveryXML(XMLWriter xml, FileInfo lockNodeInfo, LockInfo lockInfo) throws Exception { - String owner = (String) getNodeService().getProperty(lockNode, ContentModel.PROP_LOCK_OWNER); - generateLockDiscoveryXML(xml, lockNode, false, lockInfo.getScope(), lockInfo.getDepth(), WebDAV.makeLockToken(lockNode, owner), owner); + String owner = (String) lockNodeInfo.getProperties().get(ContentModel.PROP_LOCK_OWNER); + generateLockDiscoveryXML(xml, lockNodeInfo, false, lockInfo.getScope(), lockInfo.getDepth(), WebDAV.makeLockToken(lockNodeInfo.getNodeRef(), owner), owner); } /** @@ -755,18 +755,14 @@ public abstract class WebDAVMethod * @param owner String lock owner * */ - protected void generateLockDiscoveryXML(XMLWriter xml, NodeRef lockNode, boolean emptyNamespace, String scope, String depth, String lToken, String owner) throws Exception + protected void generateLockDiscoveryXML(XMLWriter xml, FileInfo lockNodeInfo, boolean emptyNamespace, String scope, String depth, String lToken, String owner) throws Exception { Attributes nullAttr= getDAVHelper().getNullAttributes(); String ns = emptyNamespace ? "" : WebDAV.DAV_NS; - if (lockNode != null) + if (lockNodeInfo != null) { - // Get the lock details - - NodeService nodeService = getNodeService(); - - Date expiryDate = (Date) nodeService.getProperty(lockNode, ContentModel.PROP_EXPIRY_DATE); + Date expiryDate = (Date) lockNodeInfo.getProperties().get(ContentModel.PROP_EXPIRY_DATE); // Output the XML response @@ -864,8 +860,8 @@ public abstract class WebDAVMethod */ protected LockInfo checkNode(FileInfo fileInfo, boolean ignoreShared, boolean lockMethod) throws WebDAVServerException { - LockInfo nodeLockInfo = getNodeLockInfo(fileInfo.getNodeRef()); - String nodeETag = getDAVHelper().makeQuotedETag(fileInfo.getNodeRef()); + LockInfo nodeLockInfo = getNodeLockInfo(fileInfo); + String nodeETag = getDAVHelper().makeQuotedETag(fileInfo); if (m_conditions == null) @@ -1055,25 +1051,25 @@ public abstract class WebDAVMethod * @param fileInfo node * @return String Lock token */ - protected LockInfo getNodeLockInfo(NodeRef nodeRef) + protected LockInfo getNodeLockInfo(FileInfo nodeInfo) { LockInfo lockInfo = new LockInfo(); NodeService nodeService = getNodeService(); LockService lockService = getLockService(); // Check if node is locked directly. - LockStatus lockSts = lockService.getLockStatus(nodeRef); + LockStatus lockSts = lockService.getLockStatus(nodeInfo.getNodeRef()); if (lockSts == LockStatus.LOCKED || lockSts == LockStatus.LOCK_OWNER) { - String propOpaqueLockToken = (String) nodeService.getProperty(nodeRef, WebDAVModel.PROP_OPAQUE_LOCK_TOKEN); + String propOpaqueLockToken = (String) nodeInfo.getProperties().get(WebDAVModel.PROP_OPAQUE_LOCK_TOKEN); if (propOpaqueLockToken != null) { // Get lock depth - String depth = (String) nodeService.getProperty(nodeRef, WebDAVModel.PROP_LOCK_DEPTH); + String depth = (String) nodeInfo.getProperties().get(WebDAVModel.PROP_LOCK_DEPTH); //Get lock scope - String scope = (String) nodeService.getProperty(nodeRef, WebDAVModel.PROP_LOCK_SCOPE); + String scope = (String) nodeInfo.getProperties().get(WebDAVModel.PROP_LOCK_SCOPE); // Get shared lock tokens - String sharedLocks = (String) nodeService.getProperty(nodeRef, WebDAVModel.PROP_SHARED_LOCK_TOKENS); + String sharedLocks = (String) nodeInfo.getProperties().get(WebDAVModel.PROP_SHARED_LOCK_TOKENS); // Node has it's own Lock token. // Store lock information to the lockInfo object @@ -1088,13 +1084,13 @@ public abstract class WebDAVMethod else { // No has no exclusive lock but can be locked with shared lock - String sharedLocks = (String) nodeService.getProperty(nodeRef, WebDAVModel.PROP_SHARED_LOCK_TOKENS); + String sharedLocks = (String) nodeInfo.getProperties().get(WebDAVModel.PROP_SHARED_LOCK_TOKENS); if (sharedLocks != null) { // Get lock depth - String depth = (String) nodeService.getProperty(nodeRef, WebDAVModel.PROP_LOCK_DEPTH); + String depth = (String) nodeInfo.getProperties().get(WebDAVModel.PROP_LOCK_DEPTH); //Get lock scope - String scope = (String) nodeService.getProperty(nodeRef, WebDAVModel.PROP_LOCK_SCOPE); + String scope = (String) nodeInfo.getProperties().get(WebDAVModel.PROP_LOCK_SCOPE); // Node has it's own Lock token. // Store lock information to the lockInfo object @@ -1110,6 +1106,7 @@ public abstract class WebDAVMethod // Node isn't locked directly and has no it's own Lock token. // Try to search indirect lock. + NodeRef nodeRef = nodeInfo.getNodeRef(); NodeRef node = nodeRef; while (true) { diff --git a/source/java/org/alfresco/repo/webdav/WebDAVServlet.java b/source/java/org/alfresco/repo/webdav/WebDAVServlet.java index f40bba7dac..6b285c58c9 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAVServlet.java +++ b/source/java/org/alfresco/repo/webdav/WebDAVServlet.java @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2005-2010 Alfresco Software Limited. * * This file is part of Alfresco @@ -14,385 +14,393 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.webdav; - -import java.io.IOException; -import java.util.Hashtable; -import java.util.Properties; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.transaction.UserTransaction; - -import org.alfresco.repo.security.authentication.AuthenticationContext; -import org.alfresco.repo.tenant.TenantService; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.cmr.security.AuthenticationService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.PropertyCheck; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.WebApplicationContextUtils; - -/** - * Servlet that accepts WebDAV requests for the hub. The request is served by the hub's content - * repository framework and the response sent back using the WebDAV protocol. - * - * @author gavinc - */ -public class WebDAVServlet extends HttpServlet -{ - private static final long serialVersionUID = 6900069445027527165L; - - // Logging - private static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol"); - - // Constants - public static final String WEBDAV_PREFIX = "webdav"; - private static final String INTERNAL_SERVER_ERROR = "Internal Server Error: "; - - // Init parameter names - private static final String BEAN_INIT_PARAMS = "webdav.initParams"; - - // Service registry, used by methods to find services to process requests - private ServiceRegistry m_serviceRegistry; - - // Transaction service, each request is wrapped in a transaction - private TransactionService m_transactionService; - - // WebDAV method handlers - protected Hashtable> m_davMethods; - - // Root node - private MTNodesCache m_rootNodes; - - // WebDAV helper class - private WebDAVHelper m_davHelper; - - /** - * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, - IOException - { - long startTime = 0; - if (logger.isInfoEnabled()) - { - startTime = System.currentTimeMillis(); - } - - try - { - // Create the appropriate WebDAV method for the request and execute it - final WebDAVMethod method = createMethod(request, response); - - if (method == null) - { - if ( logger.isErrorEnabled()) - logger.error("WebDAV method not implemented - " + request.getMethod()); - - // Return an error status - - response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); - return; - } - else if (method.getRootNodeRef() == null) - { - if ( logger.isErrorEnabled()) - logger.error("No root node for request"); - - // Return an error status - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - return; - } - - // Execute the WebDAV request, which must take care of its own transaction - method.execute(); - } - catch (Throwable e) - { - if (!(e instanceof WebDAVServerException) && e.getCause() != null) - { - if (e.getCause() instanceof WebDAVServerException) - { - e = e.getCause(); - } - } - // Work out how to handle the error - if (e instanceof WebDAVServerException) - { - WebDAVServerException error = (WebDAVServerException) e; - if (error.getCause() != null) - { - logger.error(INTERNAL_SERVER_ERROR, error.getCause()); - } - - if (logger.isDebugEnabled()) - { - // Show what status code the method sent back - - logger.debug(request.getMethod() + " is returning status code: " + error.getHttpStatusCode()); - } - - if (response.isCommitted()) - { - logger.warn("Could not return the status code to the client as the response has already been committed!"); - } - else - { - response.sendError(error.getHttpStatusCode()); - } - } - else - { - logger.error(INTERNAL_SERVER_ERROR, e); - - if (response.isCommitted()) - { - logger.warn("Could not return the internal server error code to the client as the response has already been committed!"); - } - else - { - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } - } - finally - { - if (logger.isInfoEnabled()) - { - logger.info(request.getMethod() + " took " + (System.currentTimeMillis()-startTime) + "ms to execute ["+request.getRequestURI()+"]"); - } - } - } - - /** - * Create a WebDAV method handler - * - * @param request HttpServletRequest - * @param response HttpServletResponse - * @return WebDAVMethod - */ - private WebDAVMethod createMethod(HttpServletRequest request, HttpServletResponse response) - { - // Get the type of the current request - - String strHttpMethod = request.getMethod(); - - if (logger.isDebugEnabled()) - logger.debug("WebDAV request " + strHttpMethod + " on path " - + request.getRequestURI()); - - Class methodClass = m_davMethods.get(strHttpMethod); - WebDAVMethod method = null; - - if ( methodClass != null) - { - try - { - // Create the handler method - - method = methodClass.newInstance(); - NodeRef rootNodeRef = m_rootNodes.getNodeForCurrentTenant(); - method.setDetails(request, response, m_davHelper, rootNodeRef); - } - catch (Exception ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug(ex); - } - } - - // Return the WebDAV method handler, or null if not supported - - return method; - } - - /** - * Initialize the servlet - * - * @param config ServletConfig - * @exception ServletException - */ - public void init(ServletConfig config) throws ServletException - { - super.init(config); - - // Get service registry - WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); - - // If no context has been initialised, exit silently so config changes can be made - if (context == null) - { - return; - } - - // Get global configuration properties - WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); - WebDAVInitParameters initParams = (WebDAVInitParameters) wc.getBean(BEAN_INIT_PARAMS); - - // Render this servlet permanently unavailable if its enablement property is not set - if (!initParams.getEnabled()) - { - throw new UnavailableException("WebDAV not enabled."); - } - - // Get root paths - - String storeValue = initParams.getStoreName(); - String rootPath = initParams.getRootPath(); - - // Get beans - - m_serviceRegistry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY); - - m_transactionService = m_serviceRegistry.getTransactionService(); - TenantService tenantService = (TenantService) context.getBean("tenantService"); - AuthenticationService authService = (AuthenticationService) context.getBean("authenticationService"); - NodeService nodeService = (NodeService) context.getBean("NodeService"); - SearchService searchService = (SearchService) context.getBean("SearchService"); - NamespaceService namespaceService = (NamespaceService) context.getBean("NamespaceService"); - - // Create the WebDAV helper - m_davHelper = new WebDAVHelper(m_serviceRegistry, authService); - - // Initialize the root node - - initializeRootNode(storeValue, rootPath, context, nodeService, searchService, namespaceService, tenantService, m_transactionService); - - // Create the WebDAV methods table - - m_davMethods = new Hashtable>(); - - m_davMethods.put(WebDAV.METHOD_PROPFIND, PropFindMethod.class); - m_davMethods.put(WebDAV.METHOD_PROPPATCH, PropPatchMethod.class); - m_davMethods.put(WebDAV.METHOD_COPY, CopyMethod.class); - m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class); - m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class); - m_davMethods.put(WebDAV.METHOD_HEAD, HeadMethod.class); - m_davMethods.put(WebDAV.METHOD_LOCK, LockMethod.class); - m_davMethods.put(WebDAV.METHOD_MKCOL, MkcolMethod.class); - m_davMethods.put(WebDAV.METHOD_MOVE, MoveMethod.class); - m_davMethods.put(WebDAV.METHOD_OPTIONS, OptionsMethod.class); - m_davMethods.put(WebDAV.METHOD_POST, PostMethod.class); - m_davMethods.put(WebDAV.METHOD_PUT, PutMethod.class); - m_davMethods.put(WebDAV.METHOD_UNLOCK, UnlockMethod.class); - } - - - /** - * @param storeValue - * @param rootPath - * @param context - * @param nodeService - * @param searchService - * @param namespaceService - * @param tenantService - * @param m_transactionService - */ - private void initializeRootNode(String storeValue, String rootPath, WebApplicationContext context, NodeService nodeService, SearchService searchService, - NamespaceService namespaceService, TenantService tenantService, TransactionService m_transactionService) - { - - // Use the system user as the authenticated context for the filesystem initialization - - AuthenticationContext authComponent = (AuthenticationContext) context.getBean("authenticationContext"); - authComponent.setSystemUserAsCurrentUser(); - - // Wrap the initialization in a transaction - - UserTransaction tx = m_transactionService.getUserTransaction(true); - - try - { - // Start the transaction - - if (tx != null) - tx.begin(); - - m_rootNodes = new MTNodesCache(new StoreRef(storeValue), rootPath, nodeService, searchService, namespaceService, tenantService); - - // Commit the transaction - - tx.commit(); - } - catch (Exception ex) - { - logger.error(ex); - } - finally - { - // Clear the current system user - - authComponent.clearCurrentSecurityContext(); - } - } - - /** - * Bean to hold injected initialization parameters. - * - * @author Derek Hulley - * @since V3.5 Team - */ - public static class WebDAVInitParameters - { - private boolean enabled = false; - private String storeName; - private String rootPath; - public boolean getEnabled() - { - return enabled; - } - public void setEnabled(boolean enabled) - { - this.enabled = enabled; - } - /** - * @return Returns the name of the store - * @throws ServletException if the store name was not set - */ - public String getStoreName() throws ServletException - { - if (!PropertyCheck.isValidPropertyString(storeName)) - { - throw new ServletException("WebDAV missing 'storeName' value."); - } - return storeName; - } - public void setStoreName(String storeName) - { - this.storeName = storeName; - } - /** - * @return Returns the WebDAV root path within the store - * @throws ServletException if the root path was not set - */ - public String getRootPath() throws ServletException - { - if (!PropertyCheck.isValidPropertyString(rootPath)) - { - throw new ServletException("WebDAV missing 'rootPath' value."); - } - return rootPath; - } - public void setRootPath(String rootPath) - { - this.rootPath = rootPath; - } - } -} + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.webdav; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Hashtable; +import java.util.Properties; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.UnavailableException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.transaction.UserTransaction; + +import org.alfresco.repo.security.authentication.AuthenticationContext; +import org.alfresco.repo.tenant.TenantService; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.transaction.TransactionService; +import org.alfresco.util.PropertyCheck; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Servlet that accepts WebDAV requests for the hub. The request is served by the hub's content + * repository framework and the response sent back using the WebDAV protocol. + * + * @author gavinc + */ +public class WebDAVServlet extends HttpServlet +{ + private static final long serialVersionUID = 6900069445027527165L; + + // Logging + private static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol"); + + // Constants + public static final String WEBDAV_PREFIX = "webdav"; + private static final String INTERNAL_SERVER_ERROR = "Internal Server Error: "; + + // Init parameter names + private static final String BEAN_INIT_PARAMS = "webdav.initParams"; + + // Service registry, used by methods to find services to process requests + private ServiceRegistry m_serviceRegistry; + + // Transaction service, each request is wrapped in a transaction + private TransactionService m_transactionService; + + // WebDAV method handlers + protected Hashtable> m_davMethods; + + // Root node + private MTNodesCache m_rootNodes; + + // WebDAV helper class + private WebDAVHelper m_davHelper; + + /** + * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, + IOException + { + long startTime = 0; + if (logger.isInfoEnabled()) + { + startTime = System.currentTimeMillis(); + } + + try + { + // Create the appropriate WebDAV method for the request and execute it + final WebDAVMethod method = createMethod(request, response); + + if (method == null) + { + if ( logger.isErrorEnabled()) + logger.error("WebDAV method not implemented - " + request.getMethod()); + + // Return an error status + + response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); + return; + } + else if (method.getRootNodeRef() == null) + { + if ( logger.isErrorEnabled()) + logger.error("No root node for request"); + + // Return an error status + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + + // Execute the WebDAV request, which must take care of its own transaction + method.execute(); + } + catch (Throwable e) + { + if (!(e instanceof WebDAVServerException) && e.getCause() != null) + { + if (e.getCause() instanceof WebDAVServerException) + { + e = e.getCause(); + } + } + // Work out how to handle the error + if (e instanceof WebDAVServerException) + { + WebDAVServerException error = (WebDAVServerException) e; + if (error.getCause() != null) + { + StringWriter writer = new StringWriter(); + PrintWriter print = new PrintWriter(writer); + error.printStackTrace(print); + logger.error(print.toString(), e); + } + + if (logger.isDebugEnabled()) + { + // Show what status code the method sent back + + logger.debug(request.getMethod() + " is returning status code: " + error.getHttpStatusCode()); + } + + if (response.isCommitted()) + { + logger.warn("Could not return the status code to the client as the response has already been committed!"); + } + else + { + response.sendError(error.getHttpStatusCode()); + } + } + else + { + StringWriter writer = new StringWriter(); + PrintWriter print = new PrintWriter(writer); + e.printStackTrace(print); + logger.error(print.toString(), e); + + if (response.isCommitted()) + { + logger.warn("Could not return the internal server error code to the client as the response has already been committed!"); + } + else + { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + } + finally + { + if (logger.isInfoEnabled()) + { + logger.info(request.getMethod() + " took " + (System.currentTimeMillis()-startTime) + "ms to execute ["+request.getRequestURI()+"]"); + } + } + } + + /** + * Create a WebDAV method handler + * + * @param request HttpServletRequest + * @param response HttpServletResponse + * @return WebDAVMethod + */ + private WebDAVMethod createMethod(HttpServletRequest request, HttpServletResponse response) + { + // Get the type of the current request + + String strHttpMethod = request.getMethod(); + + if (logger.isDebugEnabled()) + logger.debug("WebDAV request " + strHttpMethod + " on path " + + request.getRequestURI()); + + Class methodClass = m_davMethods.get(strHttpMethod); + WebDAVMethod method = null; + + if ( methodClass != null) + { + try + { + // Create the handler method + + method = methodClass.newInstance(); + NodeRef rootNodeRef = m_rootNodes.getNodeForCurrentTenant(); + method.setDetails(request, response, m_davHelper, rootNodeRef); + } + catch (Exception ex) + { + // Debug + + if ( logger.isDebugEnabled()) + logger.debug(ex); + } + } + + // Return the WebDAV method handler, or null if not supported + + return method; + } + + /** + * Initialize the servlet + * + * @param config ServletConfig + * @exception ServletException + */ + public void init(ServletConfig config) throws ServletException + { + super.init(config); + + // Get service registry + WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); + + // If no context has been initialised, exit silently so config changes can be made + if (context == null) + { + return; + } + + // Get global configuration properties + WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); + WebDAVInitParameters initParams = (WebDAVInitParameters) wc.getBean(BEAN_INIT_PARAMS); + + // Render this servlet permanently unavailable if its enablement property is not set + if (!initParams.getEnabled()) + { + throw new UnavailableException("WebDAV not enabled."); + } + + // Get root paths + + String storeValue = initParams.getStoreName(); + String rootPath = initParams.getRootPath(); + + // Get beans + + m_serviceRegistry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY); + + m_transactionService = m_serviceRegistry.getTransactionService(); + TenantService tenantService = (TenantService) context.getBean("tenantService"); + AuthenticationService authService = (AuthenticationService) context.getBean("authenticationService"); + NodeService nodeService = (NodeService) context.getBean("NodeService"); + SearchService searchService = (SearchService) context.getBean("SearchService"); + NamespaceService namespaceService = (NamespaceService) context.getBean("NamespaceService"); + + // Create the WebDAV helper + m_davHelper = new WebDAVHelper(m_serviceRegistry, authService); + + // Initialize the root node + + initializeRootNode(storeValue, rootPath, context, nodeService, searchService, namespaceService, tenantService, m_transactionService); + + // Create the WebDAV methods table + + m_davMethods = new Hashtable>(); + + m_davMethods.put(WebDAV.METHOD_PROPFIND, PropFindMethod.class); + m_davMethods.put(WebDAV.METHOD_PROPPATCH, PropPatchMethod.class); + m_davMethods.put(WebDAV.METHOD_COPY, CopyMethod.class); + m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class); + m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class); + m_davMethods.put(WebDAV.METHOD_HEAD, HeadMethod.class); + m_davMethods.put(WebDAV.METHOD_LOCK, LockMethod.class); + m_davMethods.put(WebDAV.METHOD_MKCOL, MkcolMethod.class); + m_davMethods.put(WebDAV.METHOD_MOVE, MoveMethod.class); + m_davMethods.put(WebDAV.METHOD_OPTIONS, OptionsMethod.class); + m_davMethods.put(WebDAV.METHOD_POST, PostMethod.class); + m_davMethods.put(WebDAV.METHOD_PUT, PutMethod.class); + m_davMethods.put(WebDAV.METHOD_UNLOCK, UnlockMethod.class); + } + + + /** + * @param storeValue + * @param rootPath + * @param context + * @param nodeService + * @param searchService + * @param namespaceService + * @param tenantService + * @param m_transactionService + */ + private void initializeRootNode(String storeValue, String rootPath, WebApplicationContext context, NodeService nodeService, SearchService searchService, + NamespaceService namespaceService, TenantService tenantService, TransactionService m_transactionService) + { + + // Use the system user as the authenticated context for the filesystem initialization + + AuthenticationContext authComponent = (AuthenticationContext) context.getBean("authenticationContext"); + authComponent.setSystemUserAsCurrentUser(); + + // Wrap the initialization in a transaction + + UserTransaction tx = m_transactionService.getUserTransaction(true); + + try + { + // Start the transaction + + if (tx != null) + tx.begin(); + + m_rootNodes = new MTNodesCache(new StoreRef(storeValue), rootPath, nodeService, searchService, namespaceService, tenantService); + + // Commit the transaction + + tx.commit(); + } + catch (Exception ex) + { + logger.error(ex); + } + finally + { + // Clear the current system user + + authComponent.clearCurrentSecurityContext(); + } + } + + /** + * Bean to hold injected initialization parameters. + * + * @author Derek Hulley + * @since V3.5 Team + */ + public static class WebDAVInitParameters + { + private boolean enabled = false; + private String storeName; + private String rootPath; + public boolean getEnabled() + { + return enabled; + } + public void setEnabled(boolean enabled) + { + this.enabled = enabled; + } + /** + * @return Returns the name of the store + * @throws ServletException if the store name was not set + */ + public String getStoreName() throws ServletException + { + if (!PropertyCheck.isValidPropertyString(storeName)) + { + throw new ServletException("WebDAV missing 'storeName' value."); + } + return storeName; + } + public void setStoreName(String storeName) + { + this.storeName = storeName; + } + /** + * @return Returns the WebDAV root path within the store + * @throws ServletException if the root path was not set + */ + public String getRootPath() throws ServletException + { + if (!PropertyCheck.isValidPropertyString(rootPath)) + { + throw new ServletException("WebDAV missing 'rootPath' value."); + } + return rootPath; + } + public void setRootPath(String rootPath) + { + this.rootPath = rootPath; + } + } +}