public static SVNCommitItem[] harvestCommitables(SVNWCAccess baseAccess, Collection paths, Map lockTokens,
boolean justLocked, SVNDepth depth, boolean force, Collection changelists,
ISVNCommitParameters params) throws SVNException {
// TODO
Map commitables = new TreeMap(FILE_COMPARATOR);
Collection danglers = new SVNHashSet();
Iterator targets = paths.iterator();
boolean isRecursionForced = false;
do {
String target = targets.hasNext() ? (String) targets.next() : "";
baseAccess.checkCancelled();
// get entry for target
File targetFile = new File(baseAccess.getAnchor(), target);
String targetName = "".equals(target) ? "" : SVNPathUtil.tail(target);
String parentPath = SVNPathUtil.removeTail(target);
SVNAdminArea dir = baseAccess.probeRetrieve(targetFile);
SVNEntry entry = baseAccess.getVersionedEntry(targetFile, false);
String url = null;
if (entry.getURL() == null) {
// it could be missing directory.
if (!entry.isThisDir() && entry.getName() != null &&
entry.isDirectory() && !(entry.isScheduledForAddition() || entry.isScheduledForReplacement()) && SVNFileType.getType(targetFile) == SVNFileType.NONE) {
File parentDir = targetFile.getParentFile();
if (parentDir != null) {
SVNEntry parentEntry = baseAccess.getEntry(parentDir, false);
if (parentEntry != null) {
url = SVNPathUtil.append(parentEntry.getURL(), SVNEncodingUtil.uriEncode(entry.getName()));
}
}
}
if (url == null) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT, "Entry for ''{0}'' has no URL", targetFile);
SVNErrorManager.error(err, SVNLogType.WC);
}
} else {
url = entry.getURL();
}
SVNEntry parentEntry = null;
if (entry.isScheduledForAddition() || entry.isScheduledForReplacement()) {
// get parent (for file or dir-> get ""), otherwise open parent
// dir and get "".
try {
baseAccess.retrieve(targetFile.getParentFile());
} catch (SVNException e) {
if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
baseAccess.open(targetFile.getParentFile(), true, 0);
} else {
throw e;
}
}
parentEntry = baseAccess.getEntry(targetFile.getParentFile(), false);
if (parentEntry == null) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT,
"''{0}'' is scheduled for addition within unversioned parent", targetFile);
SVNErrorManager.error(err, SVNLogType.WC);
} else if (parentEntry.isScheduledForAddition() || parentEntry.isScheduledForReplacement()) {
danglers.add(targetFile.getParentFile());
}
}
SVNDepth forcedDepth = depth;
if (entry.isCopied() && entry.getSchedule() == null) {
// if commit is forced => we could collect this entry, assuming
// that its parent is already included into commit
// it will be later removed from commit anyway.
if (!force) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ILLEGAL_TARGET,
"Entry for ''{0}''"
+ " is marked as 'copied' but is not itself scheduled\n"
+ "for addition. Perhaps you're committing a target that is\n"
+ "inside an unversioned (or not-yet-versioned) directory?", targetFile);
SVNErrorManager.error(err, SVNLogType.WC);
} else {
// just do not process this item as in case of recursive
// commit.
continue;
}
} else if (entry.isCopied() && entry.isScheduledForAddition()) {
if (force) {
isRecursionForced = depth != SVNDepth.INFINITY;
forcedDepth = SVNDepth.INFINITY;
}
} else if (entry.isScheduledForDeletion() && force && depth != SVNDepth.INFINITY) {
// if parent is also deleted -> skip this entry
if (!"".equals(targetName)) {
parentEntry = dir.getEntry("", false);
} else {
File parentFile = targetFile.getParentFile();
try {
baseAccess.retrieve(parentFile);
} catch (SVNException e) {
if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
baseAccess.open(targetFile.getParentFile(), true, 0);
} else {
throw e;
}
}
parentEntry = baseAccess.getEntry(parentFile, false);
}
if (parentEntry != null && parentEntry.isScheduledForDeletion() && paths.contains(parentPath)) {
continue;
}
// this recursion is not considered as "forced", all children should be
// deleted anyway.
forcedDepth = SVNDepth.INFINITY;
}
// String relativePath = entry.getKind() == SVNNodeKind.DIR ? target : SVNPathUtil.removeTail(target);
harvestCommitables(commitables, dir, targetFile, parentEntry, entry, url, null, false, false,
justLocked, lockTokens, forcedDepth, isRecursionForced, changelists, params, null);
} while (targets.hasNext());
for (Iterator ds = danglers.iterator(); ds.hasNext();) {
baseAccess.checkCancelled();
File file = (File) ds.next();
if (!commitables.containsKey(file)) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ILLEGAL_TARGET,
"''{0}'' is not under version control\n"