mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
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
This commit is contained in:
@@ -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<String> ifMatchTags = null;
|
||||
private ArrayList<String> 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
|
||||
|
@@ -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);
|
||||
|
@@ -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<QName, Serializable> props = getNodeService().getProperties(nodeRef);
|
||||
Map<QName, Serializable> 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<QName, Serializable> props = getNodeService().getProperties(node);
|
||||
Map<QName, Serializable> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<String,Class<? extends WebDAVMethod>> 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<? extends WebDAVMethod> 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<String, Class<? extends WebDAVMethod>>();
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<String,Class<? extends WebDAVMethod>> 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<? extends WebDAVMethod> 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<String, Class<? extends WebDAVMethod>>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user