/*
* ====================================================================
* 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.io.IOException;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
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.dav.http.HTTPHeader;
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.DAVRepositoryManager;
import org.tmatesoft.svn.core.internal.server.dav.DAVResource;
import org.tmatesoft.svn.core.internal.server.dav.DAVResourceState;
import org.tmatesoft.svn.core.internal.server.dav.DAVXMLUtil;
import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
import org.tmatesoft.svn.core.internal.util.SVNXMLUtil;
/**
* @version 1.3
* @author TMate Software Ltd.
*/
public class DAVLockHandler extends ServletDAVHandler {
private DAVLockRequest myLockRequest;
protected DAVLockHandler(DAVRepositoryManager repositoryManager, HttpServletRequest request, HttpServletResponse response) {
super(repositoryManager, request, response);
}
public void execute() throws SVNException {
long readLength = readInput(false);
DAVDepth depth = null;
try {
depth = getRequestDepth(DAVDepth.DEPTH_INFINITY);
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_BAD_REQUEST, null, null);
}
if (depth != DAVDepth.DEPTH_ZERO && depth != DAVDepth.DEPTH_INFINITY) {
sendError(HttpServletResponse.SC_BAD_REQUEST, "Depth must be 0 or \"infinity\" for LOCK.");
return;
}
DAVLockInfoProvider lockProvider = null;
DAVResource resource = getRequestedDAVResource(false, false);
try {
lockProvider = DAVLockInfoProvider.createLockInfoProvider(this, false);
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, null);
}
boolean isNewLockRequest = false;
DAVLock lock = null;
if (readLength > 0) {
lock = getLockRequest().parseLockInfo(this, resource, getNamespaces());
isNewLockRequest = true;
}
DAVResourceState resourceState = getResourceState(resource);
try {
int flags = resourceState == DAVResourceState.NULL ? DAV_VALIDATE_PARENT : DAV_VALIDATE_RESOURCE;
flags |= DAV_VALIDATE_ADD_LD;
validateRequest(resource, depth, flags, isNewLockRequest ? lock.getScope() : null, null, lockProvider);
} catch (DAVException dave) {
DAVException next = new DAVException("Could not LOCK {0} due to a failed precondition (e.g. other locks).",
new Object[] { SVNEncodingUtil.xmlEncodeCDATA(resource.getResourceURI().getRequestURI(), true) }, dave.getResponseCode(), dave, 0);
throw next;
}
if (!isNewLockRequest) {
List lockTokens = null;
try {
lockTokens = getLockTokensList();
} catch (DAVException dave) {
DAVException next = new DAVException("The lock refresh for {0} failed because no lock tokens were specified in an \"If:\" header.",
new Object[] { SVNEncodingUtil.xmlEncodeCDATA(resource.getResourceURI().getRequestURI(), true) }, dave.getResponseCode(), dave, 0);
throw next;
}
String lockToken = (String) lockTokens.get(0);
lock = lockProvider.refreshLock(resource, lockToken, getTimeout());
} else {
if (lock.getTimeOutDate() != null) {
//TODO: add expiration date renewal
//Date timeoutDate = lock.getTimeOutDate();
}
lockProvider.addLock(lock, resource);
setResponseHeader(HTTPHeader.LOCK_TOKEN_HEADER, "<" + lock.getLockToken() + ">");
}
HttpServletResponse servletResponse = getHttpServletResponse();
servletResponse.setContentType(DEFAULT_XML_CONTENT_TYPE);
servletResponse.setStatus(HttpServletResponse.SC_OK);
try {
StringBuffer xmlBuffer = SVNXMLUtil.addXMLHeader(null);
DAVXMLUtil.openNamespaceDeclarationTag(SVNXMLUtil.DAV_NAMESPACE_PREFIX, DAVElement.PROP.getName(), null, null, xmlBuffer, true, false);
if (lock == null) {
SVNXMLUtil.openXMLTag(SVNXMLUtil.DAV_NAMESPACE_PREFIX, DAVElement.LOCK_DISCOVERY.getName(), SVNXMLUtil.XML_STYLE_SELF_CLOSING, null, xmlBuffer);
} else {
SVNXMLUtil.openXMLTag(SVNXMLUtil.DAV_NAMESPACE_PREFIX, DAVElement.LOCK_DISCOVERY.getName(), SVNXMLUtil.XML_STYLE_PROTECT_CDATA, null, xmlBuffer);
xmlBuffer.append(DAVLockInfoProvider.getActiveLockXML(lock));
xmlBuffer.append('\n');
SVNXMLUtil.closeXMLTag(SVNXMLUtil.DAV_NAMESPACE_PREFIX, DAVElement.LOCK_DISCOVERY.getName(), xmlBuffer);
}
SVNXMLUtil.closeXMLTag(SVNXMLUtil.DAV_NAMESPACE_PREFIX, DAVElement.PROP.getName(), xmlBuffer);
getResponseWriter().write(xmlBuffer.toString());
} catch (IOException e) {
throw new DAVException(e.getMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 0);
}
}
protected DAVRequest getDAVRequest() {
return getLockRequest();
}
private DAVLockRequest getLockRequest() {
if (myLockRequest == null) {
myLockRequest = new DAVLockRequest();
}
return myLockRequest;
}
}