super(connector, request, response);
myIsMove = isMove;
}
public void execute() throws SVNException {
DAVResource resource = getRequestedDAVResource(!myIsMove, false);
if (!resource.exists()) {
sendError(HttpServletResponse.SC_NOT_FOUND, null);
return;
}
if (resource.getType() != DAVResourceType.REGULAR) {
String body = "Cannot COPY/MOVE resource " + SVNEncodingUtil.xmlEncodeCDATA(getURI()) + ".";
response(body, DAVServlet.getStatusLine(HttpServletResponse.SC_METHOD_NOT_ALLOWED), HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
String destination = getRequestHeader(HTTPHeader.DESTINATION_HEADER);
if (destination == null) {
String netScapeHost = getRequestHeader(HTTPHeader.HOST_HEADER);
String netScapeNewURI = getRequestHeader(HTTPHeader.NEW_URI_HEADER);
if (netScapeHost != null && netScapeNewURI != null) {
String path = SVNPathUtil.append(netScapeHost, netScapeNewURI);
if (path.startsWith("/")) {
path = path.substring(1);
}
destination = "http://" + path;
}
}
if (destination == null) {
SVNDebugLog.getDefaultLog().logFine(SVNLogType.NETWORK, "The request is missing a Destination header.");
sendError(HttpServletResponse.SC_BAD_REQUEST, null);
return;
}
URI uri = null;
try {
uri = DAVServletUtil.lookUpURI(destination, getRequest(), true);
} catch (DAVException dave) {
if (dave.getResponseCode() == HttpServletResponse.SC_BAD_REQUEST) {
throw dave;
}
response(dave.getMessage(), DAVServlet.getStatusLine(dave.getResponseCode()), dave.getResponseCode());
}
String path = uri.getPath();
DAVRepositoryManager manager = getRepositoryManager();
String resourceContext = manager.getResourceContext();
if (!path.startsWith(resourceContext)) {
throw new DAVException("Destination url starts with a wrong context", HttpServletResponse.SC_BAD_REQUEST, 0);
}
path = path.substring(resourceContext.length());
DAVResource newResource = getRequestedDAVResource(false, false, path);
int overwrite = getOverwrite();
if (overwrite < 0) {
sendError(HttpServletResponse.SC_BAD_REQUEST, null);
return;
}
if (newResource.exists() && overwrite == 0) {
response("Destination is not empty and Overwrite is not \"T\"", DAVServlet.getStatusLine(HttpServletResponse.SC_PRECONDITION_FAILED),
HttpServletResponse.SC_PRECONDITION_FAILED);
return;
}
if (resource.equals(newResource)) {
response("Source and Destination URIs are the same.", DAVServlet.getStatusLine(HttpServletResponse.SC_FORBIDDEN),
HttpServletResponse.SC_FORBIDDEN);
return;
}
boolean isDir = resource.isCollection();
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_ONE) {
//add logging here later
sendError(HttpServletResponse.SC_BAD_REQUEST, null);
return;
}
if (myIsMove && isDir && depth != DAVDepth.DEPTH_INFINITY) {
//add logging here later
sendError(HttpServletResponse.SC_BAD_REQUEST, null);
return;
}
if (myIsMove) {
try {
validateRequest(resource, depth, DAV_VALIDATE_PARENT | DAV_VALIDATE_USE_424, null, null, null);
} catch (DAVException dave) {
throw new DAVException("Could not MOVE {0} due to a failed precondition on the source (e.g. locks).",
new Object[] { SVNEncodingUtil.xmlEncodeCDATA(getURI()) }, dave.getResponseCode(), null, SVNLogType.NETWORK,
Level.FINE, dave, null, null, 0, dave.getResponse());
}
}
try {
validateRequest(newResource, DAVDepth.DEPTH_INFINITY, DAV_VALIDATE_PARENT | DAV_VALIDATE_USE_424, null, null, null);
} catch (DAVException dave) {
throw new DAVException("Could not MOVE/COPY {0} due to a failed precondition on the destination (e.g. locks).",
new Object[] { SVNEncodingUtil.xmlEncodeCDATA(getURI()) }, dave.getResponseCode(), null, SVNLogType.NETWORK, Level.FINE,
dave, null, null, 0, dave.getResponse());
}
if (isDir && depth == DAVDepth.DEPTH_INFINITY && resource.isParentResource(newResource)) {
response("Source collection contains the Destination.", DAVServlet.getStatusLine(HttpServletResponse.SC_FORBIDDEN), HttpServletResponse.SC_FORBIDDEN);
return;
}
if (isDir && newResource.isParentResource(newResource)) {
response("Destination collection contains the Source and Overwrite has been specified.", DAVServlet.getStatusLine(HttpServletResponse.SC_FORBIDDEN),
HttpServletResponse.SC_FORBIDDEN);
return;
}
readInput(true);
DAVLockInfoProvider lockProvider = null;
try {
lockProvider = DAVLockInfoProvider.createLockInfoProvider(this, false);
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, null);
}
if (myIsMove) {
unlock(resource, null);
}
DAVAutoVersionInfo srcAVInfo = null;
if (myIsMove) {
srcAVInfo = autoCheckOut(resource, true);
}
boolean replaceDestination = false;
DAVResourceState resNewState = getResourceState(newResource);
if (newResource.exists()) {
if (myIsMove || !newResource.isVersioned()) {
replaceDestination = true;
} else if (resource.getType() != newResource.getType()) {
replaceDestination = true;
} else if (resource.isCollection() != newResource.isCollection()) {
replaceDestination = true;
}
}
DAVAutoVersionInfo dstAVInfo = null;
if (!newResource.exists() || replaceDestination) {
try {
dstAVInfo = autoCheckOut(newResource, true);
} catch (DAVException dave) {
if (myIsMove) {
autoCheckIn(null, true, false, srcAVInfo);
}
throw dave;
}
}
if (srcAVInfo != null && srcAVInfo.getParentResource() != null && dstAVInfo != null &&
dstAVInfo.getParentResource() != null) {
DAVResource srcParentResource = srcAVInfo.getParentResource();
DAVResource dstParentResource = dstAVInfo.getParentResource();
if (srcParentResource.equals(dstParentResource)) {
dstAVInfo.setParentResource(srcAVInfo.getParentResource());
}
}