/* * ==================================================================== * Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://svnkit.com/license.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * ==================================================================== */ package org.tmatesoft.svn.core.internal.server.dav.handlers; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Level; import javax.servlet.http.HttpServletResponse; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.internal.io.dav.DAVElement; import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryUtil; import org.tmatesoft.svn.core.internal.server.dav.DAVDepth; import org.tmatesoft.svn.core.internal.server.dav.DAVException; import org.tmatesoft.svn.core.internal.server.dav.DAVLock; import org.tmatesoft.svn.core.internal.server.dav.DAVLockRecType; import org.tmatesoft.svn.core.internal.server.dav.DAVLockScope; import org.tmatesoft.svn.core.internal.server.dav.DAVLockType; import org.tmatesoft.svn.core.internal.server.dav.DAVResource; import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil; import org.tmatesoft.svn.core.internal.util.SVNXMLUtil; import org.tmatesoft.svn.util.SVNLogType; /** * @version 1.3 * @author TMate Software Ltd. */ public class DAVLockRequest extends DAVRequest { private static final DAVElement LOCK_INFO = DAVElement.getElement(DAVElement.DAV_NAMESPACE, "lockinfo"); public DAVLock parseLockInfo(DAVLockHandler handler, DAVResource resource, List namespaces) throws DAVException { DAVDepth depth = null; try { depth = handler.getRequestDepth(DAVDepth.DEPTH_INFINITY); } catch (SVNException svne) { throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_BAD_REQUEST, null, null); } if (depth != DAVDepth.DEPTH_ONE && depth != DAVDepth.DEPTH_ZERO) { throw new DAVException("An invalid Depth header was specified.", HttpServletResponse.SC_BAD_REQUEST, 0); } Date timeout = handler.getTimeout(); String lockToken = null; try { lockToken = FSRepositoryUtil.generateLockToken(); } catch (SVNException e) { DAVException first = DAVException.convertError(e.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to generate a lock token.", null); DAVException next = new DAVException("Could not parse the lockinfo due to an internal problem creating a lock structure.", first.getResponseCode(), first, 0); throw next; } DAVElementProperty rootElement = null; try { rootElement = getRoot(); } catch (SVNException e) { throw DAVException.convertError(e.getErrorMessage(), HttpServletResponse.SC_BAD_REQUEST, "Could not parse the lockinfo, malformed xml request", null); } String owner = null; DAVLockScope lockScope = DAVLockScope.UNKNOWN; DAVLockType lockType = DAVLockType.UNKNOWN; for (Iterator childrenIter = rootElement.getChildren().iterator(); childrenIter.hasNext();) { DAVElementProperty childElement = (DAVElementProperty) childrenIter.next(); DAVElement childElementName = childElement.getName(); if (childElementName == DAVElement.LOCK_TYPE && childElement.getChildren() != null && lockType == DAVLockType.UNKNOWN) { DAVElementProperty writeChild = childElement.getChild(DAVElement.WRITE); if (writeChild != null) { lockType = DAVLockType.WRITE; continue; } } if (childElementName == DAVElement.LOCK_SCOPE && childElement.getChildren() != null && lockScope == DAVLockScope.UNKNOWN) { if (childElement.getChild(DAVElement.EXCLUSIVE) != null) { lockScope = DAVLockScope.EXCLUSIVE; } else if (childElement.getChild(DAVElement.SHARED) != null) { lockScope = DAVLockScope.SHARED; } if (lockScope != DAVLockScope.UNKNOWN) { continue; } } if (childElementName == DAVElement.LOCK_OWNER) { //TODO: maybe make this recursive for all possible subelements StringBuffer buffer = new StringBuffer(); String namespace = childElementName.getNamespace(); buffer.append("<"); if (namespace == null || "".equals(namespace)) { buffer.append(childElementName.getName()); } else { buffer.append(SVNXMLUtil.PREFIX_MAP.get(namespace)); buffer.append(":"); buffer.append(childElementName.getName()); } Map attributes = childElement.getAttributes(); if (attributes != null) { for (Iterator attrsIter = attributes.keySet().iterator(); attrsIter.hasNext();) { String attrName = (String) attrsIter.next(); String attrValue = (String) attributes.get(attrName); buffer.append(" "); buffer.append(attrName); buffer.append("=\""); buffer.append(attrValue); buffer.append("\""); } } for (Iterator namespacesIter = namespaces.iterator(); namespacesIter.hasNext();) { String nextNamespace = (String) namespacesIter.next(); buffer.append(" xmlns:"); buffer.append(SVNXMLUtil.PREFIX_MAP.get(nextNamespace)); buffer.append("=\""); buffer.append(nextNamespace); buffer.append("\""); } if (childElement.isEmpty()) { buffer.append(" />"); } else { buffer.append(">"); buffer.append(SVNEncodingUtil.xmlEncodeCDATA(childElement.getFirstValue(false), false)); buffer.append("</"); if (namespace == null || "".equals(namespace)) { buffer.append(childElementName.getName()); } else { buffer.append(SVNXMLUtil.PREFIX_MAP.get(namespace)); buffer.append(":"); buffer.append(childElementName.getName()); } buffer.append(">"); } owner = buffer.toString(); continue; } throw new DAVException("The server cannot satisfy the LOCK request due to an unknown XML element (\"{0}\") within the DAV:lockinfo element.", new Object[] { childElementName.getName() }, HttpServletResponse.SC_PRECONDITION_FAILED, 0); } return new DAVLock(resource.getUserName(), depth, resource.exists(), lockToken, owner, DAVLockRecType.DIRECT, lockScope, lockType, timeout); } protected void init() throws SVNException { if (getRoot().getName() != LOCK_INFO) { invalidXMLRoot(); } } protected DAVElementProperty getRoot() throws SVNException { if (getRootElement() == null) { invalidXMLRoot(); } return getRootElement(); } protected void invalidXMLRoot() throws SVNException { throw new DAVException("The request body contains an unexpected XML root element.", null, HttpServletResponse.SC_BAD_REQUEST, null, SVNLogType.NETWORK, Level.FINE, null, null, null, 0, null); } }