package org.tmatesoft.svn.core.internal.wc2.ng;
import java.io.File;
import java.util.Set;
import java.util.logging.Level;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.core.internal.wc17.SVNWCContext;
import org.tmatesoft.svn.core.internal.wc17.SVNWCUtils;
import org.tmatesoft.svn.core.internal.wc17.db.ISVNWCDb;
import org.tmatesoft.svn.core.internal.wc17.db.ISVNWCDb.SVNWCDbOpenMode;
import org.tmatesoft.svn.core.internal.wc17.db.ISVNWCDb.WCDbInfo;
import org.tmatesoft.svn.core.internal.wc17.db.ISVNWCDb.WCDbInfo.InfoField;
import org.tmatesoft.svn.core.internal.wc17.db.SVNWCDb;
import org.tmatesoft.svn.core.wc.ISVNOptions;
import org.tmatesoft.svn.core.wc2.SvnCleanup;
import org.tmatesoft.svn.util.SVNDebugLog;
import org.tmatesoft.svn.util.SVNLogType;
public class SvnNgCleanup extends SvnNgOperationRunner<Void, SvnCleanup> {
@Override
protected Void run(SVNWCContext context) throws SVNException {
if (getOperation().getFirstTarget().isURL()) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ILLEGAL_TARGET,
"''{0}'' is not a local path", getOperation().getFirstTarget().getURL());
SVNErrorManager.error(err, SVNLogType.WC);
}
File localAbsPath = getOperation().getFirstTarget().getFile().getAbsoluteFile();
SVNWCDb db = new SVNWCDb();
SVNWCContext wcContext = new SVNWCContext(db, context.getEventHandler());
cleanup(wcContext, localAbsPath);
sleepForTimestamp();
return null;
}
private void cleanup(SVNWCContext wcContext, File localAbsPath) throws SVNException {
try {
wcContext.getDb().open(SVNWCDbOpenMode.ReadWrite, (ISVNOptions)null, true, false);
cleanupInternal(wcContext, localAbsPath);
wcContext.getDb().clearDavCacheRecursive(localAbsPath);
}
finally {
wcContext.getDb().close();
}
}
private int canBeCleaned(SVNWCContext wcContext, File localAbsPath) throws SVNException {
int wcFormat = wcContext.checkWC(localAbsPath);
if (wcFormat == 0) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY,
"''{0}'' is not a working copy directory", localAbsPath);
SVNErrorManager.error(err, SVNLogType.WC);
}
if (wcFormat < SVNWCContext.WC_NG_VERSION) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.WC_UNSUPPORTED_FORMAT,
"Log format too old, please use Subversion 1.6 or earlier");
SVNErrorManager.error(err, SVNLogType.WC);
}
return wcFormat;
}
private void cleanupInternal(SVNWCContext wcContext, File localAbsPath) throws SVNException {
int wcFormat = canBeCleaned(wcContext, localAbsPath);
wcContext.getDb().obtainWCLock(localAbsPath, -1, true);
if (wcFormat >= ISVNWCDb.WC_HAS_WORK_QUEUE) {
wcContext.wqRun(localAbsPath);
}
File cleanupWCRoot = wcContext.getDb().getWCRoot(localAbsPath);
if (cleanupWCRoot.equals(localAbsPath)) {
SVNWCUtils.admCleanupTmpArea(wcContext, localAbsPath);
wcContext.getDb().cleanupPristine(localAbsPath);
}
repairTimestamps(wcContext, localAbsPath);
wcContext.getDb().releaseWCLock(localAbsPath);
}
public static void repairTimestamps(SVNWCContext wcContext, File localAbsPath) throws SVNException {
wcContext.checkCancelled();
WCDbInfo info = wcContext.getDb().readInfo(localAbsPath, InfoField.status, InfoField.kind);
if (info.status == ISVNWCDb.SVNWCDbStatus.ServerExcluded
|| info.status == ISVNWCDb.SVNWCDbStatus.Deleted
|| info.status == ISVNWCDb.SVNWCDbStatus.Excluded
|| info.status == ISVNWCDb.SVNWCDbStatus.NotPresent
) {
return;
}
if (info.kind == ISVNWCDb.SVNWCDbKind.File || info.kind == ISVNWCDb.SVNWCDbKind.Symlink) {
try {
wcContext.isTextModified(localAbsPath, false);
} catch (SVNException e) {
SVNDebugLog.getDefaultLog().log(SVNLogType.WC, e, Level.WARNING);
}
}
else if (info.kind == ISVNWCDb.SVNWCDbKind.Dir) {
Set<String> children = wcContext.getDb().readChildren(localAbsPath);
for (String childPath : children) {
File childAbsPath = SVNFileUtil.createFilePath(localAbsPath, childPath);
repairTimestamps(wcContext, childAbsPath);
}
}
return;
}
}