Source Code Cross Referenced for SVNCommitUtil.java in  » Source-Control » tmatesoft-SVN » org » tmatesoft » svn » core » internal » wc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Source Control » tmatesoft SVN » org.tmatesoft.svn.core.internal.wc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * ====================================================================
0003:         * Copyright (c) 2004-2008 TMate Software Ltd.  All rights reserved.
0004:         *
0005:         * This software is licensed as described in the file COPYING, which
0006:         * you should have received as part of this distribution.  The terms
0007:         * are also available at http://svnkit.com/license.html
0008:         * If newer versions of this license are posted there, you may use a
0009:         * newer version instead, at your option.
0010:         * ====================================================================
0011:         */
0012:        package org.tmatesoft.svn.core.internal.wc;
0013:
0014:        import java.io.File;
0015:        import java.util.ArrayList;
0016:        import java.util.Arrays;
0017:        import java.util.Collection;
0018:        import java.util.Collections;
0019:        import java.util.HashMap;
0020:        import java.util.HashSet;
0021:        import java.util.Iterator;
0022:        import java.util.List;
0023:        import java.util.Map;
0024:        import java.util.StringTokenizer;
0025:        import java.util.TreeMap;
0026:
0027:        import org.tmatesoft.svn.core.SVNCancelException;
0028:        import org.tmatesoft.svn.core.SVNErrorCode;
0029:        import org.tmatesoft.svn.core.SVNErrorMessage;
0030:        import org.tmatesoft.svn.core.SVNException;
0031:        import org.tmatesoft.svn.core.SVNNodeKind;
0032:        import org.tmatesoft.svn.core.SVNProperty;
0033:        import org.tmatesoft.svn.core.SVNURL;
0034:        import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
0035:        import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
0036:        import org.tmatesoft.svn.core.internal.wc.admin.SVNAdminArea;
0037:        import org.tmatesoft.svn.core.internal.wc.admin.SVNEntry;
0038:        import org.tmatesoft.svn.core.internal.wc.admin.SVNVersionedProperties;
0039:        import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess;
0040:        import org.tmatesoft.svn.core.io.ISVNEditor;
0041:        import org.tmatesoft.svn.core.wc.ISVNCommitParameters;
0042:        import org.tmatesoft.svn.core.wc.ISVNEventHandler;
0043:        import org.tmatesoft.svn.core.wc.SVNCommitItem;
0044:        import org.tmatesoft.svn.core.wc.SVNEvent;
0045:        import org.tmatesoft.svn.core.wc.SVNRevision;
0046:        import org.tmatesoft.svn.core.wc.SVNStatus;
0047:        import org.tmatesoft.svn.core.wc.SVNStatusClient;
0048:        import org.tmatesoft.svn.core.wc.SVNStatusType;
0049:        import org.tmatesoft.svn.core.wc.SVNWCUtil;
0050:
0051:        /**
0052:         * @version 1.1.1
0053:         * @author  TMate Software Ltd.
0054:         */
0055:        public class SVNCommitUtil {
0056:
0057:            public static void driveCommitEditor(ISVNCommitPathHandler handler,
0058:                    Collection paths, ISVNEditor editor, long revision)
0059:                    throws SVNException {
0060:                if (paths == null || paths.isEmpty() || handler == null
0061:                        || editor == null) {
0062:                    return;
0063:                }
0064:                String[] pathsArray = (String[]) paths.toArray(new String[paths
0065:                        .size()]);
0066:                Arrays.sort(pathsArray, SVNPathUtil.PATH_COMPARATOR);
0067:                int index = 0;
0068:                String lastPath = null;
0069:                if ("".equals(pathsArray[index])) {
0070:                    handler.handleCommitPath("", editor);
0071:                    lastPath = pathsArray[index];
0072:                    index++;
0073:                } else {
0074:                    editor.openRoot(revision);
0075:                }
0076:                for (; index < pathsArray.length; index++) {
0077:                    String commitPath = pathsArray[index];
0078:                    String commonAncestor = lastPath == null
0079:                            || "".equals(lastPath) ? "" : SVNPathUtil
0080:                            .getCommonPathAncestor(commitPath, lastPath);
0081:                    if (lastPath != null) {
0082:                        while (!lastPath.equals(commonAncestor)) {
0083:                            editor.closeDir();
0084:                            if (lastPath.lastIndexOf('/') >= 0) {
0085:                                lastPath = lastPath.substring(0, lastPath
0086:                                        .lastIndexOf('/'));
0087:                            } else {
0088:                                lastPath = "";
0089:                            }
0090:                        }
0091:                    }
0092:                    String relativeCommitPath = commitPath
0093:                            .substring(commonAncestor.length());
0094:                    if (relativeCommitPath.startsWith("/")) {
0095:                        relativeCommitPath = relativeCommitPath.substring(1);
0096:                    }
0097:
0098:                    for (StringTokenizer tokens = new StringTokenizer(
0099:                            relativeCommitPath, "/"); tokens.hasMoreTokens();) {
0100:                        String token = tokens.nextToken();
0101:                        commonAncestor = "".equals(commonAncestor) ? token
0102:                                : commonAncestor + "/" + token;
0103:                        if (!commonAncestor.equals(commitPath)) {
0104:                            editor.openDir(commonAncestor, revision);
0105:                        } else {
0106:                            break;
0107:                        }
0108:                    }
0109:                    boolean closeDir = handler.handleCommitPath(commitPath,
0110:                            editor);
0111:                    if (closeDir) {
0112:                        lastPath = commitPath;
0113:                    } else {
0114:                        if (index + 1 < pathsArray.length) {
0115:                            lastPath = SVNPathUtil.removeTail(commitPath);
0116:                        } else {
0117:                            lastPath = commitPath;
0118:                        }
0119:                    }
0120:                }
0121:                while (lastPath != null && !"".equals(lastPath)) {
0122:                    editor.closeDir();
0123:                    lastPath = lastPath.lastIndexOf('/') >= 0 ? lastPath
0124:                            .substring(0, lastPath.lastIndexOf('/')) : "";
0125:                }
0126:            }
0127:
0128:            public static SVNWCAccess createCommitWCAccess(File[] paths,
0129:                    boolean recursive, boolean force, Collection relativePaths,
0130:                    final SVNStatusClient statusClient) throws SVNException {
0131:                String[] validatedPaths = new String[paths.length];
0132:                for (int i = 0; i < paths.length; i++) {
0133:                    statusClient.checkCancelled();
0134:                    File file = paths[i];
0135:                    validatedPaths[i] = SVNPathUtil.validateFilePath(file
0136:                            .getAbsolutePath());
0137:                }
0138:                String rootPath = SVNPathUtil.condencePaths(validatedPaths,
0139:                        relativePaths, recursive);
0140:                if (rootPath == null) {
0141:                    return null;
0142:                }
0143:                File baseDir = new File(rootPath).getAbsoluteFile();
0144:                rootPath = baseDir.getAbsolutePath().replace(
0145:                        File.separatorChar, '/');
0146:                Collection dirsToLock = new HashSet(); // relative paths to lock.
0147:                Collection dirsToLockRecursively = new HashSet();
0148:                boolean lockAll = false;
0149:                if (relativePaths.isEmpty()) {
0150:                    statusClient.checkCancelled();
0151:                    String target = getTargetName(baseDir);
0152:                    if (!"".equals(target)) {
0153:                        // we will have to lock target as well, not only base dir.
0154:                        SVNFileType targetType = SVNFileType.getType(new File(
0155:                                rootPath));
0156:                        relativePaths.add(target);
0157:                        if (targetType == SVNFileType.DIRECTORY) {
0158:                            // lock recursively if forced and copied...
0159:                            if (recursive
0160:                                    || (force && isRecursiveCommitForced(baseDir))) {
0161:                                // dir is copied, include children
0162:                                dirsToLockRecursively.add(target);
0163:                            } else {
0164:                                dirsToLock.add(target);
0165:                            }
0166:                        }
0167:                        baseDir = baseDir.getParentFile();
0168:                    } else {
0169:                        lockAll = true;
0170:                    }
0171:                } else {
0172:                    baseDir = adjustRelativePaths(baseDir, relativePaths);
0173:                    // there are multiple paths.
0174:                    for (Iterator targets = relativePaths.iterator(); targets
0175:                            .hasNext();) {
0176:                        statusClient.checkCancelled();
0177:                        String targetPath = (String) targets.next();
0178:                        File targetFile = new File(baseDir, targetPath);
0179:                        SVNFileType targetKind = SVNFileType
0180:                                .getType(targetFile);
0181:                        if (targetKind == SVNFileType.DIRECTORY) {
0182:                            if (recursive
0183:                                    || (force && isRecursiveCommitForced(targetFile))) {
0184:                                dirsToLockRecursively.add(targetPath);
0185:                            } else if (!targetFile.equals(baseDir)) {
0186:                                dirsToLock.add(targetPath);
0187:                            }
0188:                        }
0189:                        if (!targetFile.equals(baseDir)) {
0190:                            targetFile = targetFile.getParentFile();
0191:                            targetPath = SVNPathUtil.removeTail(targetPath);
0192:                            while (targetFile != null
0193:                                    && !targetFile.equals(baseDir)
0194:                                    && !dirsToLock.contains(targetPath)) {
0195:                                dirsToLock.add(targetPath);
0196:                                targetPath = SVNPathUtil.removeTail(targetPath);
0197:                                targetFile = targetFile.getParentFile();
0198:                            }
0199:                        }
0200:                    }
0201:                }
0202:                SVNWCAccess baseAccess = SVNWCAccess
0203:                        .newInstance(new ISVNEventHandler() {
0204:                            public void handleEvent(SVNEvent event,
0205:                                    double progress) throws SVNException {
0206:                            }
0207:
0208:                            public void checkCancelled()
0209:                                    throws SVNCancelException {
0210:                                statusClient.checkCancelled();
0211:                            }
0212:                        });
0213:                baseAccess.setOptions(statusClient.getOptions());
0214:                try {
0215:                    baseAccess.open(baseDir, true,
0216:                            lockAll ? SVNWCAccess.INFINITE_DEPTH : 0);
0217:                    statusClient.checkCancelled();
0218:                    dirsToLock = new ArrayList(dirsToLock);
0219:                    dirsToLockRecursively = new ArrayList(dirsToLockRecursively);
0220:                    Collections.sort((List) dirsToLock,
0221:                            SVNPathUtil.PATH_COMPARATOR);
0222:                    Collections.sort((List) dirsToLockRecursively,
0223:                            SVNPathUtil.PATH_COMPARATOR);
0224:                    if (!lockAll) {
0225:                        List uniqueDirsToLockRecursively = new ArrayList();
0226:                        uniqueDirsToLockRecursively
0227:                                .addAll(dirsToLockRecursively);
0228:                        for (Iterator ps = uniqueDirsToLockRecursively
0229:                                .iterator(); ps.hasNext();) {
0230:                            String pathToLock = (String) ps.next();
0231:                            for (Iterator existing = dirsToLockRecursively
0232:                                    .iterator(); existing.hasNext();) {
0233:                                String existingPath = (String) existing.next();
0234:                                if (pathToLock.startsWith(existingPath + "/")) {
0235:                                    // child of other path
0236:                                    ps.remove();
0237:                                    break;
0238:                                }
0239:                            }
0240:
0241:                        }
0242:                        Collections.sort(uniqueDirsToLockRecursively,
0243:                                SVNPathUtil.PATH_COMPARATOR);
0244:                        dirsToLockRecursively = uniqueDirsToLockRecursively;
0245:                        removeRedundantPaths(dirsToLockRecursively, dirsToLock);
0246:                        for (Iterator nonRecusivePaths = dirsToLock.iterator(); nonRecusivePaths
0247:                                .hasNext();) {
0248:                            statusClient.checkCancelled();
0249:                            String path = (String) nonRecusivePaths.next();
0250:                            File pathFile = new File(baseDir, path);
0251:                            baseAccess.open(pathFile, true, 0);
0252:                        }
0253:                        for (Iterator recusivePaths = dirsToLockRecursively
0254:                                .iterator(); recusivePaths.hasNext();) {
0255:                            statusClient.checkCancelled();
0256:                            String path = (String) recusivePaths.next();
0257:                            File pathFile = new File(baseDir, path);
0258:                            baseAccess.open(pathFile, true,
0259:                                    SVNWCAccess.INFINITE_DEPTH);
0260:                        }
0261:                    }
0262:                    for (int i = 0; i < paths.length; i++) {
0263:                        statusClient.checkCancelled();
0264:                        File path = new File(SVNPathUtil
0265:                                .validateFilePath(paths[i].getAbsolutePath()));
0266:                        path = path.getAbsoluteFile();
0267:                        try {
0268:                            baseAccess.probeRetrieve(path);
0269:                        } catch (SVNException e) {
0270:                            SVNErrorMessage err = e
0271:                                    .getErrorMessage()
0272:                                    .wrap(
0273:                                            "Are all the targets part of the same working copy?");
0274:                            SVNErrorManager.error(err);
0275:                        }
0276:                        if (!recursive && !force) {
0277:                            if (SVNFileType.getType(path) == SVNFileType.DIRECTORY) {
0278:                                // TODO replace with direct SVNStatusEditor call.
0279:                                SVNStatus status = statusClient.doStatus(path,
0280:                                        false);
0281:                                if (status != null
0282:                                        && (status.getContentsStatus() == SVNStatusType.STATUS_DELETED || status
0283:                                                .getContentsStatus() == SVNStatusType.STATUS_REPLACED)) {
0284:                                    SVNErrorMessage err = SVNErrorMessage
0285:                                            .create(
0286:                                                    SVNErrorCode.UNSUPPORTED_FEATURE,
0287:                                                    "Cannot non-recursively commit a directory deletion");
0288:                                    SVNErrorManager.error(err);
0289:                                }
0290:                            }
0291:                        }
0292:                    }
0293:                    // if commit is non-recursive and forced, remove those child dirs 
0294:                    // that were not explicitly added but are explicitly copied. ufff.
0295:                    if (!recursive && force) {
0296:                        SVNAdminArea[] lockedDirs = baseAccess.getAdminAreas();
0297:                        for (int i = 0; i < lockedDirs.length; i++) {
0298:                            statusClient.checkCancelled();
0299:                            SVNAdminArea dir = lockedDirs[i];
0300:                            if (dir == null) {
0301:                                // could be null for missing, but known dir.
0302:                                continue;
0303:                            }
0304:                            SVNEntry rootEntry = baseAccess.getEntry(dir
0305:                                    .getRoot(), true);
0306:                            if (rootEntry.getCopyFromURL() != null) {
0307:                                File dirRoot = dir.getRoot();
0308:                                boolean keep = false;
0309:                                for (int j = 0; j < paths.length; j++) {
0310:                                    if (dirRoot.equals(paths[j])) {
0311:                                        keep = true;
0312:                                        break;
0313:                                    }
0314:                                }
0315:                                if (!keep) {
0316:                                    baseAccess.closeAdminArea(dir.getRoot());
0317:                                }
0318:                            }
0319:                        }
0320:                    }
0321:                } catch (SVNException e) {
0322:                    baseAccess.close();
0323:                    throw e;
0324:                }
0325:                baseAccess.setAnchor(baseDir);
0326:                return baseAccess;
0327:            }
0328:
0329:            public static SVNWCAccess[] createCommitWCAccess2(File[] paths,
0330:                    boolean recursive, boolean force, Map relativePathsMap,
0331:                    SVNStatusClient statusClient) throws SVNException {
0332:                Map rootsMap = new HashMap(); // wc root file -> paths to be committed (paths).
0333:                Map localRootsCache = new HashMap();
0334:                for (int i = 0; i < paths.length; i++) {
0335:                    statusClient.checkCancelled();
0336:                    File path = paths[i];
0337:                    File rootPath = path;
0338:                    if (rootPath.isFile()) {
0339:                        rootPath = rootPath.getParentFile();
0340:                    }
0341:                    File wcRoot = localRootsCache.containsKey(rootPath) ? (File) localRootsCache
0342:                            .get(rootPath)
0343:                            : SVNWCUtil.getWorkingCopyRoot(rootPath, true);
0344:                    localRootsCache.put(path, wcRoot);
0345:                    if (!rootsMap.containsKey(wcRoot)) {
0346:                        rootsMap.put(wcRoot, new ArrayList());
0347:                    }
0348:                    Collection wcPaths = (Collection) rootsMap.get(wcRoot);
0349:                    wcPaths.add(path);
0350:                }
0351:                Collection result = new ArrayList();
0352:                try {
0353:                    for (Iterator roots = rootsMap.keySet().iterator(); roots
0354:                            .hasNext();) {
0355:                        statusClient.checkCancelled();
0356:                        File root = (File) roots.next();
0357:                        Collection filesList = (Collection) rootsMap.get(root);
0358:                        File[] filesArray = (File[]) filesList
0359:                                .toArray(new File[filesList.size()]);
0360:                        Collection relativePaths = new ArrayList();
0361:                        SVNWCAccess wcAccess = createCommitWCAccess(filesArray,
0362:                                recursive, force, relativePaths, statusClient);
0363:                        relativePathsMap.put(wcAccess, relativePaths);
0364:                        result.add(wcAccess);
0365:                    }
0366:                } catch (SVNException e) {
0367:                    for (Iterator wcAccesses = result.iterator(); wcAccesses
0368:                            .hasNext();) {
0369:                        SVNWCAccess wcAccess = (SVNWCAccess) wcAccesses.next();
0370:                        wcAccess.close();
0371:                    }
0372:                    throw e;
0373:                }
0374:                return (SVNWCAccess[]) result.toArray(new SVNWCAccess[result
0375:                        .size()]);
0376:            }
0377:
0378:            public static SVNCommitItem[] harvestCommitables(
0379:                    SVNWCAccess baseAccess, Collection paths, Map lockTokens,
0380:                    boolean justLocked, boolean recursive, boolean force,
0381:                    ISVNCommitParameters params) throws SVNException {
0382:                Map commitables = new TreeMap();
0383:                Collection danglers = new HashSet();
0384:                Iterator targets = paths.iterator();
0385:
0386:                boolean isRecursionForced = false;
0387:
0388:                do {
0389:                    baseAccess.checkCancelled();
0390:                    String target = targets.hasNext() ? (String) targets.next()
0391:                            : "";
0392:                    // get entry for target
0393:                    File targetFile = new File(baseAccess.getAnchor(), target);
0394:                    String targetName = "".equals(target) ? "" : SVNPathUtil
0395:                            .tail(target);
0396:                    String parentPath = SVNPathUtil.removeTail(target);
0397:                    SVNAdminArea dir = baseAccess.probeRetrieve(targetFile);
0398:                    SVNEntry entry = baseAccess.getEntry(targetFile, false);
0399:                    String url = null;
0400:                    if (entry == null) {
0401:                        SVNErrorMessage err = SVNErrorMessage.create(
0402:                                SVNErrorCode.ENTRY_NOT_FOUND,
0403:                                "''{0}'' is not under version control",
0404:                                targetFile);
0405:                        SVNErrorManager.error(err);
0406:                    } else if (entry.getURL() == null) {
0407:                        SVNErrorMessage err = SVNErrorMessage.create(
0408:                                SVNErrorCode.ENTRY_MISSING_URL,
0409:                                "''{0}'' has no URL", targetFile);
0410:                        SVNErrorManager.error(err);
0411:                    } else {
0412:                        url = entry.getURL();
0413:                    }
0414:                    SVNEntry parentEntry = null;
0415:                    if (entry != null
0416:                            && (entry.isScheduledForAddition() || entry
0417:                                    .isScheduledForReplacement())) {
0418:                        // get parent (for file or dir-> get ""), otherwise open parent
0419:                        // dir and get "".
0420:                        try {
0421:                            baseAccess.retrieve(targetFile.getParentFile());
0422:                        } catch (SVNException e) {
0423:                            if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
0424:                                baseAccess.open(targetFile.getParentFile(),
0425:                                        true, 0);
0426:                            } else {
0427:                                throw e;
0428:                            }
0429:                        }
0430:                        parentEntry = baseAccess.getEntry(targetFile
0431:                                .getParentFile(), false);
0432:                        if (parentEntry == null) {
0433:                            SVNErrorMessage err = SVNErrorMessage
0434:                                    .create(
0435:                                            SVNErrorCode.WC_CORRUPT,
0436:                                            "''{0}'' is scheduled for addition within unversioned parent",
0437:                                            targetFile);
0438:                            SVNErrorManager.error(err);
0439:                        } else if (parentEntry.isScheduledForAddition()
0440:                                || parentEntry.isScheduledForReplacement()) {
0441:                            danglers.add(targetFile.getParentFile());
0442:                        }
0443:                    }
0444:                    boolean recurse = recursive;
0445:                    if (entry != null && entry.isCopied()
0446:                            && entry.getSchedule() == null) {
0447:                        // if commit is forced => we could collect this entry, assuming
0448:                        // that its parent is already included into commit
0449:                        // it will be later removed from commit anyway.
0450:                        if (!force) {
0451:                            SVNErrorMessage err = SVNErrorMessage
0452:                                    .create(
0453:                                            SVNErrorCode.ILLEGAL_TARGET,
0454:                                            "Entry for ''{0}''"
0455:                                                    + " is marked as 'copied' but is not itself scheduled\n"
0456:                                                    + "for addition.  Perhaps you're committing a target that is\n"
0457:                                                    + "inside an unversioned (or not-yet-versioned) directory?",
0458:                                            targetFile);
0459:                            SVNErrorManager.error(err);
0460:                        } else {
0461:                            // just do not process this item as in case of recursive
0462:                            // commit.
0463:                            continue;
0464:                        }
0465:                    } else if (entry != null && entry.isCopied()
0466:                            && entry.isScheduledForAddition()) {
0467:                        if (force) {
0468:                            isRecursionForced = !recursive;
0469:                            recurse = true;
0470:                        }
0471:                    } else if (entry != null && entry.isScheduledForDeletion()
0472:                            && force && !recursive) {
0473:                        // if parent is also deleted -> skip this entry
0474:                        if (!"".equals(targetName)) {
0475:                            parentEntry = dir.getEntry("", false);
0476:                        } else {
0477:                            File parentFile = targetFile.getParentFile();
0478:                            try {
0479:                                baseAccess.retrieve(parentFile);
0480:                            } catch (SVNException e) {
0481:                                if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
0482:                                    baseAccess.open(targetFile.getParentFile(),
0483:                                            true, 0);
0484:                                } else {
0485:                                    throw e;
0486:                                }
0487:                            }
0488:                            parentEntry = baseAccess
0489:                                    .getEntry(parentFile, false);
0490:                        }
0491:                        if (parentEntry != null
0492:                                && parentEntry.isScheduledForDeletion()
0493:                                && paths.contains(parentPath)) {
0494:                            continue;
0495:                        }
0496:                        // this recursion is not considered as "forced", all children should be 
0497:                        // deleted anyway.
0498:                        recurse = true;
0499:                    }
0500:                    //            String relativePath = entry.getKind() == SVNNodeKind.DIR ? target : SVNPathUtil.removeTail(target);
0501:                    harvestCommitables(commitables, dir, targetFile,
0502:                            parentEntry, entry, url, null, false, false,
0503:                            justLocked, lockTokens, recurse, isRecursionForced,
0504:                            params);
0505:                } while (targets.hasNext());
0506:
0507:                for (Iterator ds = danglers.iterator(); ds.hasNext();) {
0508:                    baseAccess.checkCancelled();
0509:                    File file = (File) ds.next();
0510:                    if (!commitables.containsKey(file)) {
0511:                        SVNErrorMessage err = SVNErrorMessage
0512:                                .create(
0513:                                        SVNErrorCode.ILLEGAL_TARGET,
0514:                                        "''{0}'' is not under version control\n"
0515:                                                + "and is not part of the commit, \n"
0516:                                                + "yet its child is part of the commit",
0517:                                        file);
0518:                        SVNErrorManager.error(err);
0519:                    }
0520:                }
0521:                if (isRecursionForced) {
0522:                    // if commit is non-recursive and forced and there are elements included into commit 
0523:                    // that not only 'copied' but also has local mods (modified or deleted), remove those items?
0524:                    // or not?
0525:                    for (Iterator items = commitables.values().iterator(); items
0526:                            .hasNext();) {
0527:                        baseAccess.checkCancelled();
0528:                        SVNCommitItem item = (SVNCommitItem) items.next();
0529:                        if (item.isDeleted()) {
0530:                            // to detect deleted copied items.
0531:                            File file = item.getFile();
0532:                            if (item.getKind() == SVNNodeKind.DIR) {
0533:                                if (!file.exists()) {
0534:                                    continue;
0535:                                }
0536:                            } else {
0537:                                String name = SVNPathUtil.tail(item.getPath());
0538:                                SVNAdminArea dir = baseAccess.retrieve(item
0539:                                        .getFile().getParentFile());
0540:                                if (!dir.getBaseFile(name, false).exists()) {
0541:                                    continue;
0542:                                }
0543:                            }
0544:                        }
0545:                        if (item.isContentsModified() || item.isDeleted()
0546:                                || item.isPropertiesModified()) {
0547:                            // if item was not explicitly included into commit, then just make it 'added'
0548:                            // but do not remove that are marked as 'deleted'
0549:                            String itemPath = item.getPath();
0550:                            if (!paths.contains(itemPath)) {
0551:                                items.remove();
0552:                            }
0553:                        }
0554:                    }
0555:                }
0556:                return (SVNCommitItem[]) commitables.values().toArray(
0557:                        new SVNCommitItem[commitables.values().size()]);
0558:            }
0559:
0560:            public static String translateCommitables(SVNCommitItem[] items,
0561:                    Map decodedPaths) throws SVNException {
0562:                Map itemsMap = new TreeMap();
0563:                for (int i = 0; i < items.length; i++) {
0564:                    SVNCommitItem item = items[i];
0565:                    if (itemsMap.containsKey(item.getURL().toString())) {
0566:                        SVNCommitItem oldItem = (SVNCommitItem) itemsMap
0567:                                .get(item.getURL().toString());
0568:                        SVNErrorMessage err = SVNErrorMessage
0569:                                .create(
0570:                                        SVNErrorCode.CLIENT_DUPLICATE_COMMIT_URL,
0571:                                        "Cannot commit both ''{0}'' and ''{1}'' as they refer to the same URL",
0572:                                        new Object[] { item.getFile(),
0573:                                                oldItem.getFile() });
0574:                        SVNErrorManager.error(err);
0575:                    }
0576:                    itemsMap.put(item.getURL().toString(), item);
0577:                }
0578:
0579:                Iterator urls = itemsMap.keySet().iterator();
0580:                String baseURL = (String) urls.next();
0581:                while (urls.hasNext()) {
0582:                    String url = (String) urls.next();
0583:                    baseURL = SVNPathUtil.getCommonURLAncestor(baseURL, url);
0584:                }
0585:                if (itemsMap.containsKey(baseURL)) {
0586:                    SVNCommitItem root = (SVNCommitItem) itemsMap.get(baseURL);
0587:                    if (root.getKind() != SVNNodeKind.DIR) {
0588:                        baseURL = SVNPathUtil.removeTail(baseURL);
0589:                    } else if (root.getKind() == SVNNodeKind.DIR
0590:                            && (root.isAdded() || root.isDeleted()
0591:                                    || root.isCopied() || root.isLocked())) {
0592:                        baseURL = SVNPathUtil.removeTail(baseURL);
0593:                    }
0594:                }
0595:                urls = itemsMap.keySet().iterator();
0596:                while (urls.hasNext()) {
0597:                    String url = (String) urls.next();
0598:                    SVNCommitItem item = (SVNCommitItem) itemsMap.get(url);
0599:                    String realPath = url.equals(baseURL) ? "" : url
0600:                            .substring(baseURL.length() + 1);
0601:                    decodedPaths.put(SVNEncodingUtil.uriDecode(realPath), item);
0602:                }
0603:                return baseURL;
0604:            }
0605:
0606:            public static Map translateLockTokens(Map lockTokens, String baseURL) {
0607:                Map translatedLocks = new TreeMap();
0608:                for (Iterator urls = lockTokens.keySet().iterator(); urls
0609:                        .hasNext();) {
0610:                    String url = (String) urls.next();
0611:                    String token = (String) lockTokens.get(url);
0612:                    url = url.equals(baseURL) ? "" : url.substring(baseURL
0613:                            .length() + 1);
0614:                    translatedLocks.put(SVNEncodingUtil.uriDecode(url), token);
0615:                }
0616:                lockTokens.clear();
0617:                lockTokens.putAll(translatedLocks);
0618:                return lockTokens;
0619:            }
0620:
0621:            public static void harvestCommitables(Map commitables,
0622:                    SVNAdminArea dir, File path, SVNEntry parentEntry,
0623:                    SVNEntry entry, String url, String copyFromURL,
0624:                    boolean copyMode, boolean addsOnly, boolean justLocked,
0625:                    Map lockTokens, boolean recursive, boolean forcedRecursion,
0626:                    ISVNCommitParameters params) throws SVNException {
0627:                if (commitables.containsKey(path)) {
0628:                    return;
0629:                }
0630:                if (dir != null && dir.getWCAccess() != null) {
0631:                    dir.getWCAccess().checkCancelled();
0632:                }
0633:                long cfRevision = entry.getCopyFromRevision();
0634:                String cfURL = null;
0635:                if (entry.getKind() != SVNNodeKind.DIR
0636:                        && entry.getKind() != SVNNodeKind.FILE) {
0637:                    SVNErrorMessage err = SVNErrorMessage.create(
0638:                            SVNErrorCode.NODE_UNKNOWN_KIND,
0639:                            "Unknown entry kind for ''{0}''", path);
0640:                    SVNErrorManager.error(err);
0641:                }
0642:                SVNFileType fileType = SVNFileType.getType(path);
0643:                if (fileType == SVNFileType.UNKNOWN) {
0644:                    SVNErrorMessage err = SVNErrorMessage.create(
0645:                            SVNErrorCode.NODE_UNKNOWN_KIND,
0646:                            "Unknown entry kind for ''{0}''", path);
0647:                    SVNErrorManager.error(err);
0648:                }
0649:                String specialPropertyValue = dir
0650:                        .getProperties(entry.getName()).getPropertyValue(
0651:                                SVNProperty.SPECIAL);
0652:                boolean specialFile = fileType == SVNFileType.SYMLINK;
0653:                if (SVNFileType.isSymlinkSupportEnabled()) {
0654:                    if (((specialPropertyValue == null && specialFile) || (!SVNFileUtil.isWindows
0655:                            && specialPropertyValue != null && !specialFile))
0656:                            && fileType != SVNFileType.NONE) {
0657:                        SVNErrorMessage err = SVNErrorMessage
0658:                                .create(
0659:                                        SVNErrorCode.NODE_UNEXPECTED_KIND,
0660:                                        "Entry ''{0}'' has unexpectedly changed special status",
0661:                                        path);
0662:                        SVNErrorManager.error(err);
0663:                    }
0664:                }
0665:                boolean propConflicts;
0666:                boolean textConflicts = false;
0667:                SVNAdminArea entries = null;
0668:                if (entry.getKind() == SVNNodeKind.DIR) {
0669:                    SVNAdminArea childDir = null;
0670:                    try {
0671:                        childDir = dir.getWCAccess().retrieve(
0672:                                dir.getFile(entry.getName()));
0673:                    } catch (SVNException e) {
0674:                        if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
0675:                            childDir = null;
0676:                        } else {
0677:                            throw e;
0678:                        }
0679:                    }
0680:                    if (childDir != null && childDir.entries(true) != null) {
0681:                        entries = childDir;
0682:                        if (entries.getEntry("", false) != null) {
0683:                            entry = entries.getEntry("", false);
0684:                            dir = childDir;
0685:                        }
0686:                    }
0687:                    propConflicts = dir.hasPropConflict(entry.getName());
0688:                } else {
0689:                    propConflicts = dir.hasPropConflict(entry.getName());
0690:                    textConflicts = dir.hasTextConflict(entry.getName());
0691:                }
0692:                if (propConflicts || textConflicts) {
0693:                    SVNErrorMessage err = SVNErrorMessage.create(
0694:                            SVNErrorCode.WC_FOUND_CONFLICT,
0695:                            "Aborting commit: ''{0}'' remains in conflict",
0696:                            path);
0697:                    SVNErrorManager.error(err);
0698:                }
0699:                if (entry.getURL() != null && !copyMode) {
0700:                    url = entry.getURL();
0701:                }
0702:                boolean commitDeletion = !addsOnly
0703:                        && ((entry.isDeleted() && entry.getSchedule() == null)
0704:                                || entry.isScheduledForDeletion() || entry
0705:                                .isScheduledForReplacement());
0706:                if (!addsOnly && !commitDeletion
0707:                        && fileType == SVNFileType.NONE && params != null) {
0708:                    ISVNCommitParameters.Action action = entry.getKind() == SVNNodeKind.DIR ? params
0709:                            .onMissingDirectory(path)
0710:                            : params.onMissingFile(path);
0711:                    if (action == ISVNCommitParameters.ERROR) {
0712:                        SVNErrorMessage err = SVNErrorMessage.create(
0713:                                SVNErrorCode.WC_NOT_LOCKED,
0714:                                "Working copy file ''{0}'' is missing", path);
0715:                        SVNErrorManager.error(err);
0716:                    } else if (action == ISVNCommitParameters.DELETE) {
0717:                        commitDeletion = true;
0718:                        entry.scheduleForDeletion();
0719:                        dir.saveEntries(false);
0720:                    }
0721:                }
0722:                boolean commitAddition = false;
0723:                boolean commitCopy = false;
0724:                if (entry.isScheduledForAddition()
0725:                        || entry.isScheduledForReplacement()) {
0726:                    commitAddition = true;
0727:                    if (entry.getCopyFromURL() != null) {
0728:                        cfURL = entry.getCopyFromURL();
0729:                        addsOnly = false;
0730:                        commitCopy = true;
0731:                    } else {
0732:                        addsOnly = true;
0733:                    }
0734:                }
0735:                if ((entry.isCopied() || copyMode) && !entry.isDeleted()
0736:                        && entry.getSchedule() == null) {
0737:                    long parentRevision = entry.getRevision() - 1;
0738:                    boolean switched = false;
0739:                    if (entry != null && parentEntry != null) {
0740:                        switched = !entry.getURL().equals(
0741:                                SVNPathUtil.append(parentEntry.getURL(),
0742:                                        SVNEncodingUtil.uriEncode(path
0743:                                                .getName())));
0744:                    }
0745:                    if (!switched && !dir.getWCAccess().isWCRoot(path)) {
0746:                        if (parentEntry != null) {
0747:                            parentRevision = parentEntry.getRevision();
0748:                        }
0749:
0750:                    } else if (!copyMode) {
0751:                        SVNErrorMessage err = SVNErrorMessage
0752:                                .create(
0753:                                        SVNErrorCode.WC_CORRUPT,
0754:                                        "Did not expect ''{0}'' to be a working copy root",
0755:                                        path);
0756:                        SVNErrorManager.error(err);
0757:                    }
0758:                    if (parentRevision != entry.getRevision()) {
0759:                        commitAddition = true;
0760:                        commitCopy = true;
0761:                        addsOnly = false;
0762:                        cfRevision = entry.getRevision();
0763:                        if (copyMode) {
0764:                            cfURL = entry.getURL();
0765:                        } else if (copyFromURL != null) {
0766:                            cfURL = copyFromURL;
0767:                        } else {
0768:                            SVNErrorMessage err = SVNErrorMessage
0769:                                    .create(
0770:                                            SVNErrorCode.BAD_URL,
0771:                                            "Commit item ''{0}'' has copy flag but no copyfrom URL",
0772:                                            path);
0773:                            SVNErrorManager.error(err);
0774:                        }
0775:                    }
0776:                }
0777:                boolean textModified = false;
0778:                boolean propsModified = false;
0779:                boolean commitLock;
0780:
0781:                if (commitAddition) {
0782:                    SVNVersionedProperties props = dir.getProperties(entry
0783:                            .getName());
0784:                    SVNVersionedProperties baseProps = dir
0785:                            .getBaseProperties(entry.getName());
0786:                    Map propDiff = null;
0787:                    if (entry.isScheduledForReplacement()) {
0788:                        propDiff = props.asMap();
0789:                    } else {
0790:                        propDiff = baseProps.compareTo(props).asMap();
0791:                    }
0792:                    boolean eolChanged = textModified = propDiff != null
0793:                            && propDiff.containsKey(SVNProperty.EOL_STYLE);
0794:                    if (entry.getKind() == SVNNodeKind.FILE) {
0795:                        if (commitCopy) {
0796:                            textModified = propDiff != null
0797:                                    && propDiff
0798:                                            .containsKey(SVNProperty.EOL_STYLE);
0799:                            if (!textModified) {
0800:                                textModified = dir.hasTextModifications(entry
0801:                                        .getName(), eolChanged);
0802:                            }
0803:                        } else {
0804:                            textModified = true;
0805:                        }
0806:                    }
0807:                    propsModified = propDiff != null && !propDiff.isEmpty();
0808:                } else if (!commitDeletion) {
0809:                    SVNVersionedProperties props = dir.getProperties(entry
0810:                            .getName());
0811:                    SVNVersionedProperties baseProps = dir
0812:                            .getBaseProperties(entry.getName());
0813:                    Map propDiff = baseProps.compareTo(props).asMap();
0814:                    boolean eolChanged = textModified = propDiff != null
0815:                            && propDiff.containsKey(SVNProperty.EOL_STYLE);
0816:                    propsModified = propDiff != null && !propDiff.isEmpty();
0817:                    if (entry.getKind() == SVNNodeKind.FILE) {
0818:                        textModified = dir.hasTextModifications(
0819:                                entry.getName(), eolChanged);
0820:                    }
0821:                }
0822:
0823:                commitLock = entry.getLockToken() != null
0824:                        && (justLocked || textModified || propsModified
0825:                                || commitDeletion || commitAddition || commitCopy);
0826:
0827:                if (commitAddition || commitDeletion || textModified
0828:                        || propsModified || commitCopy || commitLock) {
0829:                    SVNCommitItem item = new SVNCommitItem(path, SVNURL
0830:                            .parseURIEncoded(url), cfURL != null ? SVNURL
0831:                            .parseURIEncoded(cfURL) : null, entry.getKind(),
0832:                            SVNRevision.create(entry.getRevision()),
0833:                            SVNRevision.create(cfRevision), commitAddition,
0834:                            commitDeletion, propsModified, textModified,
0835:                            commitCopy, commitLock);
0836:                    String itemPath = dir.getRelativePath(dir.getWCAccess()
0837:                            .retrieve(dir.getWCAccess().getAnchor()));
0838:                    if ("".equals(itemPath)) {
0839:                        itemPath += entry.getName();
0840:                    } else if (!"".equals(entry.getName())) {
0841:                        itemPath += "/" + entry.getName();
0842:                    }
0843:                    item.setPath(itemPath);
0844:                    commitables.put(path, item);
0845:                    if (lockTokens != null && entry.getLockToken() != null) {
0846:                        lockTokens.put(url, entry.getLockToken());
0847:                    }
0848:                }
0849:                if (entries != null && recursive
0850:                        && (commitAddition || !commitDeletion)) {
0851:                    // recurse.
0852:                    for (Iterator ents = entries.entries(copyMode); ents
0853:                            .hasNext();) {
0854:                        if (dir != null && dir.getWCAccess() != null) {
0855:                            dir.getWCAccess().checkCancelled();
0856:                        }
0857:                        SVNEntry currentEntry = (SVNEntry) ents.next();
0858:                        if ("".equals(currentEntry.getName())) {
0859:                            continue;
0860:                        }
0861:                        // if recursion is forced and entry is explicitly copied, skip it.
0862:                        if (forcedRecursion && currentEntry.isCopied()
0863:                                && currentEntry.getCopyFromURL() != null) {
0864:                            continue;
0865:                        }
0866:                        String currentCFURL = cfURL != null ? cfURL
0867:                                : copyFromURL;
0868:                        if (currentCFURL != null) {
0869:                            currentCFURL = SVNPathUtil.append(currentCFURL,
0870:                                    SVNEncodingUtil.uriEncode(currentEntry
0871:                                            .getName()));
0872:                        }
0873:                        String currentURL = currentEntry.getURL();
0874:                        if (copyMode || entry.getURL() == null) {
0875:                            currentURL = SVNPathUtil.append(url,
0876:                                    SVNEncodingUtil.uriEncode(currentEntry
0877:                                            .getName()));
0878:                        }
0879:                        File currentFile = dir.getFile(currentEntry.getName());
0880:                        SVNAdminArea childDir;
0881:                        if (currentEntry.getKind() == SVNNodeKind.DIR) {
0882:                            try {
0883:                                childDir = dir.getWCAccess().retrieve(
0884:                                        dir.getFile(currentEntry.getName()));
0885:                            } catch (SVNException e) {
0886:                                if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
0887:                                    childDir = null;
0888:                                } else {
0889:                                    throw e;
0890:                                }
0891:                            }
0892:                            if (childDir == null) {
0893:                                SVNFileType currentType = SVNFileType
0894:                                        .getType(currentFile);
0895:                                if (currentType == SVNFileType.NONE
0896:                                        && currentEntry
0897:                                                .isScheduledForDeletion()) {
0898:                                    SVNCommitItem item = new SVNCommitItem(
0899:                                            currentFile,
0900:                                            SVNURL.parseURIEncoded(currentURL),
0901:                                            null, currentEntry.getKind(),
0902:                                            SVNRevision.UNDEFINED,
0903:                                            SVNRevision.UNDEFINED, false, true,
0904:                                            false, false, false, false);
0905:                                    String dirPath = dir.getRelativePath(dir
0906:                                            .getWCAccess().retrieve(
0907:                                                    dir.getWCAccess()
0908:                                                            .getAnchor()));
0909:                                    item.setPath(SVNPathUtil.append(dirPath,
0910:                                            currentEntry.getName()));
0911:                                    commitables.put(currentFile, item);
0912:                                    continue;
0913:                                } else if (currentType != SVNFileType.NONE) {
0914:                                    // directory is not missing, but obstructed, 
0915:                                    // or no special params are specified.
0916:                                    SVNErrorMessage err = SVNErrorMessage
0917:                                            .create(
0918:                                                    SVNErrorCode.WC_NOT_LOCKED,
0919:                                                    "Working copy ''{0}'' is missing or not locked",
0920:                                                    currentFile);
0921:                                    SVNErrorManager.error(err);
0922:                                } else {
0923:                                    ISVNCommitParameters.Action action = params != null ? params
0924:                                            .onMissingDirectory(dir
0925:                                                    .getFile(currentEntry
0926:                                                            .getName()))
0927:                                            : ISVNCommitParameters.ERROR;
0928:                                    if (action == ISVNCommitParameters.DELETE) {
0929:                                        SVNCommitItem item = new SVNCommitItem(
0930:                                                currentFile,
0931:                                                SVNURL
0932:                                                        .parseURIEncoded(currentURL),
0933:                                                null, currentEntry.getKind(),
0934:                                                SVNRevision.UNDEFINED,
0935:                                                SVNRevision.UNDEFINED, false,
0936:                                                true, false, false, false,
0937:                                                false);
0938:                                        String dirPath = dir
0939:                                                .getRelativePath(dir
0940:                                                        .getWCAccess()
0941:                                                        .retrieve(
0942:                                                                dir
0943:                                                                        .getWCAccess()
0944:                                                                        .getAnchor()));
0945:                                        item.setPath(SVNPathUtil
0946:                                                .append(dirPath, currentEntry
0947:                                                        .getName()));
0948:                                        commitables.put(currentFile, item);
0949:                                        currentEntry.scheduleForDeletion();
0950:                                        entries.saveEntries(false);
0951:                                        continue;
0952:                                    } else if (action != ISVNCommitParameters.SKIP) {
0953:                                        SVNErrorMessage err = SVNErrorMessage
0954:                                                .create(
0955:                                                        SVNErrorCode.WC_NOT_LOCKED,
0956:                                                        "Working copy ''{0}'' is missing or not locked",
0957:                                                        currentFile);
0958:                                        SVNErrorManager.error(err);
0959:                                    }
0960:                                }
0961:                            }
0962:                        }
0963:                        harvestCommitables(commitables, dir, currentFile,
0964:                                entry, currentEntry, currentURL, currentCFURL,
0965:                                copyMode, addsOnly, justLocked, lockTokens,
0966:                                true, forcedRecursion, params);
0967:
0968:                    }
0969:                }
0970:                if (lockTokens != null && entry.getKind() == SVNNodeKind.DIR
0971:                        && commitDeletion) {
0972:                    // harvest lock tokens for deleted items.
0973:                    collectLocks(dir, lockTokens);
0974:                }
0975:            }
0976:
0977:            private static void collectLocks(SVNAdminArea adminArea,
0978:                    Map lockTokens) throws SVNException {
0979:                for (Iterator ents = adminArea.entries(false); ents.hasNext();) {
0980:                    SVNEntry entry = (SVNEntry) ents.next();
0981:                    if (entry.getURL() != null && entry.getLockToken() != null) {
0982:                        lockTokens.put(entry.getURL(), entry.getLockToken());
0983:                    }
0984:                    if (!adminArea.getThisDirName().equals(entry.getName())
0985:                            && entry.isDirectory()) {
0986:
0987:                        SVNAdminArea child;
0988:                        try {
0989:                            child = adminArea.getWCAccess().retrieve(
0990:                                    adminArea.getFile(entry.getName()));
0991:                        } catch (SVNException e) {
0992:                            if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
0993:                                child = null;
0994:                            } else {
0995:                                throw e;
0996:                            }
0997:                        }
0998:                        if (child != null) {
0999:                            collectLocks(child, lockTokens);
1000:                        }
1001:                    }
1002:                }
1003:                adminArea.closeEntries();
1004:            }
1005:
1006:            private static void removeRedundantPaths(
1007:                    Collection dirsToLockRecursively, Collection dirsToLock) {
1008:                for (Iterator paths = dirsToLock.iterator(); paths.hasNext();) {
1009:                    String path = (String) paths.next();
1010:                    if (dirsToLockRecursively.contains(path)) {
1011:                        paths.remove();
1012:                    } else {
1013:                        for (Iterator recPaths = dirsToLockRecursively
1014:                                .iterator(); recPaths.hasNext();) {
1015:                            String existingPath = (String) recPaths.next();
1016:                            if (path.startsWith(existingPath + "/")) {
1017:                                paths.remove();
1018:                                break;
1019:                            }
1020:                        }
1021:                    }
1022:                }
1023:            }
1024:
1025:            private static File adjustRelativePaths(File rootFile,
1026:                    Collection relativePaths) throws SVNException {
1027:                if (relativePaths.contains("")) {
1028:                    String targetName = getTargetName(rootFile);
1029:                    if (!"".equals(targetName)
1030:                            && rootFile.getParentFile() != null) {
1031:                        // there is a versioned parent.
1032:                        rootFile = rootFile.getParentFile();
1033:                        List result = new ArrayList();
1034:                        for (Iterator paths = relativePaths.iterator(); paths
1035:                                .hasNext();) {
1036:                            String path = (String) paths.next();
1037:                            path = "".equals(path) ? targetName : SVNPathUtil
1038:                                    .append(targetName, path);
1039:                            if (!result.contains(path)) {
1040:                                result.add(path);
1041:                            }
1042:                        }
1043:                        relativePaths.clear();
1044:                        Collections.sort(result);
1045:                        relativePaths.addAll(result);
1046:                    }
1047:                }
1048:                return rootFile;
1049:            }
1050:
1051:            private static String getTargetName(File file) throws SVNException {
1052:                SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
1053:                try {
1054:                    wcAccess.probeOpen(file, false, 0);
1055:                    SVNFileType fileType = SVNFileType.getType(file);
1056:                    if ((fileType == SVNFileType.FILE || fileType == SVNFileType.SYMLINK)
1057:                            || !wcAccess.isWCRoot(file)) {
1058:                        return file.getName();
1059:                    }
1060:                } finally {
1061:                    wcAccess.close();
1062:                }
1063:                return "";
1064:            }
1065:
1066:            private static boolean isRecursiveCommitForced(File directory)
1067:                    throws SVNException {
1068:                SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
1069:                try {
1070:                    wcAccess.open(directory, false, 0);
1071:                    SVNEntry targetEntry = wcAccess.getEntry(directory, false);
1072:                    if (targetEntry != null) {
1073:                        return targetEntry.isCopied()
1074:                                || targetEntry.isScheduledForDeletion()
1075:                                || targetEntry.isScheduledForReplacement();
1076:                    }
1077:                } finally {
1078:                    wcAccess.close();
1079:                }
1080:                return false;
1081:            }
1082:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.