/*
* ====================================================================
* Copyright (c) 2004-2008 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;
import java.util.logging.Level;
import javax.servlet.http.HttpServletResponse;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNRevisionProperty;
import org.tmatesoft.svn.core.internal.io.fs.FSFS;
import org.tmatesoft.svn.core.internal.io.fs.FSRoot;
import org.tmatesoft.svn.core.internal.io.fs.FSTransactionInfo;
import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
import org.tmatesoft.svn.util.SVNLogType;
/**
* @version 1.2.0
* @author TMate Software Ltd.
*/
public class DAVWorkingResourceHelper extends DAVResourceHelper {
protected void prepare(DAVResource resource) throws DAVException {
String txnName = DAVServletUtil.getTxn(resource.getActivitiesDB(), resource.getResourceURI().getActivityID());
if (txnName == null) {
throw new DAVException("An unknown activity was specified in the URL. This is generally caused by a problem in the client software.",
null, HttpServletResponse.SC_BAD_REQUEST, null, SVNLogType.NETWORK, Level.FINE, null, null, null, 0, null);
}
resource.setTxnName(txnName);
FSFS fsfs = resource.getFSFS();
FSTransactionInfo txnInfo = null;
try {
txnInfo = fsfs.openTxn(txnName);
} catch (SVNException svne) {
if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.FS_NO_SUCH_TRANSACTION) {
throw new DAVException("An activity was specified and found, but the corresponding SVN FS transaction was not found.",
null, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, SVNLogType.NETWORK, Level.FINE, null, null, null, 0, null);
}
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"An activity was specified and found, but the corresponding SVN FS transaction was not found.", null);
}
resource.setTxnInfo(txnInfo);
if (resource.isBaseLined()) {
resource.setExists(true);
return;
}
String userName = resource.getUserName();
if (resource.getUserName() != null) {
SVNProperties props = null;
try {
props = fsfs.getTransactionProperties(txnName);
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Failed to retrieve author of the SVN FS transaction corresponding to the specified activity.", null);
}
String currentAuthor = props.getStringValue(SVNRevisionProperty.AUTHOR);
if (currentAuthor == null) {
try {
fsfs.setTransactionProperty(txnName, SVNRevisionProperty.AUTHOR, SVNPropertyValue.create(userName));
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Failed to set the author of the SVN FS transaction corresponding to the specified activity.", null);
}
} else if (!currentAuthor.equals(userName)) {
throw new DAVException("Multi-author commits not supported.", null, HttpServletResponse.SC_NOT_IMPLEMENTED, null,
SVNLogType.NETWORK, Level.FINE, null, null, null, 0, null);
}
}
FSRoot root = null;
try {
root = fsfs.createTransactionRoot(txnInfo);
resource.setRoot(root);
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Could not open the (transaction) root of the repository", null);
}
SVNNodeKind kind = DAVServletUtil.checkPath(root, resource.getResourceURI().getPath());
resource.setExists(kind != SVNNodeKind.NONE);
resource.setCollection(kind == SVNNodeKind.DIR);
}
protected DAVResource getParentResource(DAVResource resource) throws DAVException {
return DAVPrivateResourceHelper.createPrivateResource(resource, DAVResourceKind.WORKING);
}
public static DAVResource createWorkingResource(DAVResource baseResource, String activityID, String txnName, boolean inPlace) {
StringBuffer pathBuffer = new StringBuffer();
if (baseResource.isBaseLined()) {
pathBuffer.append('/');
pathBuffer.append(DAVResourceURI.SPECIAL_URI);
pathBuffer.append("/wbl/");
pathBuffer.append(activityID);
pathBuffer.append('/');
pathBuffer.append(baseResource.getRevision());
} else {
pathBuffer.append('/');
pathBuffer.append(DAVResourceURI.SPECIAL_URI);
pathBuffer.append("/wrk/");
pathBuffer.append(activityID);
pathBuffer.append(baseResource.getResourceURI().getPath());
}
String uriPath = SVNEncodingUtil.uriEncode(pathBuffer.toString());
DAVResource resource = null;
if (inPlace) {
resource = baseResource;
} else {
resource = new DAVResource();
baseResource.copyTo(resource);
}
resource.setTxnName(txnName);
resource.setExists(true);
resource.setVersioned(true);
resource.setWorking(true);
DAVResourceURI uri = resource.getResourceURI();
uri.setType(DAVResourceType.WORKING);
uri.setURI(uriPath);
uri.setActivityID(activityID);
return resource;
}
}