Source Code Cross Referenced for SVNMoveClient.java in  » Source-Control » tmatesoft-SVN » org » tmatesoft » svn » core » 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.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.wc;
0013:
0014:        import java.io.File;
0015:        import java.util.Iterator;
0016:
0017:        import org.tmatesoft.svn.core.SVNErrorCode;
0018:        import org.tmatesoft.svn.core.SVNErrorMessage;
0019:        import org.tmatesoft.svn.core.SVNException;
0020:        import org.tmatesoft.svn.core.SVNNodeKind;
0021:        import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
0022:        import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
0023:        import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
0024:        import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
0025:        import org.tmatesoft.svn.core.internal.wc.SVNFileType;
0026:        import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
0027:        import org.tmatesoft.svn.core.internal.wc.admin.SVNAdminArea;
0028:        import org.tmatesoft.svn.core.internal.wc.admin.SVNEntry;
0029:        import org.tmatesoft.svn.core.internal.wc.admin.SVNLog;
0030:        import org.tmatesoft.svn.core.internal.wc.admin.SVNVersionedProperties;
0031:        import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess;
0032:
0033:        /**
0034:         * The <b>SVNMoveClient</b> provides an extra client-side functionality over
0035:         * standard (i.e. compatible with the SVN command line client) move 
0036:         * operations. This class helps to overcome the SVN limitations regarding
0037:         * move operations. Using <b>SVNMoveClient</b> you can easily:
0038:         * <ul>
0039:         * <li>move versioned items to other versioned ones  
0040:         * within the same Working Copy, what even allows to replace items 
0041:         * scheduled for deletion, or those that are missing but are still under
0042:         * version control and have a node kind different from the node kind of the 
0043:         * source (!);  
0044:         * <li>move versioned items belonging to one Working Copy to versioned items
0045:         * that belong to absolutely different Working Copy; 
0046:         * <li>move versioned items to unversioned ones;
0047:         * <li>move unversioned items to versioned ones;
0048:         * <li>move unversioned items to unversioned ones;
0049:         * <li>revert any of the kinds of moving listed above;
0050:         * <li>complete a copy/move operation for a file, that is if you have
0051:         * manually copied/moved a versioned file to an unversioned file in a Working
0052:         * copy, you can run a 'virtual' copy/move on these files to copy/move
0053:         * all the necessary administrative version control information.
0054:         * </ul>
0055:         * 
0056:         * @version 1.1.1
0057:         * @author  TMate Software Ltd.
0058:         */
0059:        public class SVNMoveClient extends SVNBasicClient {
0060:
0061:            private SVNWCClient myWCClient;
0062:
0063:            /**
0064:             * Constructs and initializes an <b>SVNMoveClient</b> object
0065:             * with the specified run-time configuration and authentication 
0066:             * drivers.
0067:             * 
0068:             * <p>
0069:             * If <code>options</code> is <span class="javakeyword">null</span>,
0070:             * then this <b>SVNMoveClient</b> will be using a default run-time
0071:             * configuration driver  which takes client-side settings from the 
0072:             * default SVN's run-time configuration area but is not able to
0073:             * change those settings (read more on {@link ISVNOptions} and {@link SVNWCUtil}).  
0074:             * 
0075:             * <p>
0076:             * If <code>authManager</code> is <span class="javakeyword">null</span>,
0077:             * then this <b>SVNMoveClient</b> will be using a default authentication
0078:             * and network layers driver (see {@link SVNWCUtil#createDefaultAuthenticationManager()})
0079:             * which uses server-side settings and auth storage from the 
0080:             * default SVN's run-time configuration area (or system properties
0081:             * if that area is not found).
0082:             * 
0083:             * @param authManager an authentication and network layers driver
0084:             * @param options     a run-time configuration options driver     
0085:             */
0086:            public SVNMoveClient(ISVNAuthenticationManager authManager,
0087:                    ISVNOptions options) {
0088:                super (authManager, options);
0089:                myWCClient = new SVNWCClient(authManager, options);
0090:            }
0091:
0092:            public SVNMoveClient(ISVNRepositoryPool repositoryPool,
0093:                    ISVNOptions options) {
0094:                super (repositoryPool, options);
0095:                myWCClient = new SVNWCClient(repositoryPool, options);
0096:            }
0097:
0098:            /**
0099:             * Moves a source item to a destination one. 
0100:             * 
0101:             * <p>
0102:             * <code>dst</code> should not exist. Furher it's considered to be versioned if
0103:             * its parent directory is under version control, otherwise <code>dst</code>
0104:             * is considered to be unversioned.
0105:             * 
0106:             * <p>
0107:             * If both <code>src</code> and <code>dst</code> are unversioned, then simply 
0108:             * moves <code>src</code> to <code>dst</code> in the filesystem.
0109:             *
0110:             * <p>
0111:             * If <code>src</code> is versioned but <code>dst</code> is not, then 
0112:             * exports <code>src</code> to <code>dst</code> in the filesystem and
0113:             * removes <code>src</code> from version control.
0114:             * 
0115:             * <p>
0116:             * If <code>dst</code> is versioned but <code>src</code> is not, then 
0117:             * moves <code>src</code> to <code>dst</code> (even if <code>dst</code>
0118:             * is scheduled for deletion).
0119:             * 
0120:             * <p>
0121:             * If both <code>src</code> and <code>dst</code> are versioned and located
0122:             * within the same Working Copy, then moves <code>src</code> to 
0123:             * <code>dst</code> (even if <code>dst</code> is scheduled for deletion),
0124:             * or tries to replace <code>dst</code> with <code>src</code> if the former
0125:             * is missing and has a node kind different from the node kind of the source.
0126:             * If <code>src</code> is scheduled for addition with history, 
0127:             * <code>dst</code> will be set the same ancestor URL and revision from which
0128:             * the source was copied. If <code>src</code> and <code>dst</code> are located in 
0129:             * different Working Copies, then this method copies <code>src</code> to 
0130:             * <code>dst</code>, tries to put the latter under version control and 
0131:             * finally removes <code>src</code>.
0132:             *  
0133:             * @param  src            a source path
0134:             * @param  dst            a destination path
0135:             * @throws SVNException   if one of the following is true:
0136:             *                        <ul>
0137:             *                        <li><code>dst</code> already exists
0138:             *                        <li><code>src</code> does not exist
0139:             *                        </ul>
0140:             */
0141:            public void doMove(File src, File dst) throws SVNException {
0142:                if (dst.exists()) {
0143:                    SVNErrorMessage err = SVNErrorMessage.create(
0144:                            SVNErrorCode.ENTRY_EXISTS,
0145:                            "File ''{0}'' already exists", dst);
0146:                    SVNErrorManager.error(err);
0147:                } else if (!src.exists()) {
0148:                    SVNErrorMessage err = SVNErrorMessage.create(
0149:                            SVNErrorCode.NODE_UNKNOWN_KIND,
0150:                            "Path ''{0}'' does not exist", src);
0151:                    SVNErrorManager.error(err);
0152:                }
0153:                // src considered as unversioned when it is not versioned
0154:                boolean srcIsVersioned = isVersionedFile(src);
0155:                // dst is considered as unversioned when its parent is not versioned.
0156:                boolean dstParentIsVersioned = isVersionedFile(dst
0157:                        .getParentFile());
0158:
0159:                if (!srcIsVersioned && !dstParentIsVersioned) {
0160:                    // world:world
0161:                    SVNFileUtil.rename(src, dst);
0162:                } else if (!dstParentIsVersioned) {
0163:                    // wc:world
0164:                    // 1. export to world
0165:                    SVNFileUtil.copy(src, dst, false, false);
0166:
0167:                    // 2. delete in wc.
0168:                    myWCClient.doDelete(src, true, false);
0169:                } else if (!srcIsVersioned) {
0170:                    // world:wc (add, if dst is 'deleted' it will be replaced)
0171:                    SVNFileUtil.rename(src, dst);
0172:                    // do we have to add it if it was unversioned?
0173:                    //myWCClient.doAdd(dst, false, false, false, true, false);
0174:                } else {
0175:                    // wc:wc.
0176:
0177:                    SVNWCAccess wcAccess = createWCAccess();
0178:                    File srcParent = src.getParentFile();
0179:                    File dstParent = dst.getParentFile();
0180:                    SVNAdminArea srcParentArea = null;
0181:                    SVNAdminArea dstParentArea = null;
0182:                    try {
0183:                        if (srcParent.equals(dstParent)) {
0184:                            wcAccess.closeAdminArea(srcParent);
0185:                            srcParentArea = dstParentArea = wcAccess.open(
0186:                                    srcParent, true, 0);
0187:                        } else {
0188:                            srcParentArea = wcAccess.open(srcParent, false, 0);
0189:                            dstParentArea = wcAccess.open(dstParent, true, 0);
0190:                        }
0191:
0192:                        SVNEntry srcEntry = srcParentArea.getEntry(src
0193:                                .getName(), true);
0194:                        SVNEntry dstEntry = dstParentArea.getEntry(dst
0195:                                .getName(), true);
0196:
0197:                        File srcWCRoot = SVNWCUtil
0198:                                .getWorkingCopyRoot(src, true);
0199:                        File dstWCRoot = SVNWCUtil
0200:                                .getWorkingCopyRoot(dst, true);
0201:                        boolean sameWC = srcWCRoot != null
0202:                                && srcWCRoot.equals(dstWCRoot);
0203:                        if (sameWC
0204:                                && dstEntry != null
0205:                                && (dstEntry.isScheduledForDeletion() || dstEntry
0206:                                        .getKind() != srcEntry.getKind())) {
0207:                            wcAccess.close();
0208:                            if (srcEntry.getKind() == dstEntry.getKind()
0209:                                    && srcEntry.getSchedule() == null
0210:                                    && srcEntry.isFile()) {
0211:                                // make normal move to keep history (R+).
0212:                                SVNCopyClient copyClient = new SVNCopyClient(
0213:                                        (ISVNAuthenticationManager) null, null);
0214:                                copyClient.doCopy(src, SVNRevision.WORKING,
0215:                                        dst, true, true);
0216:                                return;
0217:                            }
0218:                            // attempt replace.
0219:                            SVNFileUtil.copy(src, dst, false, false);
0220:                            try {
0221:                                myWCClient.doAdd(dst, false, false, false,
0222:                                        true, false);
0223:                            } catch (SVNException e) {
0224:                                // will be thrown on obstruction.
0225:                            }
0226:                            myWCClient.doDelete(src, true, false);
0227:                            return;
0228:                        }
0229:
0230:                        // 2. do manual copy of the file or directory
0231:                        SVNFileUtil.copy(src, dst, false, sameWC);
0232:
0233:                        // 3. update dst dir and dst entry in parent.
0234:                        if (!sameWC) {
0235:                            // just add dst (at least try to add, files already there).
0236:                            wcAccess.close();
0237:                            try {
0238:                                myWCClient.doAdd(dst, false, false, false,
0239:                                        true, false);
0240:                            } catch (SVNException e) {
0241:                                // obstruction
0242:                            }
0243:                        } else if (srcEntry.isFile()) {
0244:
0245:                            if (dstEntry == null) {
0246:                                dstEntry = dstParentArea
0247:                                        .addEntry(dst.getName());
0248:                            }
0249:
0250:                            String srcURL = srcEntry.getURL();
0251:                            String srcCFURL = srcEntry.getCopyFromURL();
0252:                            long srcRevision = srcEntry.getRevision();
0253:                            long srcCFRevision = srcEntry.getCopyFromRevision();
0254:                            // copy props!
0255:                            SVNVersionedProperties srcProps = srcParentArea
0256:                                    .getProperties(src.getName());
0257:                            SVNVersionedProperties dstProps = dstParentArea
0258:                                    .getProperties(dst.getName());
0259:                            srcProps.copyTo(dstProps);
0260:                            File srcBaseFile = srcParentArea.getBaseFile(src
0261:                                    .getName(), false);
0262:                            File dstBaseFile = dstParentArea.getBaseFile(dst
0263:                                    .getName(), false);
0264:                            if (srcBaseFile.isFile()) {
0265:                                SVNFileUtil.copy(srcBaseFile, dstBaseFile,
0266:                                        false, false);
0267:                            }
0268:
0269:                            if (srcEntry.isScheduledForAddition()
0270:                                    && srcEntry.isCopied()) {
0271:                                dstEntry.scheduleForAddition();
0272:                                dstEntry.setCopyFromRevision(srcCFRevision);
0273:                                dstEntry.setCopyFromURL(srcCFURL);
0274:                                dstEntry.setKind(SVNNodeKind.FILE);
0275:                                dstEntry.setRevision(srcRevision);
0276:                                dstEntry.setCopied(true);
0277:                            } else if (!srcEntry.isCopied()
0278:                                    && !srcEntry.isScheduledForAddition()) {
0279:                                dstEntry.setCopied(true);
0280:                                dstEntry.scheduleForAddition();
0281:                                dstEntry.setKind(SVNNodeKind.FILE);
0282:                                dstEntry.setCopyFromRevision(srcRevision);
0283:                                dstEntry.setCopyFromURL(srcURL);
0284:                            } else {
0285:                                dstEntry.scheduleForAddition();
0286:                                dstEntry.setKind(SVNNodeKind.FILE);
0287:                                if (!dstEntry.isScheduledForReplacement()) {
0288:                                    dstEntry.setRevision(0);
0289:                                }
0290:                            }
0291:
0292:                            SVNLog log = dstParentArea.getLog();
0293:                            dstParentArea.saveEntries(false);
0294:                            dstParentArea.saveVersionedProperties(log, true);
0295:                            log.save();
0296:                            dstParentArea.runLogs();
0297:                        } else if (srcEntry.isDirectory()) {
0298:                            SVNAdminArea srcArea = wcAccess.open(src, false, 0);
0299:                            srcEntry = srcArea.getEntry(srcArea
0300:                                    .getThisDirName(), false);
0301:                            if (dstEntry == null) {
0302:                                dstEntry = dstParentArea
0303:                                        .addEntry(dst.getName());
0304:                            }
0305:                            SVNAdminArea dstArea = wcAccess.open(dst, true,
0306:                                    SVNWCAccess.INFINITE_DEPTH);
0307:
0308:                            SVNVersionedProperties srcProps = srcArea
0309:                                    .getProperties(srcArea.getThisDirName());
0310:                            SVNVersionedProperties dstProps = dstArea
0311:                                    .getProperties(dstArea.getThisDirName());
0312:
0313:                            SVNEntry dstParentEntry = dstParentArea.getEntry(
0314:                                    dstParentArea.getThisDirName(), false);
0315:                            String srcURL = srcEntry.getURL();
0316:                            String srcCFURL = srcEntry.getCopyFromURL();
0317:                            String dstURL = dstParentEntry.getURL();
0318:                            String repositoryRootURL = dstParentEntry
0319:                                    .getRepositoryRoot();
0320:                            long srcRevision = srcEntry.getRevision();
0321:                            long srcCFRevision = srcEntry.getCopyFromRevision();
0322:
0323:                            dstURL = SVNPathUtil.append(dstURL, SVNEncodingUtil
0324:                                    .uriEncode(dst.getName()));
0325:                            if (srcEntry.isScheduledForAddition()
0326:                                    && srcEntry.isCopied()) {
0327:                                srcProps.copyTo(dstProps);
0328:                                dstEntry.scheduleForAddition();
0329:                                dstEntry.setKind(SVNNodeKind.DIR);
0330:                                dstEntry.setCopied(true);
0331:                                dstEntry.setCopyFromRevision(srcCFRevision);
0332:                                dstEntry.setCopyFromURL(srcCFURL);
0333:
0334:                                SVNEntry dstThisEntry = dstArea.getEntry(
0335:                                        dstArea.getThisDirName(), false);
0336:                                dstThisEntry.scheduleForAddition();
0337:                                dstThisEntry.setKind(SVNNodeKind.DIR);
0338:                                dstThisEntry.setCopyFromRevision(srcCFRevision);
0339:                                dstThisEntry.setCopyFromURL(srcCFURL);
0340:                                dstThisEntry.setRevision(srcRevision);
0341:                                dstThisEntry.setCopied(true);
0342:
0343:                                SVNLog log = dstArea.getLog();
0344:                                dstArea.saveVersionedProperties(log, true);
0345:                                dstParentArea.saveEntries(false);
0346:                                log.save();
0347:                                dstArea.runLogs();
0348:
0349:                                // update URL in children.
0350:                                dstArea.updateURL(dstURL, true);
0351:                                dstParentArea.saveEntries(true);
0352:                            } else if (!srcEntry.isCopied()
0353:                                    && !srcEntry.isScheduledForAddition()) {
0354:                                // versioned (deleted, replaced, or normal).
0355:                                srcProps.copyTo(dstProps);
0356:                                dstEntry.scheduleForAddition();
0357:                                dstEntry.setKind(SVNNodeKind.DIR);
0358:                                dstEntry.setCopied(true);
0359:                                dstEntry.setCopyFromRevision(srcRevision);
0360:                                dstEntry.setCopyFromURL(srcURL);
0361:
0362:                                // update URL, CF-URL and CF-REV in children.
0363:                                SVNEntry dstThisEntry = dstArea.getEntry(
0364:                                        dstArea.getThisDirName(), false);
0365:                                dstThisEntry.scheduleForAddition();
0366:                                dstThisEntry.setKind(SVNNodeKind.DIR);
0367:                                dstThisEntry.setCopied(true);
0368:                                dstThisEntry.scheduleForAddition();
0369:                                dstThisEntry.setKind(SVNNodeKind.DIR);
0370:                                dstThisEntry.setCopyFromRevision(srcRevision);
0371:                                dstThisEntry.setCopyFromURL(srcURL);
0372:                                dstThisEntry.setURL(dstURL);
0373:                                dstThisEntry
0374:                                        .setRepositoryRoot(repositoryRootURL);
0375:
0376:                                SVNLog log = dstArea.getLog();
0377:                                dstArea.saveVersionedProperties(log, true);
0378:                                dstArea.saveEntries(false);
0379:                                log.save();
0380:                                dstArea.runLogs();
0381:
0382:                                updateCopiedDirectory(dstArea, dstArea
0383:                                        .getThisDirName(), dstURL,
0384:                                        repositoryRootURL, null, -1);
0385:                                dstArea.saveEntries(true);
0386:                                dstParentArea.saveEntries(true);
0387:
0388:                            } else {
0389:                                // unversioned entry (copied or added)
0390:                                dstParentArea.deleteEntry(dst.getName());
0391:                                dstParentArea.saveEntries(true);
0392:                                SVNFileUtil.deleteAll(dst, this );
0393:                                SVNFileUtil.copy(src, dst, false, false);
0394:                                wcAccess.close();
0395:                                myWCClient.doAdd(dst, false, false, false,
0396:                                        true, false);
0397:                            }
0398:                        }
0399:                        // now delete src (if it is not the same as dst :))
0400:                        try {
0401:                            wcAccess.close();
0402:                            myWCClient.doDelete(src, true, false);
0403:                        } catch (SVNException e) {
0404:                            //
0405:                        }
0406:                    } finally {
0407:                        wcAccess.close();
0408:                    }
0409:                }
0410:            }
0411:
0412:            private void updateCopiedDirectory(SVNAdminArea dir, String name,
0413:                    String newURL, String reposRootURL, String copyFromURL,
0414:                    long copyFromRevision) throws SVNException {
0415:                SVNWCAccess wcAccess = dir.getWCAccess();
0416:                SVNEntry entry = dir.getEntry(name, true);
0417:                if (entry != null) {
0418:                    entry.setCopied(true);
0419:                    if (newURL != null) {
0420:                        entry.setURL(newURL);
0421:                    }
0422:                    entry.setRepositoryRoot(reposRootURL);
0423:                    if (entry.isFile()) {
0424:                        if (dir.getWCProperties(name) != null) {
0425:                            dir.getWCProperties(name).removeAll();
0426:                            dir.saveWCProperties(false);
0427:                        }
0428:                        if (copyFromURL != null) {
0429:                            entry.setCopyFromURL(copyFromURL);
0430:                            entry.setCopyFromRevision(copyFromRevision);
0431:                        }
0432:                    }
0433:                    boolean deleted = false;
0434:                    if (entry.isDeleted() && newURL != null) {
0435:                        // convert to scheduled for deletion.
0436:                        deleted = true;
0437:                        entry.setDeleted(false);
0438:                        entry.scheduleForDeletion();
0439:                        if (entry.isDirectory()) {
0440:                            entry.setKind(SVNNodeKind.FILE);
0441:                        }
0442:                    }
0443:                    if (entry.getLockToken() != null && newURL != null) {
0444:                        entry.setLockToken(null);
0445:                        entry.setLockOwner(null);
0446:                        entry.setLockComment(null);
0447:                        entry.setLockCreationDate(null);
0448:                    }
0449:                    if (!dir.getThisDirName().equals(name)
0450:                            && entry.isDirectory() && !deleted) {
0451:                        SVNAdminArea childDir = wcAccess.retrieve(dir
0452:                                .getFile(name));
0453:                        if (childDir != null) {
0454:                            String childCopyFromURL = copyFromURL == null ? null
0455:                                    : SVNPathUtil.append(copyFromURL,
0456:                                            SVNEncodingUtil.uriEncode(entry
0457:                                                    .getName()));
0458:                            updateCopiedDirectory(childDir, childDir
0459:                                    .getThisDirName(), newURL, reposRootURL,
0460:                                    childCopyFromURL, copyFromRevision);
0461:                        }
0462:                    } else if (dir.getThisDirName().equals(name)) {
0463:                        dir.getWCProperties(dir.getThisDirName()).removeAll();
0464:                        dir.saveWCProperties(false);
0465:                        if (copyFromURL != null) {
0466:                            entry.setCopyFromURL(copyFromURL);
0467:                            entry.setCopyFromRevision(copyFromRevision);
0468:                        }
0469:                        for (Iterator ents = dir.entries(true); ents.hasNext();) {
0470:                            SVNEntry childEntry = (SVNEntry) ents.next();
0471:                            if (dir.getThisDirName().equals(
0472:                                    childEntry.getName())) {
0473:                                continue;
0474:                            }
0475:                            String childCopyFromURL = copyFromURL == null ? null
0476:                                    : SVNPathUtil.append(copyFromURL,
0477:                                            SVNEncodingUtil
0478:                                                    .uriEncode(childEntry
0479:                                                            .getName()));
0480:                            String newChildURL = newURL == null ? null
0481:                                    : SVNPathUtil.append(newURL,
0482:                                            SVNEncodingUtil
0483:                                                    .uriEncode(childEntry
0484:                                                            .getName()));
0485:                            updateCopiedDirectory(dir, childEntry.getName(),
0486:                                    newChildURL, reposRootURL,
0487:                                    childCopyFromURL, copyFromRevision);
0488:                        }
0489:                        dir.saveEntries(false);
0490:                    }
0491:                }
0492:            }
0493:
0494:            /**
0495:             * Reverts a previous move operation back. Provided in pair with {@link #doMove(File, File) doMove()} 
0496:             * and used to roll back move operations. In this case <code>src</code> is
0497:             * considered to be the target of the previsous move operation, and <code>dst</code>
0498:             * is regarded to be the source of that same operation which have been moved
0499:             * to <code>src</code> and now is to be restored. 
0500:             * 
0501:             * <p>
0502:             * <code>dst</code> could exist in that case if it has been a WC directory
0503:             * that was scheduled for deletion during the previous move operation. Furher 
0504:             * <code>dst</code> is considered to be versioned if its parent directory is 
0505:             * under version control, otherwise <code>dst</code> is considered to be unversioned.
0506:             * 
0507:             * <p>
0508:             * If both <code>src</code> and <code>dst</code> are unversioned, then simply 
0509:             * moves <code>src</code> back to <code>dst</code> in the filesystem.
0510:             *
0511:             * <p>
0512:             * If <code>src</code> is versioned but <code>dst</code> is not, then 
0513:             * unmoves <code>src</code> to <code>dst</code> in the filesystem and
0514:             * removes <code>src</code> from version control.
0515:             * 
0516:             * <p>
0517:             * If <code>dst</code> is versioned but <code>src</code> is not, then 
0518:             * first tries to make a revert on <code>dst</code> - if it has not been committed
0519:             * yet, it will be simply reverted. However in the case <code>dst</code> has been already removed 
0520:             * from the repository, <code>src</code> will be copied back to <code>dst</code>
0521:             * and scheduled for addition. Then <code>src</code> is removed from the filesystem.
0522:             * 
0523:             * <p>
0524:             * If both <code>src</code> and <code>dst</code> are versioned then the 
0525:             * following situations are possible:
0526:             * <ul>
0527:             * <li>If <code>dst</code> is still scheduled for deletion, then it is
0528:             * reverted back and <code>src</code> is scheduled for deletion.
0529:             * <li>in the case if <code>dst</code> exists but is not scheduled for 
0530:             * deletion, <code>src</code> is cleanly exported to <code>dst</code> and
0531:             * removed from version control.
0532:             * <li>if <code>dst</code> and <code>src</code> are from different repositories
0533:             * (appear to be in different Working Copies), then <code>src</code> is copied
0534:             * to <code>dst</code> (with scheduling <code>dst</code> for addition, but not
0535:             * with history since copying is made in the filesystem only) and removed from
0536:             * version control.
0537:             * <li>if both <code>dst</code> and <code>src</code> are in the same 
0538:             * repository (appear to be located in the same Working Copy) and: 
0539:             *    <ul style="list-style-type: lower-alpha">
0540:             *    <li>if <code>src</code> is scheduled for addition with history, then
0541:             *    copies <code>src</code> to <code>dst</code> specifying the source
0542:             *    ancestor's URL and revision (i.e. the ancestor of the source is the
0543:             *    ancestor of the destination);
0544:             *    <li>if <code>src</code> is already under version control, then
0545:             *    copies <code>src</code> to <code>dst</code> specifying the source
0546:             *    URL and revision as the ancestor (i.e. <code>src</code> itself is the
0547:             *    ancestor of <code>dst</code>);
0548:             *    <li>if <code>src</code> is just scheduled for addition (without history),
0549:             *    then simply copies <code>src</code> to <code>dst</code> (only in the filesystem,
0550:             *    without history) and schedules <code>dst</code> for addition;  
0551:             *    </ul>
0552:             * then <code>src</code> is removed from version control.
0553:             * </ul>
0554:             * 
0555:             * @param  src            a source path
0556:             * @param  dst            a destination path
0557:             * @throws SVNException   if <code>src</code> does not exist
0558:             * 
0559:             */
0560:            // move that considered as move undo.
0561:            public void undoMove(File src, File dst) throws SVNException {
0562:                // dst could exists, if it is deleted directory.
0563:                if (!src.exists()) {
0564:                    SVNErrorMessage err = SVNErrorMessage.create(
0565:                            SVNErrorCode.NODE_UNKNOWN_KIND,
0566:                            "Path ''{0}'' does not exist", src);
0567:                    SVNErrorManager.error(err);
0568:                }
0569:                // src considered as unversioned when it is not versioned
0570:                boolean srcIsVersioned = isVersionedFile(src);
0571:                // dst is considered as unversioned when its parent is not versioned.
0572:                boolean dstParentIsVersioned = isVersionedFile(dst
0573:                        .getParentFile());
0574:
0575:                if (!srcIsVersioned && !dstParentIsVersioned) {
0576:                    // world:world
0577:                    SVNFileUtil.rename(src, dst);
0578:                } else if (!dstParentIsVersioned) {
0579:                    // wc:world
0580:                    // 1. export to world
0581:                    SVNFileUtil.copy(src, dst, false, false);
0582:
0583:                    // 2. delete in wc.
0584:                    myWCClient.doDelete(src, true, false);
0585:                } else if (!srcIsVersioned) {
0586:                    // world:wc (add, if dst is 'deleted' it will be replaced)
0587:                    SVNFileUtil.rename(src, dst);
0588:                    // dst should probably be deleted, in this case - revert it
0589:                    SVNWCAccess dstAccess = createWCAccess();
0590:                    boolean revert = false;
0591:                    try {
0592:                        dstAccess.probeOpen(dst, false, 0);
0593:                        SVNEntry dstEntry = dstAccess.getEntry(dst, false);
0594:                        revert = dstEntry != null
0595:                                && dstEntry.isScheduledForDeletion();
0596:                    } catch (SVNException e) {
0597:                    } finally {
0598:                        dstAccess.close();
0599:                    }
0600:                    if (revert) {
0601:                        myWCClient.doRevert(dst, true);
0602:                    } else {
0603:                        // should we do this? there is no old source, may be rename is enough.
0604:                        //                myWCClient.doAdd(dst, false, false, false, true, false);
0605:                    }
0606:                } else {
0607:                    // wc:wc.
0608:                    SVNWCAccess wcAccess = createWCAccess();
0609:                    File srcParent = src.getParentFile();
0610:                    File dstParent = dst.getParentFile();
0611:                    SVNAdminArea srcParentArea = null;
0612:                    SVNAdminArea dstParentArea = null;
0613:                    try {
0614:                        if (srcParent.equals(dstParent)) {
0615:                            wcAccess.closeAdminArea(srcParent);
0616:                            srcParentArea = dstParentArea = wcAccess.open(
0617:                                    srcParent, true, 0);
0618:                        } else {
0619:                            srcParentArea = wcAccess.open(srcParent, false, 0);
0620:                            dstParentArea = wcAccess.open(dstParent, true, 0);
0621:                        }
0622:
0623:                        SVNEntry srcEntry = srcParentArea.getEntry(src
0624:                                .getName(), true);
0625:                        SVNEntry dstEntry = dstParentArea.getEntry(dst
0626:                                .getName(), true);
0627:                        if (dstEntry != null
0628:                                && dstEntry.isScheduledForDeletion()) {
0629:                            wcAccess.close();
0630:                            // clear undo.
0631:                            myWCClient.doRevert(dst, true);
0632:                            myWCClient.doDelete(src, true, false);
0633:                            return;
0634:                        }
0635:                        SVNEntry dstParentEntry = wcAccess.getEntry(dstParent,
0636:                                false);
0637:
0638:                        File srcWCRoot = SVNWCUtil
0639:                                .getWorkingCopyRoot(src, true);
0640:                        File dstWCRoot = SVNWCUtil
0641:                                .getWorkingCopyRoot(dst, true);
0642:                        boolean sameWC = srcWCRoot != null
0643:                                && srcWCRoot.equals(dstWCRoot);
0644:
0645:                        SVNFileUtil.copy(src, dst, false, sameWC);
0646:
0647:                        // obstruction assertion.
0648:                        if (dstEntry != null
0649:                                && dstEntry.getKind() != srcEntry.getKind()) {
0650:                            // ops have no sence->target is obstructed, just export src to
0651:                            // dst and delete src.
0652:                            wcAccess.close();
0653:                            myWCClient.doDelete(src, true, false);
0654:                            return;
0655:                        }
0656:                        if (!sameWC) {
0657:                            // just add dst (at least try to add, files already there).
0658:                            wcAccess.close();
0659:                            try {
0660:                                myWCClient.doAdd(dst, false, false, false,
0661:                                        true, false);
0662:                            } catch (SVNException e) {
0663:                                // obstruction
0664:                            }
0665:                        } else if (srcEntry.isFile()) {
0666:                            if (dstEntry == null) {
0667:                                dstEntry = dstParentArea
0668:                                        .addEntry(dst.getName());
0669:                            }
0670:
0671:                            String srcURL = srcEntry.getURL();
0672:                            String srcCFURL = srcEntry.getCopyFromURL();
0673:                            long srcRevision = srcEntry.getRevision();
0674:                            long srcCFRevision = srcEntry.getCopyFromRevision();
0675:
0676:                            if (srcEntry.isScheduledForAddition()
0677:                                    && srcEntry.isCopied()) {
0678:                                dstEntry.scheduleForAddition();
0679:                                dstEntry.setCopyFromRevision(srcCFRevision);
0680:                                dstEntry.setCopyFromURL(srcCFURL);
0681:                                dstEntry.setKind(SVNNodeKind.FILE);
0682:                                dstEntry.setRevision(srcRevision);
0683:                                dstEntry.setCopied(true);
0684:                            } else if (!srcEntry.isCopied()
0685:                                    && !srcEntry.isScheduledForAddition()) {
0686:                                dstEntry.setCopied(true);
0687:                                dstEntry.scheduleForAddition();
0688:                                dstEntry.setKind(SVNNodeKind.FILE);
0689:                                dstEntry.setCopyFromRevision(srcRevision);
0690:                                dstEntry.setCopyFromURL(srcURL);
0691:                            } else {
0692:                                dstEntry.scheduleForAddition();
0693:                                dstEntry.setKind(SVNNodeKind.FILE);
0694:                                if (!dstEntry.isScheduledForReplacement()) {
0695:                                    dstEntry.setRevision(0);
0696:                                }
0697:                            }
0698:                            dstParentArea.saveEntries(false);
0699:                        } else if (srcEntry.isDirectory()) {
0700:                            SVNAdminArea srcArea = wcAccess.open(src, false, 0);
0701:                            srcEntry = srcArea.getEntry(srcArea
0702:                                    .getThisDirName(), false);
0703:                            if (dstEntry == null) {
0704:                                dstEntry = dstParentArea
0705:                                        .addEntry(dst.getName());
0706:                            }
0707:
0708:                            String srcURL = srcEntry.getURL();
0709:                            String dstURL = dstParentEntry.getURL();
0710:                            long srcRevision = srcEntry.getRevision();
0711:                            String repositoryRootURL = srcEntry
0712:                                    .getRepositoryRoot();
0713:
0714:                            dstURL = SVNPathUtil.append(dstURL, SVNEncodingUtil
0715:                                    .uriEncode(dst.getName()));
0716:
0717:                            SVNAdminArea dstArea = wcAccess.open(dst, true,
0718:                                    SVNWCAccess.INFINITE_DEPTH);
0719:
0720:                            if (srcEntry.isScheduledForAddition()
0721:                                    && srcEntry.isCopied()) {
0722:                                dstEntry.scheduleForAddition();
0723:                                dstEntry.setKind(SVNNodeKind.DIR);
0724:                                dstParentArea.saveEntries(true);
0725:                                // update URL in children.
0726:                                dstArea.updateURL(dstURL, true);
0727:                                dstArea.saveEntries(true);
0728:                            } else if (!srcEntry.isCopied()
0729:                                    && !srcEntry.isScheduledForAddition()) {
0730:                                dstEntry.setCopied(true);
0731:                                dstEntry.scheduleForAddition();
0732:                                dstEntry.setKind(SVNNodeKind.DIR);
0733:                                dstEntry.setCopyFromRevision(srcRevision);
0734:                                dstEntry.setCopyFromURL(srcURL);
0735:
0736:                                dstParentArea.saveEntries(true);
0737:
0738:                                SVNEntry dstThisEntry = dstArea.getEntry(
0739:                                        dstArea.getThisDirName(), false);
0740:                                dstThisEntry.setCopied(true);
0741:                                dstThisEntry.scheduleForAddition();
0742:                                dstThisEntry.setKind(SVNNodeKind.DIR);
0743:                                dstThisEntry.setCopyFromRevision(srcRevision);
0744:                                dstThisEntry.setURL(dstURL);
0745:                                dstThisEntry.setCopyFromURL(srcURL);
0746:                                dstThisEntry
0747:                                        .setRepositoryRoot(repositoryRootURL);
0748:
0749:                                updateCopiedDirectory(dstArea, dstArea
0750:                                        .getThisDirName(), dstURL,
0751:                                        repositoryRootURL, null, -1);
0752:                                dstArea.saveEntries(true);
0753:                            } else {
0754:                                // replay
0755:                                dstParentArea.deleteEntry(dst.getName());
0756:                                dstParentArea.saveEntries(true);
0757:                                wcAccess.close();
0758:                                SVNFileUtil.deleteAll(dst, this );
0759:                                SVNFileUtil.copy(src, dst, false, false);
0760:                                myWCClient.doAdd(dst, false, false, false,
0761:                                        true, false);
0762:                            }
0763:                        }
0764:                        // now delete src.
0765:                        try {
0766:                            wcAccess.close();
0767:                            myWCClient.doDelete(src, true, false);
0768:                        } catch (SVNException e) {
0769:                            //
0770:                        }
0771:                    } finally {
0772:                        wcAccess.close();
0773:                    }
0774:                }
0775:            }
0776:
0777:            /**
0778:             * Copies/moves administrative version control information of a source file 
0779:             * to administrative information of a destination file.
0780:             * For example, if you have manually copied/moved a source file to a target one 
0781:             * (manually means just in the filesystem, not using version control operations) and then
0782:             * would like to turn this copying/moving into a complete version control copy
0783:             * or move operation, use this method that will finish all the work for you - it
0784:             * will copy/move all the necessary administrative information (kept in the source
0785:             * <i>.svn</i> directory) to the target <i>.svn</i> directory. 
0786:             * 
0787:             * <p>
0788:             * In that case when you have your files copied/moved in the filesystem, you
0789:             * can not perform standard (version control) copying/moving - since the target already exists and
0790:             * the source may be already deleted. Use this method to overcome that restriction.  
0791:             * 
0792:             * @param  src           a source file path (was copied/moved to <code>dst</code>)
0793:             * @param  dst           a destination file path
0794:             * @param  move          if <span class="javakeyword">true</span> then
0795:             *                       completes moving <code>src</code> to <code>dst</code>,
0796:             *                       otherwise completes copying <code>src</code> to <code>dst</code>
0797:             * @throws SVNException  if one of the following is true:
0798:             *                       <ul>
0799:             *                       <li><code>move = </code><span class="javakeyword">true</span> and <code>src</code>
0800:             *                       still exists
0801:             *                       <li><code>dst</code> does not exist
0802:             *                       <li><code>dst</code> is a directory 
0803:             *                       <li><code>src</code> is a directory
0804:             *                       <li><code>src</code> is not under version control
0805:             *                       <li><code>dst</code> is already under version control
0806:             *                       <li>if <code>src</code> is copied but not scheduled for
0807:             *                       addition, and SVNKit is not able to locate the copied
0808:             *                       directory root for <code>src</code>
0809:             *                       </ul>
0810:             */
0811:            public void doVirtualCopy(File src, File dst, boolean move)
0812:                    throws SVNException {
0813:                SVNFileType srcType = SVNFileType.getType(src);
0814:                SVNFileType dstType = SVNFileType.getType(dst);
0815:
0816:                String opName = move ? "move" : "copy";
0817:                if (move && srcType != SVNFileType.NONE) {
0818:                    SVNErrorMessage err = SVNErrorMessage
0819:                            .create(
0820:                                    SVNErrorCode.ENTRY_EXISTS,
0821:                                    "Cannot perform 'virtual' {0}: ''{1}'' still exists",
0822:                                    new Object[] { opName, src });
0823:                    SVNErrorManager.error(err);
0824:                }
0825:                if (dstType == SVNFileType.NONE) {
0826:                    SVNErrorMessage err = SVNErrorMessage
0827:                            .create(
0828:                                    SVNErrorCode.ENTRY_NOT_FOUND,
0829:                                    "Cannot perform 'virtual' {0}: ''{1}'' does not exist",
0830:                                    new Object[] { opName, dst });
0831:                    SVNErrorManager.error(err);
0832:                }
0833:                if (dstType == SVNFileType.DIRECTORY) {
0834:                    SVNErrorMessage err = SVNErrorMessage
0835:                            .create(
0836:                                    SVNErrorCode.ILLEGAL_TARGET,
0837:                                    "Cannot perform 'virtual' {0}: ''{1}'' is a directory",
0838:                                    new Object[] { opName, dst });
0839:                    SVNErrorManager.error(err);
0840:                }
0841:                if (!move && srcType == SVNFileType.DIRECTORY) {
0842:                    SVNErrorMessage err = SVNErrorMessage
0843:                            .create(
0844:                                    SVNErrorCode.ILLEGAL_TARGET,
0845:                                    "Cannot perform 'virtual' {0}: ''{1}'' is a directory",
0846:                                    new Object[] { opName, src });
0847:                    SVNErrorManager.error(err);
0848:                }
0849:
0850:                SVNWCAccess dstAccess = createWCAccess();
0851:                try {
0852:                    dstAccess.probeOpen(dst, false, 0);
0853:                    SVNEntry dstEntry = dstAccess.getEntry(dst, false);
0854:                    if (dstEntry != null) {
0855:                        SVNErrorMessage err = SVNErrorMessage
0856:                                .create(
0857:                                        SVNErrorCode.ENTRY_EXISTS,
0858:                                        "''{0}'' is already under version control",
0859:                                        dst);
0860:                        SVNErrorManager.error(err);
0861:                    }
0862:                } finally {
0863:                    dstAccess.close();
0864:                }
0865:
0866:                SVNWCAccess srcAccess = createWCAccess();
0867:                String cfURL = null;
0868:                boolean added = false;
0869:                long cfRevision = -1;
0870:                try {
0871:                    srcAccess.probeOpen(src, false, 0);
0872:                    SVNEntry srcEntry = srcAccess.getEntry(src, false);
0873:                    if (srcEntry == null) {
0874:                        SVNErrorMessage err = SVNErrorMessage.create(
0875:                                SVNErrorCode.ENTRY_NOT_FOUND,
0876:                                "''{0}'' is not under version control", src);
0877:                        SVNErrorManager.error(err);
0878:                    }
0879:                    if (srcEntry.isCopied()
0880:                            && !srcEntry.isScheduledForAddition()) {
0881:                        cfURL = getCopyFromURL(src.getParentFile(),
0882:                                SVNEncodingUtil.uriEncode(src.getName()));
0883:                        cfRevision = getCopyFromRevision(src.getParentFile());
0884:                        if (cfURL == null || cfRevision < 0) {
0885:                            SVNErrorMessage err = SVNErrorMessage
0886:                                    .create(
0887:                                            SVNErrorCode.ENTRY_NOT_FOUND,
0888:                                            "Cannot locate copied directory root for ''{0}''",
0889:                                            src);
0890:                            SVNErrorManager.error(err);
0891:                        }
0892:                        added = false;
0893:                    } else {
0894:                        cfURL = srcEntry.isCopied() ? srcEntry.getCopyFromURL()
0895:                                : srcEntry.getURL();
0896:                        cfRevision = srcEntry.isCopied() ? srcEntry
0897:                                .getCopyFromRevision() : srcEntry.getRevision();
0898:                        added = srcEntry.isScheduledForAddition()
0899:                                && !srcEntry.isCopied();
0900:                    }
0901:                } finally {
0902:                    srcAccess.close();
0903:                }
0904:                if (move) {
0905:                    myWCClient.doDelete(src, true, false);
0906:                }
0907:                if (added) {
0908:                    myWCClient.doAdd(dst, true, false, false, false, false);
0909:                    return;
0910:                }
0911:
0912:                dstAccess = createWCAccess();
0913:                srcAccess = createWCAccess();
0914:                try {
0915:                    SVNAdminArea dstArea = dstAccess.probeOpen(dst, true, 0);
0916:                    SVNEntry dstEntry = dstAccess.getEntry(dst, false);
0917:                    if (dstEntry != null) {
0918:                        SVNErrorMessage err = SVNErrorMessage
0919:                                .create(
0920:                                        SVNErrorCode.ENTRY_EXISTS,
0921:                                        "''{0}'' is already under version control",
0922:                                        dst);
0923:                        SVNErrorManager.error(err);
0924:                    }
0925:
0926:                    SVNAdminArea srcArea = srcAccess.probeOpen(src, false, 0);
0927:                    SVNVersionedProperties srcProps = srcArea.getProperties(src
0928:                            .getName());
0929:                    SVNVersionedProperties dstProps = dstArea.getProperties(dst
0930:                            .getName());
0931:
0932:                    srcProps.copyTo(dstProps);
0933:
0934:                    dstEntry = dstArea.addEntry(dst.getName());
0935:                    dstEntry.setCopyFromURL(cfURL);
0936:                    dstEntry.setCopyFromRevision(cfRevision);
0937:                    dstEntry.setCopied(true);
0938:                    dstEntry.setKind(SVNNodeKind.FILE);
0939:                    dstEntry.scheduleForAddition();
0940:
0941:                    dstArea.saveEntries(false);
0942:                    SVNLog log = dstArea.getLog();
0943:                    dstArea.saveVersionedProperties(log, true);
0944:                    log.save();
0945:                    dstArea.runLogs();
0946:                } finally {
0947:                    srcAccess.close();
0948:                    dstAccess.close();
0949:                }
0950:
0951:            }
0952:
0953:            private static boolean isVersionedFile(File file) {
0954:                SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
0955:                try {
0956:                    SVNAdminArea area = wcAccess.probeOpen(file, false, 0);
0957:                    if (area.getEntry(area.getThisDirName(), false) == null) {
0958:                        return false;
0959:                    }
0960:                    SVNFileType type = SVNFileType.getType(file);
0961:                    if (type.isFile() || type == SVNFileType.NONE) {
0962:                        // file or missing file
0963:                        return area.getEntry(file.getName(), false) != null;
0964:                    } else if (type != SVNFileType.NONE
0965:                            && !area.getRoot().equals(file)) {
0966:                        // directory, but not anchor. always considered unversioned.
0967:                        return false;
0968:                    }
0969:                    return true;
0970:                } catch (SVNException e) {
0971:                    return false;
0972:                } finally {
0973:                    try {
0974:                        wcAccess.close();
0975:                    } catch (SVNException svne) {
0976:                        //
0977:                    }
0978:                }
0979:            }
0980:
0981:            private String getCopyFromURL(File path, String urlTail)
0982:                    throws SVNException {
0983:                if (path == null) {
0984:                    return null;
0985:                }
0986:                SVNWCAccess wcAccess = createWCAccess();
0987:                try {
0988:                    wcAccess.probeOpen(path, false, 0);
0989:                } catch (SVNException e) {
0990:                    wcAccess.close();
0991:                    return null;
0992:                }
0993:                // urlTail is either name of an entry
0994:                try {
0995:                    SVNEntry entry = wcAccess.getEntry(path, false);
0996:                    if (entry == null) {
0997:                        return null;
0998:                    }
0999:                    String cfURL = entry.getCopyFromURL();
1000:                    if (cfURL != null) {
1001:                        return SVNPathUtil.append(cfURL, urlTail);
1002:                    }
1003:                    urlTail = SVNPathUtil.append(SVNEncodingUtil.uriEncode(path
1004:                            .getName()), urlTail);
1005:                    path = path.getParentFile();
1006:                    return getCopyFromURL(path, urlTail);
1007:                } finally {
1008:                    wcAccess.close();
1009:                }
1010:            }
1011:
1012:            private long getCopyFromRevision(File path) throws SVNException {
1013:                if (path == null) {
1014:                    return -1;
1015:                }
1016:                SVNWCAccess wcAccess = createWCAccess();
1017:                try {
1018:                    wcAccess.probeOpen(path, false, 0);
1019:                } catch (SVNException e) {
1020:                    wcAccess.close();
1021:                    return -1;
1022:                }
1023:                try {
1024:                    SVNEntry entry = wcAccess.getEntry(path, false);
1025:                    if (entry == null) {
1026:                        return -1;
1027:                    }
1028:                    long rev = entry.getCopyFromRevision();
1029:                    if (rev >= 0) {
1030:                        return rev;
1031:                    }
1032:                    path = path.getParentFile();
1033:                    return getCopyFromRevision(path);
1034:                } finally {
1035:                    wcAccess.close();
1036:                }
1037:            }
1038:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.