if (resourceType == DAVResourceType.VERSION && resource.isBaseLined()) {
return null;
}
if (resourceType != DAVResourceType.REGULAR) {
throw new DAVException("auto-checkout attempted on non-regular version-controlled resource.", null,
HttpServletResponse.SC_METHOD_NOT_ALLOWED, null, SVNLogType.NETWORK, Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG,
DAVElement.SVN_DAV_ERROR_NAMESPACE, SVNErrorCode.UNSUPPORTED_FEATURE.getCode(), null);
}
if (resource.isBaseLined()) {
new DAVException("auto-checkout attempted on baseline collection, which is not supported.", null,
HttpServletResponse.SC_METHOD_NOT_ALLOWED, null, SVNLogType.NETWORK, Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG,
DAVElement.SVN_DAV_ERROR_NAMESPACE, SVNErrorCode.UNSUPPORTED_FEATURE.getCode(), null);
}
String sharedActivity = DAVServlet.getSharedActivity();
String sharedTxnName = null;
FSTransactionInfo sharedTxnInfo = null;
if (sharedActivity == null) {
try {
sharedActivity = SVNUUIDGenerator.formatUUID(SVNUUIDGenerator.generateUUID());
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"cannot generate UUID for a shared activity", null);
}
sharedTxnInfo = DAVServletUtil.createActivity(resource, fsfs);
sharedTxnName = sharedTxnInfo.getTxnId();
DAVServletUtil.storeActivity(resource, sharedTxnInfo.getTxnId());
DAVServlet.setSharedActivity(sharedActivity);
}
if (sharedTxnName == null) {
sharedTxnName = DAVServletUtil.getTxn(resource.getActivitiesDB(), sharedActivity);
if (sharedTxnName == null) {
throw new DAVException("Cannot look up a txn_name by activity", null, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null,
SVNLogType.NETWORK, Level.FINE, null, null, null, 0, null);
}
}
resource = DAVWorkingResourceHelper.createWorkingResource(resource, sharedActivity, sharedTxnName, true);
resource.setIsAutoCkeckedOut(true);
FSTransactionInfo txnInfo = DAVServletUtil.openTxn(fsfs, resource.getTxnName());
FSTransactionRoot txnRoot = null;
try {
txnRoot = fsfs.createTransactionRoot(txnInfo);
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Could not open a (transaction) root in the repository", null);
}
resource.setTxnInfo(txnInfo);
resource.setRoot(txnRoot);
return null;
}
if (resourceType != DAVResourceType.VERSION) {
throw new DAVException("CHECKOUT can only be performed on a version resource [at this time].", null,
HttpServletResponse.SC_METHOD_NOT_ALLOWED, null, SVNLogType.NETWORK, Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG,
DAVElement.SVN_DAV_ERROR_NAMESPACE, SVNErrorCode.UNSUPPORTED_FEATURE.getCode(), null);
}
if (isCreateActivity) {
throw new DAVException("CHECKOUT can not create an activity at this time. Use MKACTIVITY first.", null,
HttpServletResponse.SC_NOT_IMPLEMENTED, null, SVNLogType.NETWORK, Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG,
DAVElement.SVN_DAV_ERROR_NAMESPACE, SVNErrorCode.UNSUPPORTED_FEATURE.getCode(), null);
}
if (isUnreserved) {
throw new DAVException("Unreserved checkouts are not yet available. A version history may not be checked out more than once, into a specific activity.",
null, HttpServletResponse.SC_NOT_IMPLEMENTED, null, SVNLogType.NETWORK, Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG,
DAVElement.SVN_DAV_ERROR_NAMESPACE, SVNErrorCode.UNSUPPORTED_FEATURE.getCode(), null);
}
if (activities == null) {
throw new DAVException("An activity must be provided for checkout.", null, HttpServletResponse.SC_CONFLICT, null, SVNLogType.NETWORK,
Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG, DAVElement.SVN_DAV_ERROR_NAMESPACE, SVNErrorCode.INCOMPLETE_DATA.getCode(),
null);
}
if (activities.size() != 1) {
throw new DAVException("Only one activity may be specified within the CHECKOUT.", null, HttpServletResponse.SC_CONFLICT, null,
SVNLogType.NETWORK, Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG, DAVElement.SVN_DAV_ERROR_NAMESPACE,
SVNErrorCode.INCORRECT_PARAMS.getCode(), null);
}
DAVURIInfo parse = null;
try {
parse = DAVPathUtil.simpleParseURI((String) activities.get(0), resource);
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_CONFLICT, "The activity href could not be parsed properly.",
null);
}
if (parse.getActivityID() == null) {
throw new DAVException("The provided href is not an activity URI.", null, HttpServletResponse.SC_CONFLICT, null, SVNLogType.NETWORK,
Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG, DAVElement.SVN_DAV_ERROR_NAMESPACE, SVNErrorCode.INCORRECT_PARAMS.getCode(),
null);
}
String txnName = DAVServletUtil.getTxn(resource.getActivitiesDB(), parse.getActivityID());
if (txnName == null) {
throw new DAVException("The specified activity does not exist.", null, HttpServletResponse.SC_CONFLICT, null, SVNLogType.NETWORK,
Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG, DAVElement.SVN_DAV_ERROR_NAMESPACE,
SVNErrorCode.APMOD_ACTIVITY_NOT_FOUND.getCode(), null);
}
if (resource.isBaseLined() || !SVNRevision.isValidRevisionNumber(resource.getRevision())) {
long youngestRevision = -1;
try {
youngestRevision = fsfs.getYoungestRevision();
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Could not determine the youngest revision for verification against the baseline being checked out.", null);
}
if (resource.getRevision() != youngestRevision) {
throw new DAVException("The specified baseline is not the latest baseline, so it may not be checked out.", null,
HttpServletResponse.SC_CONFLICT, null, SVNLogType.NETWORK, Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG,
DAVElement.SVN_DAV_ERROR_NAMESPACE, SVNErrorCode.APMOD_BAD_BASELINE.getCode(), null);
}
} else {
FSTransactionInfo txnInfo = DAVServletUtil.openTxn(fsfs, txnName);
FSTransactionRoot txnRoot = null;
String reposPath = resource.getResourceURI().getPath();
try {
txnRoot = fsfs.createTransactionRoot(txnInfo);
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Could not open the transaction tree.", null);
}
long txnCreatedRevision = -1;
try {
FSRevisionNode node = txnRoot.getRevisionNode(reposPath);
txnCreatedRevision = node.getCreatedRevision();
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Could not get created-rev of transaction node.", null);
}
if (SVNRevision.isValidRevisionNumber(txnCreatedRevision)) {
SVNDebugLog.getDefaultLog().logFine(SVNLogType.DEFAULT, "resource.getRevision(): " + resource.getRevision() + ", txnCreatedRevision: " + txnCreatedRevision);
SVNDebugLog.getDefaultLog().logFine(SVNLogType.DEFAULT, "resource type: " + resource.getType());
if (resource.getRevision() < txnCreatedRevision) {
throw new DAVException("resource out of date; try updating", null, HttpServletResponse.SC_CONFLICT, null, SVNLogType.NETWORK,
Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG, DAVElement.SVN_DAV_ERROR_NAMESPACE,
SVNErrorCode.FS_CONFLICT.getCode(), null);
} else if (resource.getRevision() > txnCreatedRevision) {
String txnNodeRevID = null;
try {
FSRevisionNode node = txnRoot.getRevisionNode(reposPath);
txnNodeRevID = node.getId().getNodeID();
} catch (SVNException svne) {
SVNErrorMessage err = svne.getErrorMessage();
throw new DAVException("Unable to fetch the node revision id of the version resource within the transaction.", null,
HttpServletResponse.SC_CONFLICT, err, SVNLogType.FSFS, Level.FINE, null,
DAVXMLUtil.SVN_DAV_ERROR_TAG, DAVElement.SVN_DAV_ERROR_NAMESPACE, err.getErrorCode().getCode(), null);
}
String urlNodeRevID = null;
try {
FSRoot root = resource.getRoot();
FSRevisionNode node = root.getRevisionNode(reposPath);
urlNodeRevID = node.getId().getNodeID();
} catch (SVNException svne) {
SVNErrorMessage err = svne.getErrorMessage();
throw new DAVException("Unable to fetch the node revision id of the version resource within the revision.", null,
HttpServletResponse.SC_CONFLICT, err, SVNLogType.FSFS, Level.FINE, null,
DAVXMLUtil.SVN_DAV_ERROR_TAG, DAVElement.SVN_DAV_ERROR_NAMESPACE, err.getErrorCode().getCode(), null);
}
if (!urlNodeRevID.equals(txnNodeRevID)) {
throw new DAVException("version resource newer than txn (restart the commit)", null, HttpServletResponse.SC_CONFLICT,
null, SVNLogType.NETWORK, Level.FINE, null, DAVXMLUtil.SVN_DAV_ERROR_TAG, DAVElement.SVN_DAV_ERROR_NAMESPACE,
SVNErrorCode.FS_CONFLICT.getCode(), null);
}
}
}