mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged V3.2 to HEAD
17891: Merged DEV_TEMPORARY to V3.2 17873: ETHREEOH-3810: WCM - Recursion detector erroring 18032: Merged V3.1 to V3.2 18030: Merged V2.2 to V3.1 17683: Merged DEV_TEMPORARY to V2.2 (back-port of fix) 17677: ETHREEOH-2778: davfs2 is not working correctly with Alfresco 17880: Merged DEV_TEMPORARY to V2.2 (record-only as fix is already applied to 3.1 branch) 17845: ETWOTWO-1289: My Web Files (Forms) dashlets: XSS Attck can be made when web project's details has been edited 18062: Merged DEV_TEMPORARY to V3.2 18036: ETHREEOH-1844: Text field (areas) became non-editable if user use navigate-remove combination for repeatable elements on Create Web content based on web form screen 18205: Merged V3.1 to V3.2 (record-only) *RECORD ONLY* Merged DEV/TEMPORARY to 3.1 17837: ETHREEOH-3801: Creating users via the api does not add them to the user store 18277: Merged DEV_TEMPORARY to V3.2 18178: ETHREEOH-3222: ERROR [org.alfresco.webdav.protocol] WebDAV method not implemented - PROPPATCH 18311: Fix for ETHREEOH-3872: forms32 examples not working 18317: Remaining fixes to forms samples (ETHREEOH-3872) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18318 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -24,6 +24,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.webdav;
|
package org.alfresco.repo.webdav;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@@ -37,7 +40,10 @@ import org.alfresco.service.cmr.model.FileFolderService;
|
|||||||
import org.alfresco.service.cmr.model.FileInfo;
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.dom4j.DocumentHelper;
|
||||||
import org.dom4j.io.XMLWriter;
|
import org.dom4j.io.XMLWriter;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the WebDAV LOCK method
|
* Implements the WebDAV LOCK method
|
||||||
@@ -46,6 +52,8 @@ import org.dom4j.io.XMLWriter;
|
|||||||
*/
|
*/
|
||||||
public class LockMethod extends WebDAVMethod
|
public class LockMethod extends WebDAVMethod
|
||||||
{
|
{
|
||||||
|
public static final String EMPTY_NS = "";
|
||||||
|
|
||||||
private String m_strLockToken = null;
|
private String m_strLockToken = null;
|
||||||
private int m_timeoutDuration = WebDAV.DEPTH_INFINITY;
|
private int m_timeoutDuration = WebDAV.DEPTH_INFINITY;
|
||||||
|
|
||||||
@@ -232,6 +240,9 @@ public class LockMethod extends WebDAVMethod
|
|||||||
createLock(lockNodeInfo.getNodeRef(), userName);
|
createLock(lockNodeInfo.getNodeRef(), userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_response.setHeader(WebDAV.HEADER_LOCK_TOKEN, "<" + WebDAV.makeLockToken(lockNodeInfo.getNodeRef(), userName) + ">");
|
||||||
|
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
|
// We either created a new lock or refreshed an existing lock, send back the lock details
|
||||||
generateResponse(lockNodeInfo.getNodeRef(), userName);
|
generateResponse(lockNodeInfo.getNodeRef(), userName);
|
||||||
}
|
}
|
||||||
@@ -302,16 +313,125 @@ public class LockMethod extends WebDAVMethod
|
|||||||
xml.startDocument();
|
xml.startDocument();
|
||||||
|
|
||||||
String nsdec = generateNamespaceDeclarations(null);
|
String nsdec = generateNamespaceDeclarations(null);
|
||||||
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_MULTI_STATUS + nsdec, WebDAV.XML_NS_MULTI_STATUS + nsdec,
|
xml.startElement(EMPTY_NS, WebDAV.XML_PROP + nsdec, WebDAV.XML_PROP + nsdec,
|
||||||
getDAVHelper().getNullAttributes());
|
getDAVHelper().getNullAttributes());
|
||||||
|
|
||||||
// Output the lock details
|
// Output the lock details
|
||||||
generateLockDiscoveryXML(xml, lockNode);
|
generateLockDiscoveryXML(xml, lockNode);
|
||||||
|
|
||||||
// Close off the XML
|
// Close off the XML
|
||||||
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_MULTI_STATUS, WebDAV.XML_NS_MULTI_STATUS);
|
xml.endElement(EMPTY_NS, WebDAV.XML_PROP, WebDAV.XML_PROP);
|
||||||
|
|
||||||
// Send the XML back to the client
|
// Send the XML back to the client
|
||||||
xml.flush();
|
xml.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the lock discovery XML response
|
||||||
|
*
|
||||||
|
* @param xml XMLWriter
|
||||||
|
* @param lockNode NodeRef
|
||||||
|
*/
|
||||||
|
protected void generateLockDiscoveryXML(XMLWriter xml, NodeRef lockNode) throws Exception
|
||||||
|
{
|
||||||
|
Attributes nullAttr= getDAVHelper().getNullAttributes();
|
||||||
|
|
||||||
|
if (lockNode != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Get the lock details
|
||||||
|
|
||||||
|
NodeService nodeService = getNodeService();
|
||||||
|
|
||||||
|
String owner = (String) nodeService.getProperty(lockNode, ContentModel.PROP_LOCK_OWNER);
|
||||||
|
Date expiryDate = (Date) nodeService.getProperty(lockNode, ContentModel.PROP_EXPIRY_DATE);
|
||||||
|
|
||||||
|
// Output the XML response
|
||||||
|
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_LOCK_DISCOVERY, WebDAV.XML_LOCK_DISCOVERY, nullAttr);
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_ACTIVE_LOCK, WebDAV.XML_ACTIVE_LOCK, nullAttr);
|
||||||
|
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_LOCK_TYPE, nullAttr);
|
||||||
|
xml.write(DocumentHelper.createElement(WebDAV.XML_WRITE));
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_LOCK_TYPE);
|
||||||
|
|
||||||
|
// NOTE: We only do exclusive lock tokens at the moment
|
||||||
|
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_LOCK_SCOPE, nullAttr);
|
||||||
|
xml.write(DocumentHelper.createElement(WebDAV.XML_EXCLUSIVE));
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_LOCK_SCOPE);
|
||||||
|
|
||||||
|
// NOTE: We only support one level of lock at the moment
|
||||||
|
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_DEPTH, WebDAV.XML_DEPTH, nullAttr);
|
||||||
|
xml.write(WebDAV.ZERO);
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_DEPTH, WebDAV.XML_DEPTH);
|
||||||
|
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_OWNER, WebDAV.XML_OWNER, nullAttr);
|
||||||
|
xml.write(owner);
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_OWNER, WebDAV.XML_OWNER);
|
||||||
|
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_TIMEOUT, WebDAV.XML_TIMEOUT, nullAttr);
|
||||||
|
|
||||||
|
// Output the expiry time
|
||||||
|
|
||||||
|
String strTimeout = WebDAV.INFINITE;
|
||||||
|
if (expiryDate != null)
|
||||||
|
{
|
||||||
|
long timeoutRemaining = (expiryDate.getTime() - System.currentTimeMillis())/1000L;
|
||||||
|
|
||||||
|
strTimeout = WebDAV.SECOND + timeoutRemaining;
|
||||||
|
}
|
||||||
|
xml.write(strTimeout);
|
||||||
|
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_TIMEOUT, WebDAV.XML_TIMEOUT);
|
||||||
|
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_LOCK_TOKEN, WebDAV.XML_LOCK_TOKEN, nullAttr);
|
||||||
|
xml.startElement(EMPTY_NS, WebDAV.XML_HREF, WebDAV.XML_HREF, nullAttr);
|
||||||
|
|
||||||
|
xml.write(WebDAV.makeLockToken(lockNode, owner));
|
||||||
|
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_HREF, WebDAV.XML_HREF);
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_LOCK_TOKEN, WebDAV.XML_LOCK_TOKEN);
|
||||||
|
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_ACTIVE_LOCK, WebDAV.XML_ACTIVE_LOCK);
|
||||||
|
xml.endElement(EMPTY_NS, WebDAV.XML_LOCK_DISCOVERY, WebDAV.XML_LOCK_DISCOVERY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a list of namespace declarations for the response
|
||||||
|
*/
|
||||||
|
protected String generateNamespaceDeclarations(HashMap<String,String> nameSpaces)
|
||||||
|
{
|
||||||
|
StringBuilder ns = new StringBuilder();
|
||||||
|
|
||||||
|
ns.append(" ");
|
||||||
|
ns.append(WebDAV.XML_NS);
|
||||||
|
ns.append("=\"");
|
||||||
|
ns.append(WebDAV.DEFAULT_NAMESPACE_URI);
|
||||||
|
ns.append("\"");
|
||||||
|
|
||||||
|
// Add additional namespaces
|
||||||
|
|
||||||
|
if ( nameSpaces != null)
|
||||||
|
{
|
||||||
|
Iterator<String> namespaceList = nameSpaces.keySet().iterator();
|
||||||
|
|
||||||
|
while (namespaceList.hasNext())
|
||||||
|
{
|
||||||
|
String strNamespaceUri = namespaceList.next();
|
||||||
|
String strNamespaceName = nameSpaces.get(strNamespaceUri);
|
||||||
|
|
||||||
|
ns.append(" ").append(WebDAV.XML_NS).append(":").append(strNamespaceName).append("=\"");
|
||||||
|
ns.append(strNamespaceUri).append("\" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ns.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -348,7 +348,7 @@ public class PropFindMethod extends WebDAVMethod
|
|||||||
/**
|
/**
|
||||||
* Creates a WebDAVProperty from the given XML node
|
* Creates a WebDAVProperty from the given XML node
|
||||||
*/
|
*/
|
||||||
private WebDAVProperty createProperty(Node node)
|
protected WebDAVProperty createProperty(Node node)
|
||||||
{
|
{
|
||||||
WebDAVProperty property = null;
|
WebDAVProperty property = null;
|
||||||
|
|
||||||
|
396
source/java/org/alfresco/repo/webdav/PropPatchMethod.java
Executable file
396
source/java/org/alfresco/repo/webdav/PropPatchMethod.java
Executable file
@@ -0,0 +1,396 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.webdav;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
|
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.dom4j.DocumentHelper;
|
||||||
|
import org.dom4j.io.XMLWriter;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the WebDAV PROPPATCH method
|
||||||
|
*
|
||||||
|
* @author Ivan Rybnikov
|
||||||
|
*/
|
||||||
|
public class PropPatchMethod extends PropFindMethod
|
||||||
|
{
|
||||||
|
|
||||||
|
// Properties to patch
|
||||||
|
protected ArrayList<PropertyAction> m_propertyActions = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeImpl() throws WebDAVServerException, Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
m_response.setStatus(WebDAV.WEBDAV_SC_MULTI_STATUS);
|
||||||
|
|
||||||
|
FileInfo pathNodeInfo = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check that the path exists
|
||||||
|
pathNodeInfo = getDAVHelper().getNodeForPath(getRootNodeRef(), m_strPath, m_request.getServletPath());
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e)
|
||||||
|
{
|
||||||
|
// The path is not valid - send a 404 error back to the client
|
||||||
|
throw new WebDAVServerException(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the response content type
|
||||||
|
m_response.setContentType(WebDAV.XML_CONTENT_TYPE);
|
||||||
|
|
||||||
|
// Create multistatus response
|
||||||
|
XMLWriter xml = createXMLWriter();
|
||||||
|
|
||||||
|
xml.startDocument();
|
||||||
|
|
||||||
|
String nsdec = generateNamespaceDeclarations(m_namespaces);
|
||||||
|
xml.startElement(
|
||||||
|
WebDAV.DAV_NS,
|
||||||
|
WebDAV.XML_MULTI_STATUS + nsdec,
|
||||||
|
WebDAV.XML_NS_MULTI_STATUS + nsdec,
|
||||||
|
getDAVHelper().getNullAttributes());
|
||||||
|
|
||||||
|
// Create the path for the current location in the tree
|
||||||
|
StringBuilder baseBuild = new StringBuilder(256);
|
||||||
|
baseBuild.append(getPath());
|
||||||
|
if (baseBuild.length() == 0 || baseBuild.charAt(baseBuild.length() - 1) != WebDAVHelper.PathSeperatorChar)
|
||||||
|
{
|
||||||
|
baseBuild.append(WebDAVHelper.PathSeperatorChar);
|
||||||
|
}
|
||||||
|
String basePath = baseBuild.toString();
|
||||||
|
|
||||||
|
// Output the response for the root node, depth zero
|
||||||
|
generateResponse(xml, pathNodeInfo, basePath);
|
||||||
|
|
||||||
|
// Close the outer XML element
|
||||||
|
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_MULTI_STATUS, WebDAV.XML_NS_MULTI_STATUS);
|
||||||
|
|
||||||
|
// Send remaining data
|
||||||
|
xml.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the request body
|
||||||
|
*
|
||||||
|
* @exception WebDAVServerException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void parseRequestBody() throws WebDAVServerException
|
||||||
|
{
|
||||||
|
Document body = getRequestBodyAsDocument();
|
||||||
|
if (body != null)
|
||||||
|
{
|
||||||
|
Element rootElement = body.getDocumentElement();
|
||||||
|
NodeList childList = rootElement.getChildNodes();
|
||||||
|
|
||||||
|
m_propertyActions = new ArrayList<PropertyAction>();
|
||||||
|
|
||||||
|
for (int i = 0; i < childList.getLength(); i++)
|
||||||
|
{
|
||||||
|
Node currentNode = childList.item(i);
|
||||||
|
switch (currentNode.getNodeType())
|
||||||
|
{
|
||||||
|
case Node.TEXT_NODE:
|
||||||
|
break;
|
||||||
|
case Node.ELEMENT_NODE:
|
||||||
|
if (currentNode.getNodeName().endsWith(WebDAV.XML_SET) || currentNode.getNodeName().endsWith(WebDAV.XML_REMOVE))
|
||||||
|
{
|
||||||
|
NodeList propertiesList = currentNode.getChildNodes();
|
||||||
|
|
||||||
|
for (int j = 0; j < propertiesList.getLength(); j++)
|
||||||
|
{
|
||||||
|
Node propertiesNode = propertiesList.item(j);
|
||||||
|
switch (propertiesNode.getNodeType())
|
||||||
|
{
|
||||||
|
case Node.TEXT_NODE:
|
||||||
|
break;
|
||||||
|
case Node.ELEMENT_NODE:
|
||||||
|
if (propertiesNode.getNodeName().endsWith(WebDAV.XML_PROP))
|
||||||
|
{
|
||||||
|
NodeList propList = propertiesNode.getChildNodes();
|
||||||
|
|
||||||
|
for (int k = 0; k < propList.getLength(); k++)
|
||||||
|
{
|
||||||
|
Node propNode = propList.item(k);
|
||||||
|
switch (propNode.getNodeType())
|
||||||
|
{
|
||||||
|
case Node.TEXT_NODE:
|
||||||
|
break;
|
||||||
|
case Node.ELEMENT_NODE:
|
||||||
|
int action = currentNode.getNodeName().endsWith(WebDAV.XML_SET) ? PropertyAction.SET : PropertyAction.REMOVE;
|
||||||
|
m_propertyActions.add(new PropertyAction(action, createProperty(propNode)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the request headers
|
||||||
|
*
|
||||||
|
* @exception WebDAVServerException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void parseRequestHeaders() throws WebDAVServerException
|
||||||
|
{
|
||||||
|
// Nothing to do in this method
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a WebDAVProperty from the given XML node
|
||||||
|
*/
|
||||||
|
protected WebDAVProperty createProperty(Node node)
|
||||||
|
{
|
||||||
|
WebDAVProperty property = super.createProperty(node);
|
||||||
|
|
||||||
|
String strValue = null;
|
||||||
|
Node value = node.getFirstChild();
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
strValue = value.getNodeValue();
|
||||||
|
}
|
||||||
|
property.setValue(strValue);
|
||||||
|
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the required response XML
|
||||||
|
*
|
||||||
|
* @param xml XMLWriter
|
||||||
|
* @param node NodeRef
|
||||||
|
* @param path String
|
||||||
|
*/
|
||||||
|
protected void generateResponse(XMLWriter xml, FileInfo nodeInfo, String path) throws Exception
|
||||||
|
{
|
||||||
|
boolean isFolder = nodeInfo.isFolder();
|
||||||
|
|
||||||
|
// Output the response block for the current node
|
||||||
|
xml.startElement(
|
||||||
|
WebDAV.DAV_NS,
|
||||||
|
WebDAV.XML_RESPONSE,
|
||||||
|
WebDAV.XML_NS_RESPONSE,
|
||||||
|
getDAVHelper().getNullAttributes());
|
||||||
|
|
||||||
|
// Build the href string for the current node
|
||||||
|
String strHRef = WebDAV.getURLForPath(m_request, path, isFolder);
|
||||||
|
|
||||||
|
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_HREF, WebDAV.XML_NS_HREF, getDAVHelper().getNullAttributes());
|
||||||
|
xml.write(strHRef);
|
||||||
|
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_HREF, WebDAV.XML_NS_HREF);
|
||||||
|
|
||||||
|
|
||||||
|
boolean failed = false;
|
||||||
|
WebDAVProperty failedProperty = null;
|
||||||
|
for (PropertyAction action : m_propertyActions)
|
||||||
|
{
|
||||||
|
if (action.getProperty().isProtected())
|
||||||
|
{
|
||||||
|
generateError(xml);
|
||||||
|
failed = true;
|
||||||
|
failedProperty = action.getProperty();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PropertyAction propertyAction : m_propertyActions)
|
||||||
|
{
|
||||||
|
int statusCode;
|
||||||
|
String statusCodeDescription;
|
||||||
|
WebDAVProperty property = propertyAction.getProperty();
|
||||||
|
|
||||||
|
if (!failed)
|
||||||
|
{
|
||||||
|
if (PropertyAction.SET == propertyAction.getAction())
|
||||||
|
{
|
||||||
|
getNodeService().setProperty(nodeInfo.getNodeRef(), property.createQName(), property.getValue());
|
||||||
|
}
|
||||||
|
else if (PropertyAction.REMOVE == propertyAction.getAction())
|
||||||
|
{
|
||||||
|
getNodeService().removeProperty(nodeInfo.getNodeRef(), property.createQName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new WebDAVServerException(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
|
}
|
||||||
|
statusCode = HttpServletResponse.SC_OK;
|
||||||
|
statusCodeDescription = WebDAV.SC_OK_DESC;
|
||||||
|
}
|
||||||
|
else if (failedProperty == property)
|
||||||
|
{
|
||||||
|
statusCode = HttpServletResponse.SC_FORBIDDEN;
|
||||||
|
statusCodeDescription = WebDAV.SC_FORBIDDEN_DESC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statusCode = WebDAV.WEBDAV_SC_FAILED_DEPENDENCY;
|
||||||
|
statusCodeDescription = WebDAV.WEBDAV_SC_FAILED_DEPENDENCY_DESC;
|
||||||
|
}
|
||||||
|
|
||||||
|
generatePropertyResponse(xml, property, statusCode, statusCodeDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close off the response element
|
||||||
|
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_RESPONSE, WebDAV.XML_NS_RESPONSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the XML response for a PROPFIND request that asks for a list of
|
||||||
|
* all known properties
|
||||||
|
*
|
||||||
|
* @param xml XMLWriter
|
||||||
|
* @param node NodeRef
|
||||||
|
* @param isDir boolean
|
||||||
|
*/
|
||||||
|
protected void generatePropertyResponse(XMLWriter xml, WebDAVProperty property, int status, String description)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Output the start of the properties element
|
||||||
|
Attributes nullAttr = getDAVHelper().getNullAttributes();
|
||||||
|
|
||||||
|
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT, nullAttr);
|
||||||
|
|
||||||
|
// Output property name
|
||||||
|
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP, nullAttr);
|
||||||
|
if (property.hasNamespaceName())
|
||||||
|
{
|
||||||
|
xml.write(DocumentHelper.createElement(property.getNamespaceName() + WebDAV.NAMESPACE_SEPARATOR + property.getName()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xml.write(DocumentHelper.createElement(property.getName()));
|
||||||
|
}
|
||||||
|
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP);
|
||||||
|
|
||||||
|
// Output action result status
|
||||||
|
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS, nullAttr);
|
||||||
|
xml.write(WebDAV.HTTP1_1 + " " + status + " " + description);
|
||||||
|
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS);
|
||||||
|
|
||||||
|
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Convert to a runtime exception
|
||||||
|
throw new AlfrescoRuntimeException("XML processing error", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the error tag
|
||||||
|
*
|
||||||
|
* @param xml XMLWriter
|
||||||
|
*/
|
||||||
|
protected void generateError(XMLWriter xml)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Output the start of the error element
|
||||||
|
Attributes nullAttr = getDAVHelper().getNullAttributes();
|
||||||
|
|
||||||
|
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_ERROR, WebDAV.XML_NS_ERROR, nullAttr);
|
||||||
|
// Output error
|
||||||
|
xml.write(DocumentHelper.createElement(WebDAV.XML_NS_CANNOT_MODIFY_PROTECTED_PROPERTY));
|
||||||
|
|
||||||
|
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_ERROR, WebDAV.XML_NS_ERROR);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Convert to a runtime exception
|
||||||
|
throw new AlfrescoRuntimeException("XML processing error", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class PropertyAction
|
||||||
|
{
|
||||||
|
protected static final int SET = 0;
|
||||||
|
protected static final int REMOVE = 1;
|
||||||
|
|
||||||
|
private WebDAVProperty property;
|
||||||
|
private int action;
|
||||||
|
|
||||||
|
public PropertyAction(int action, WebDAVProperty property)
|
||||||
|
{
|
||||||
|
this.action = action;
|
||||||
|
this.property = property;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAction()
|
||||||
|
{
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WebDAVProperty getProperty()
|
||||||
|
{
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
|
||||||
|
str.append("[");
|
||||||
|
str.append("action=");
|
||||||
|
str.append(getAction() == 0 ? "SET" : "REMOVE");
|
||||||
|
str.append(",property=");
|
||||||
|
str.append(getProperty());
|
||||||
|
str.append("]");
|
||||||
|
|
||||||
|
return str.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -71,11 +71,17 @@ public class WebDAV
|
|||||||
|
|
||||||
public static final int WEBDAV_SC_MULTI_STATUS = 207;
|
public static final int WEBDAV_SC_MULTI_STATUS = 207;
|
||||||
public static final int WEBDAV_SC_LOCKED = 423;
|
public static final int WEBDAV_SC_LOCKED = 423;
|
||||||
|
public static final int WEBDAV_SC_FAILED_DEPENDENCY = 424;
|
||||||
|
|
||||||
|
// WebDAV HTTP response code descriptions
|
||||||
|
|
||||||
|
public static final String WEBDAV_SC_FAILED_DEPENDENCY_DESC = "Failed Dependency";
|
||||||
|
|
||||||
// HTTP response code descriptions
|
// HTTP response code descriptions
|
||||||
|
|
||||||
public static final String SC_OK_DESC = "OK";
|
public static final String SC_OK_DESC = "OK";
|
||||||
public static final String SC_NOT_FOUND_DESC = "Not Found";
|
public static final String SC_NOT_FOUND_DESC = "Not Found";
|
||||||
|
public static final String SC_FORBIDDEN_DESC = "Forbidden";
|
||||||
|
|
||||||
// HTTP methods
|
// HTTP methods
|
||||||
|
|
||||||
@@ -169,6 +175,9 @@ public class WebDAV
|
|||||||
public static final String XML_SUPPORTED_LOCK = "supportedlock";
|
public static final String XML_SUPPORTED_LOCK = "supportedlock";
|
||||||
public static final String XML_TIMEOUT = "timeout";
|
public static final String XML_TIMEOUT = "timeout";
|
||||||
public static final String XML_WRITE = "write";
|
public static final String XML_WRITE = "write";
|
||||||
|
public static final String XML_SET = "set";
|
||||||
|
public static final String XML_REMOVE = "remove";
|
||||||
|
public static final String XML_ERROR = "error";
|
||||||
|
|
||||||
// Namespaced versions of payload elements
|
// Namespaced versions of payload elements
|
||||||
|
|
||||||
@@ -202,6 +211,8 @@ public class WebDAV
|
|||||||
public static final String XML_NS_SUPPORTED_LOCK = DAV_NS_PREFIX + "supportedlock";
|
public static final String XML_NS_SUPPORTED_LOCK = DAV_NS_PREFIX + "supportedlock";
|
||||||
public static final String XML_NS_TIMEOUT = DAV_NS_PREFIX + "timeout";
|
public static final String XML_NS_TIMEOUT = DAV_NS_PREFIX + "timeout";
|
||||||
public static final String XML_NS_WRITE = DAV_NS_PREFIX + "write";
|
public static final String XML_NS_WRITE = DAV_NS_PREFIX + "write";
|
||||||
|
public static final String XML_NS_ERROR = DAV_NS_PREFIX + "error";
|
||||||
|
public static final String XML_NS_CANNOT_MODIFY_PROTECTED_PROPERTY = DAV_NS_PREFIX + "cannot-modify-protected-property";
|
||||||
|
|
||||||
public static final String XML_CONTENT_TYPE = "text/xml; charset=UTF-8";
|
public static final String XML_CONTENT_TYPE = "text/xml; charset=UTF-8";
|
||||||
|
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.webdav;
|
package org.alfresco.repo.webdav;
|
||||||
|
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to represent a WebDAV property
|
* Class to represent a WebDAV property
|
||||||
*
|
*
|
||||||
@@ -136,6 +138,31 @@ public class WebDAVProperty
|
|||||||
m_strValue = strValue;
|
m_strValue = strValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates QName of the property
|
||||||
|
*
|
||||||
|
* @return QName
|
||||||
|
*/
|
||||||
|
public QName createQName()
|
||||||
|
{
|
||||||
|
return QName.createQName(m_strNamespaceUri, m_strName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if property is protected according to the WebDav specification
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean isProtected()
|
||||||
|
{
|
||||||
|
return WebDAV.XML_GET_CONTENT_LENGTH.equals(m_strName) ||
|
||||||
|
WebDAV.XML_GET_ETAG.equals(m_strName) ||
|
||||||
|
WebDAV.XML_GET_LAST_MODIFIED.equals(m_strName) ||
|
||||||
|
WebDAV.XML_LOCK_DISCOVERY.equals(m_strName) ||
|
||||||
|
WebDAV.XML_RESOURCE_TYPE.equals(m_strName) ||
|
||||||
|
WebDAV.XML_SUPPORTED_LOCK.equals(m_strName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the property as a string
|
* Return the property as a string
|
||||||
*
|
*
|
||||||
|
@@ -304,6 +304,7 @@ public class WebDAVServlet extends HttpServlet
|
|||||||
m_davMethods = new Hashtable<String,Class>();
|
m_davMethods = new Hashtable<String,Class>();
|
||||||
|
|
||||||
m_davMethods.put(WebDAV.METHOD_PROPFIND, PropFindMethod.class);
|
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_COPY, CopyMethod.class);
|
||||||
m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class);
|
m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class);
|
||||||
m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class);
|
m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class);
|
||||||
|
Reference in New Issue
Block a user