if (handler == null) {
return -1;
}
depth = depth == null ? SVNDepth.UNKNOWN : depth;
SVNWCAccess wcAccess = createWCAccess();
SVNStatusEditor editor = null;
final boolean[] deletedInRepository = new boolean[] {false};
ISVNStatusHandler realHandler = new ISVNStatusHandler() {
public void handleStatus(SVNStatus status) throws SVNException {
if (deletedInRepository[0] && status.getEntry() != null) {
status.setRemoteStatus(SVNStatusType.STATUS_DELETED, null, null, null);
}
if (!SVNWCAccess.matchesChangeList(changeLists, status.getEntry())) {
return;
}
handler.handleStatus(status);
}
};
try {
SVNAdminAreaInfo info = null;
try {
SVNAdminArea anchor = wcAccess.open(path, false, SVNDepth.recurseFromDepth(depth) ? -1 : 1);
info = new SVNAdminAreaInfo(wcAccess, anchor, anchor, "");
} catch (SVNException svne) {
if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_DIRECTORY) {
info = wcAccess.openAnchor(path, false, SVNDepth.recurseFromDepth(depth) ? -1 : 1);
if (depth == SVNDepth.EMPTY) {
depth = SVNDepth.IMMEDIATES;
}
} else {
throw svne;
}
}
SVNEntry entry = null;
if (remote) {
SVNAdminArea anchor = info.getAnchor();
entry = wcAccess.getVersionedEntry(anchor.getRoot(), false);
if (entry.getURL() == null) {
SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "Entry ''{0}'' has no URL", info.getAnchor().getRoot());
SVNErrorManager.error(error, SVNLogType.WC);
}
SVNURL url = entry.getSVNURL();
SVNRepository repository = createRepository(url, anchor.getRoot(), wcAccess, true);
long rev;
if (revision == SVNRevision.HEAD) {
rev = -1;
} else {
rev = getRevisionNumber(revision, repository, path);
}
SVNNodeKind kind = repository.checkPath("", rev);
checkCancelled();
SVNReporter reporter = null;
if (kind == SVNNodeKind.NONE) {
if (!entry.isScheduledForAddition()) {
deletedInRepository[0] = true;
}
editor = new SVNStatusEditor(getOptions(), wcAccess, info, includeIgnored, reportAll, depth,
realHandler);
checkCancelled();
editor.closeEdit();
} else {
editor = new SVNRemoteStatusEditor(getOptions(), wcAccess, info, includeIgnored, reportAll,
depth, realHandler);
// session is closed in SVNStatusReporter.
SVNRepository locksRepos = createRepository(url, anchor.getRoot(), wcAccess, false);
checkCancelled();
boolean serverSupportsDepth = repository.hasCapability(SVNCapability.DEPTH);
reporter = new SVNReporter(info, path, false, !serverSupportsDepth, depth, false, true, true,
getDebugLog());
SVNStatusReporter statusReporter = new SVNStatusReporter(locksRepos, reporter, editor);
String target = "".equals(info.getTargetName()) ? null : info.getTargetName();
repository.status(rev, target, depth, statusReporter, SVNCancellableEditor.newInstance((ISVNEditor) editor, getEventDispatcher(), getDebugLog()));
}
if (getEventDispatcher() != null) {
long reportedFiles = reporter != null ? reporter.getReportedFilesCount() : 0;
long totalFiles = reporter != null ? reporter.getTotalFilesCount() : 0;
SVNEvent event = SVNEventFactory.createSVNEvent(info.getAnchor().getFile(info.getTargetName()), SVNNodeKind.NONE, null, editor.getTargetRevision(), SVNEventAction.STATUS_COMPLETED, null, null, null, reportedFiles, totalFiles);
getEventDispatcher().handleEvent(event, ISVNEventHandler.UNKNOWN);
}
} else {
editor = new SVNStatusEditor(getOptions(), wcAccess, info, includeIgnored, reportAll, depth, handler);
editor.closeEdit();
}
if (!isIgnoreExternals() && (depth == SVNDepth.INFINITY || depth == SVNDepth.UNKNOWN)) {
// iterate over externals that were collected in SVNAdminAreaInfo.
Map externalsMap = info.getNewExternals();
for (Iterator paths = externalsMap.keySet().iterator(); paths.hasNext();) {
String ownerPath = (String) paths.next();
String externalValue = (String) externalsMap.get(ownerPath);
SVNExternal[] externals = SVNExternal.parseExternals(ownerPath, externalValue);
for (int i = 0; i < externals.length; i++) {
SVNExternal external = externals[i];
String externalPath = SVNPathUtil.append(ownerPath, external.getPath());
File externalFile = info.getAnchor().getFile(externalPath);
if (SVNFileType.getType(externalFile) != SVNFileType.DIRECTORY) {
continue;
}
try {
int format = SVNAdminAreaFactory.checkWC(externalFile, true);
if (format == 0) {
// something unversioned instead of external.
continue;
}
} catch (SVNException e) {
continue;
}
handleEvent(SVNEventFactory.createSVNEvent(externalFile, SVNNodeKind.DIR, null, SVNRepository.INVALID_REVISION, SVNEventAction.STATUS_EXTERNAL, null, null, null),
ISVNEventHandler.UNKNOWN);
setEventPathPrefix(externalPath);
try {
doStatus(externalFile, SVNRevision.HEAD, depth, remote, reportAll, includeIgnored,
false, handler, null);
} catch (SVNException e) {
if (e instanceof SVNCancelException) {
throw e;
}
} finally {
setEventPathPrefix(null);
}
}
}
}
} finally {
wcAccess.close();
}
return editor.getTargetRevision();
}