Source Code Cross Referenced for SVNBasicClient.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) 


001:        /*
002:         * ====================================================================
003:         * Copyright (c) 2004-2008 TMate Software Ltd.  All rights reserved.
004:         *
005:         * This software is licensed as described in the file COPYING, which
006:         * you should have received as part of this distribution.  The terms
007:         * are also available at http://svnkit.com/license.html
008:         * If newer versions of this license are posted there, you may use a
009:         * newer version instead, at your option.
010:         * ====================================================================
011:         */
012:        package org.tmatesoft.svn.core.wc;
013:
014:        import java.io.File;
015:        import java.util.ArrayList;
016:        import java.util.Collections;
017:        import java.util.HashMap;
018:        import java.util.Iterator;
019:        import java.util.LinkedList;
020:        import java.util.List;
021:        import java.util.Map;
022:
023:        import org.tmatesoft.svn.core.ISVNLogEntryHandler;
024:        import org.tmatesoft.svn.core.SVNCancelException;
025:        import org.tmatesoft.svn.core.SVNErrorCode;
026:        import org.tmatesoft.svn.core.SVNErrorMessage;
027:        import org.tmatesoft.svn.core.SVNException;
028:        import org.tmatesoft.svn.core.SVNLogEntry;
029:        import org.tmatesoft.svn.core.SVNLogEntryPath;
030:        import org.tmatesoft.svn.core.SVNNodeKind;
031:        import org.tmatesoft.svn.core.SVNURL;
032:        import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
033:        import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
034:        import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
035:        import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
036:        import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
037:        import org.tmatesoft.svn.core.internal.wc.admin.SVNEntry;
038:        import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess;
039:        import org.tmatesoft.svn.core.io.SVNLocationEntry;
040:        import org.tmatesoft.svn.core.io.SVNRepository;
041:        import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
042:        import org.tmatesoft.svn.util.ISVNDebugLog;
043:        import org.tmatesoft.svn.util.SVNDebugLog;
044:
045:        /**
046:         * The <b>SVNBasicClient</b> is the base class of all 
047:         * <b>SVN</b>*<b>Client</b> classes that provides a common interface
048:         * and realization.
049:         * 
050:         * <p>
051:         * All of <b>SVN</b>*<b>Client</b> classes use inherited methods of
052:         * <b>SVNBasicClient</b> to access Working Copies metadata, to create 
053:         * a driver object to access a repository if it's necessary, etc. In addition
054:         * <b>SVNBasicClient</b> provides some interface methods  - such as those
055:         * that allow you to set your {@link ISVNEventHandler event handler}, 
056:         * obtain run-time configuration options, and others. 
057:         * 
058:         * @version 1.1.1
059:         * @author  TMate Software Ltd.
060:         */
061:        public class SVNBasicClient implements  ISVNEventHandler {
062:
063:            private ISVNRepositoryPool myRepositoryPool;
064:            private ISVNOptions myOptions;
065:            private ISVNEventHandler myEventDispatcher;
066:            private List myPathPrefixesStack;
067:            private boolean myIsIgnoreExternals;
068:            private boolean myIsLeaveConflictsUnresolved;
069:            private ISVNDebugLog myDebugLog;
070:
071:            protected SVNBasicClient(
072:                    final ISVNAuthenticationManager authManager,
073:                    ISVNOptions options) {
074:                this (new DefaultSVNRepositoryPool(
075:                        authManager == null ? SVNWCUtil
076:                                .createDefaultAuthenticationManager()
077:                                : authManager, options, 0, false), options);
078:            }
079:
080:            protected SVNBasicClient(ISVNRepositoryPool repositoryPool,
081:                    ISVNOptions options) {
082:                myRepositoryPool = repositoryPool;
083:                setOptions(options);
084:                myPathPrefixesStack = new LinkedList();
085:            }
086:
087:            /**
088:             * Gets a run-time configuration area driver used by this object.
089:             * 
090:             * @return the run-time options driver being in use
091:             */
092:            public ISVNOptions getOptions() {
093:                return myOptions;
094:            }
095:
096:            public void setOptions(ISVNOptions options) {
097:                myOptions = options;
098:                if (myOptions == null) {
099:                    myOptions = SVNWCUtil.createDefaultOptions(true);
100:                }
101:            }
102:
103:            /**
104:             * Sets externals definitions to be ignored or not during
105:             * operations.
106:             * 
107:             * <p>
108:             * For example, if external definitions are set to be ignored
109:             * then a checkout operation won't fetch them into a Working Copy.
110:             * 
111:             * @param ignore  <span class="javakeyword">true</span> to ignore
112:             *                externals definitions, <span class="javakeyword">false</span> - 
113:             *                not to
114:             * @see           #isIgnoreExternals()
115:             */
116:            public void setIgnoreExternals(boolean ignore) {
117:                myIsIgnoreExternals = ignore;
118:            }
119:
120:            /**
121:             * Determines if externals definitions are ignored.
122:             * 
123:             * @return <span class="javakeyword">true</span> if ignored,
124:             *         otherwise <span class="javakeyword">false</span>
125:             * @see    #setIgnoreExternals(boolean)
126:             */
127:            public boolean isIgnoreExternals() {
128:                return myIsIgnoreExternals;
129:            }
130:
131:            /**
132:             * Sets (or unsets) all conflicted working files to be untouched
133:             * by update and merge operations.
134:             * 
135:             * <p>
136:             * By default when a file receives changes from the repository 
137:             * that are in conflict with local edits, an update operation places
138:             * two sections for each conflicting snatch into the working file 
139:             * one of which is a user's local edit and the second is the one just 
140:             * received from the repository. Like this:
141:             * <pre class="javacode">
142:             * <<<<<<< .mine
143:             * user's text
144:             * =======
145:             * received text
146:             * >>>>>>> .r2</pre><br /> 
147:             * Also the operation creates three temporary files that appear in the 
148:             * same directory as the working file. Now if you call this method with 
149:             * <code>leave</code> set to <span class="javakeyword">true</span>,
150:             * an update will still create temporary files but won't place those two
151:             * sections into your working file. And this behaviour also concerns
152:             * merge operations: any merging to a conflicted file will be prevented. 
153:             * In addition if there is any registered event
154:             * handler for an <b>SVNDiffClient</b> or <b>SVNUpdateClient</b> 
155:             * instance then the handler will be dispatched an event with 
156:             * the status type set to {@link SVNStatusType#CONFLICTED_UNRESOLVED}. 
157:             * 
158:             * <p>
159:             * The default value is <span class="javakeyword">false</span> until
160:             * a caller explicitly changes it calling this method. 
161:             * 
162:             * @param leave  <span class="javakeyword">true</span> to prevent 
163:             *               conflicted files from merging (all merging operations 
164:             *               will be skipped), otherwise <span class="javakeyword">false</span>
165:             * @see          #isLeaveConflictsUnresolved()              
166:             * @see          SVNUpdateClient
167:             * @see          SVNDiffClient
168:             * @see          ISVNEventHandler
169:             */
170:            public void setLeaveConflictsUnresolved(boolean leave) {
171:                myIsLeaveConflictsUnresolved = leave;
172:            }
173:
174:            /**
175:             * Determines if conflicted files should be left unresolved
176:             * preventing from merging their contents during update and merge 
177:             * operations.
178:             *  
179:             * @return  <span class="javakeyword">true</span> if conflicted files
180:             *          are set to be prevented from merging, <span class="javakeyword">false</span>
181:             *          if there's no such restriction
182:             * @see     #setLeaveConflictsUnresolved(boolean) 
183:             */
184:            public boolean isLeaveConflictsUnresolved() {
185:                return myIsLeaveConflictsUnresolved;
186:            }
187:
188:            /**
189:             * Sets an event handler for this object. This event handler
190:             * will be dispatched {@link SVNEvent} objects to provide 
191:             * detailed information about actions and progress state 
192:             * of version control operations performed by <b>do</b>*<b>()</b>
193:             * methods of <b>SVN</b>*<b>Client</b> classes.
194:             * 
195:             * @param dispatcher an event handler
196:             */
197:            public void setEventHandler(ISVNEventHandler dispatcher) {
198:                myEventDispatcher = dispatcher;
199:            }
200:
201:            /**
202:             * Sets a logger to write debug log information to.
203:             * 
204:             * @param log a debug logger
205:             */
206:            public void setDebugLog(ISVNDebugLog log) {
207:                myDebugLog = log;
208:            }
209:
210:            /**
211:             * Returns the debug logger currently in use.  
212:             * 
213:             * <p>
214:             * If no debug logger has been specified by the time this call occurs, 
215:             * a default one (returned by <code>org.tmatesoft.svn.util.SVNDebugLog.getDefaultLog()</code>) 
216:             * will be created and used.
217:             * 
218:             * @return a debug logger
219:             */
220:            public ISVNDebugLog getDebugLog() {
221:                if (myDebugLog == null) {
222:                    return SVNDebugLog.getDefaultLog();
223:                }
224:                return myDebugLog;
225:            }
226:
227:            protected void sleepForTimeStamp() {
228:                if (myPathPrefixesStack == null
229:                        || myPathPrefixesStack.isEmpty()) {
230:                    SVNFileUtil.sleepForTimestamp();
231:                }
232:            }
233:
234:            protected SVNRepository createRepository(SVNURL url,
235:                    boolean mayReuse) throws SVNException {
236:                SVNRepository repository = null;
237:                if (myRepositoryPool == null) {
238:                    repository = SVNRepositoryFactory.create(url, null);
239:                } else {
240:                    repository = myRepositoryPool.createRepository(url,
241:                            mayReuse);
242:                }
243:                repository.setDebugLog(getDebugLog());
244:                repository.setCanceller(getEventDispatcher());
245:                return repository;
246:            }
247:
248:            protected ISVNRepositoryPool getRepositoryPool() {
249:                return myRepositoryPool;
250:            }
251:
252:            protected void dispatchEvent(SVNEvent event) throws SVNException {
253:                dispatchEvent(event, ISVNEventHandler.UNKNOWN);
254:
255:            }
256:
257:            protected void dispatchEvent(SVNEvent event, double progress)
258:                    throws SVNException {
259:                if (myEventDispatcher != null) {
260:                    String path = "";
261:                    if (!myPathPrefixesStack.isEmpty()) {
262:                        for (Iterator paths = myPathPrefixesStack.iterator(); paths
263:                                .hasNext();) {
264:                            String segment = (String) paths.next();
265:                            path = SVNPathUtil.append(path, segment);
266:                        }
267:                    }
268:                    if (path != null && !"".equals(path)) {
269:                        path = SVNPathUtil.append(path, event.getPath());
270:                        event.setPath(path);
271:                    }
272:                    try {
273:                        myEventDispatcher.handleEvent(event, progress);
274:                    } catch (SVNException e) {
275:                        throw e;
276:                    } catch (Throwable th) {
277:                        SVNErrorMessage err = SVNErrorMessage.create(
278:                                SVNErrorCode.UNKNOWN,
279:                                "Error while dispatching event: {0}", th
280:                                        .getMessage());
281:                        SVNErrorManager.error(err, th);
282:                    }
283:                }
284:            }
285:
286:            /**
287:             * Removes or adds a path prefix. This method is not intended for 
288:             * users (from an API point of view). 
289:             * 
290:             * @param prefix a path prefix
291:             */
292:            public void setEventPathPrefix(String prefix) {
293:                if (prefix == null && !myPathPrefixesStack.isEmpty()) {
294:                    myPathPrefixesStack.remove(myPathPrefixesStack.size() - 1);
295:                } else if (prefix != null) {
296:                    myPathPrefixesStack.add(prefix);
297:                }
298:            }
299:
300:            protected ISVNEventHandler getEventDispatcher() {
301:                return myEventDispatcher;
302:            }
303:
304:            protected SVNWCAccess createWCAccess() {
305:                return createWCAccess((String) null);
306:            }
307:
308:            protected SVNWCAccess createWCAccess(final String pathPrefix) {
309:                ISVNEventHandler eventHandler = null;
310:                if (pathPrefix != null) {
311:                    eventHandler = new ISVNEventHandler() {
312:                        public void handleEvent(SVNEvent event, double progress)
313:                                throws SVNException {
314:                            String fullPath = SVNPathUtil.append(pathPrefix,
315:                                    event.getPath());
316:                            event.setPath(fullPath);
317:                            dispatchEvent(event, progress);
318:                        }
319:
320:                        public void checkCancelled() throws SVNCancelException {
321:                            SVNBasicClient.this .checkCancelled();
322:                        }
323:                    };
324:                } else {
325:                    eventHandler = this ;
326:                }
327:                SVNWCAccess access = SVNWCAccess.newInstance(eventHandler);
328:                access.setOptions(myOptions);
329:                return access;
330:            }
331:
332:            /**
333:             * Dispatches events to the registered event handler (if any). 
334:             * 
335:             * @param event       the current event
336:             * @param progress    progress state (from 0 to 1)
337:             * @throws SVNException
338:             */
339:            public void handleEvent(SVNEvent event, double progress)
340:                    throws SVNException {
341:                dispatchEvent(event, progress);
342:            }
343:
344:            /**
345:             * Redirects this call to the registered event handler (if any).
346:             * 
347:             * @throws SVNCancelException  if the current operation
348:             *                             was cancelled
349:             */
350:            public void checkCancelled() throws SVNCancelException {
351:                if (myEventDispatcher != null) {
352:                    myEventDispatcher.checkCancelled();
353:                }
354:            }
355:
356:            protected long getRevisionNumber(SVNRevision revision,
357:                    SVNRepository repository, File path) throws SVNException {
358:                if (repository == null
359:                        && (revision == SVNRevision.HEAD || revision.getDate() != null)) {
360:                    SVNErrorMessage err = SVNErrorMessage
361:                            .create(SVNErrorCode.CLIENT_RA_ACCESS_REQUIRED);
362:                    SVNErrorManager.error(err);
363:                }
364:                if (revision.getNumber() >= 0) {
365:                    return revision.getNumber();
366:                } else if (revision.getDate() != null) {
367:                    return repository.getDatedRevision(revision.getDate());
368:                } else if (revision == SVNRevision.HEAD) {
369:                    return repository.getLatestRevision();
370:                } else if (!revision.isValid()) {
371:                    return -1;
372:                } else if (revision == SVNRevision.COMMITTED
373:                        || revision == SVNRevision.WORKING
374:                        || revision == SVNRevision.BASE
375:                        || revision == SVNRevision.PREVIOUS) {
376:                    if (path == null) {
377:                        SVNErrorMessage err = SVNErrorMessage
378:                                .create(SVNErrorCode.CLIENT_VERSIONED_PATH_REQUIRED);
379:                        SVNErrorManager.error(err);
380:                    }
381:                    SVNWCAccess wcAccess = createWCAccess();
382:                    wcAccess.probeOpen(path, false, 0);
383:                    SVNEntry entry = wcAccess.getEntry(path, false);
384:                    wcAccess.close();
385:
386:                    if (entry == null) {
387:                        SVNErrorMessage err = SVNErrorMessage.create(
388:                                SVNErrorCode.UNVERSIONED_RESOURCE,
389:                                "''{0}'' is not under version control", path);
390:                        SVNErrorManager.error(err);
391:                    }
392:                    if (revision == SVNRevision.WORKING
393:                            || revision == SVNRevision.BASE) {
394:                        return entry.getRevision();
395:                    }
396:                    if (entry.getCommittedRevision() < 0) {
397:                        SVNErrorMessage err = SVNErrorMessage.create(
398:                                SVNErrorCode.CLIENT_BAD_REVISION,
399:                                "Path ''{0}'' has no committed revision", path);
400:                        SVNErrorManager.error(err);
401:                    }
402:                    return revision == SVNRevision.PREVIOUS ? entry
403:                            .getCommittedRevision() - 1 : entry
404:                            .getCommittedRevision();
405:                } else {
406:                    SVNErrorMessage err = SVNErrorMessage.create(
407:                            SVNErrorCode.CLIENT_BAD_REVISION,
408:                            "Unrecognized revision type requested for ''{0}''",
409:                            path != null ? path : (Object) repository
410:                                    .getLocation());
411:                    SVNErrorManager.error(err);
412:                }
413:                return -1;
414:            }
415:
416:            protected SVNRepository createRepository(SVNURL url, File path,
417:                    SVNRevision pegRevision, SVNRevision revision)
418:                    throws SVNException {
419:                return createRepository(url, path, pegRevision, revision, null);
420:            }
421:
422:            protected SVNRepository createRepository(SVNURL url, File path,
423:                    SVNRevision pegRevision, SVNRevision revision, long[] pegRev)
424:                    throws SVNException {
425:                if (url == null) {
426:                    SVNURL pathURL = getURL(path);
427:                    if (pathURL == null) {
428:                        SVNErrorMessage err = SVNErrorMessage.create(
429:                                SVNErrorCode.ENTRY_MISSING_URL,
430:                                "''{0}'' has no URL", path);
431:                        SVNErrorManager.error(err);
432:                    }
433:                }
434:                if (!revision.isValid() && pegRevision.isValid()) {
435:                    revision = pegRevision;
436:                }
437:                SVNRevision startRevision = SVNRevision.UNDEFINED;
438:                if (path == null) {
439:                    if (!revision.isValid()) {
440:                        startRevision = SVNRevision.HEAD;
441:                    } else {
442:                        startRevision = revision;
443:                    }
444:                    if (!pegRevision.isValid()) {
445:                        pegRevision = SVNRevision.HEAD;
446:                    }
447:                } else {
448:                    if (!revision.isValid()) {
449:                        startRevision = SVNRevision.BASE;
450:                    } else {
451:                        startRevision = revision;
452:                    }
453:                    if (!pegRevision.isValid()) {
454:                        pegRevision = SVNRevision.WORKING;
455:                    }
456:                }
457:                //        SVNRepository repository = createRepository(initialURL, true);
458:
459:                SVNRepositoryLocation[] locations = getLocations(url, path,
460:                        null, pegRevision, startRevision, SVNRevision.UNDEFINED);
461:                url = locations[0].getURL();
462:                long actualRevision = locations[0].getRevisionNumber();
463:                SVNRepository repository = createRepository(url, true);
464:                actualRevision = getRevisionNumber(SVNRevision
465:                        .create(actualRevision), repository, path);
466:                if (actualRevision < 0) {
467:                    actualRevision = repository.getLatestRevision();
468:                }
469:                if (pegRev != null && pegRev.length > 0) {
470:                    pegRev[0] = actualRevision;
471:                }
472:                return repository;
473:            }
474:
475:            protected SVNRepositoryLocation[] getLocations(SVNURL url,
476:                    File path, SVNRepository repository, SVNRevision revision,
477:                    SVNRevision start, SVNRevision end) throws SVNException {
478:                if (!revision.isValid() || !start.isValid()) {
479:                    SVNErrorManager.error(SVNErrorMessage
480:                            .create(SVNErrorCode.CLIENT_BAD_REVISION));
481:                }
482:                long pegRevisionNumber = -1;
483:                long startRevisionNumber;
484:                long endRevisionNumber;
485:
486:                if (path != null) {
487:                    SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
488:                    try {
489:                        wcAccess.openAnchor(path, false, 0);
490:                        SVNEntry entry = wcAccess.getEntry(path, false);
491:                        if (entry.getCopyFromURL() != null
492:                                && revision == SVNRevision.WORKING) {
493:                            url = entry.getCopyFromSVNURL();
494:                            pegRevisionNumber = entry.getCopyFromRevision();
495:                        } else if (entry.getURL() != null) {
496:                            url = entry.getSVNURL();
497:                        } else {
498:                            SVNErrorMessage err = SVNErrorMessage.create(
499:                                    SVNErrorCode.ENTRY_MISSING_URL,
500:                                    "''{0}'' has no URL", path);
501:                            SVNErrorManager.error(err);
502:                        }
503:                    } finally {
504:                        wcAccess.close();
505:                    }
506:                }
507:                if (repository == null) {
508:                    repository = createRepository(url, true);
509:                }
510:                if (pegRevisionNumber < 0) {
511:                    pegRevisionNumber = getRevisionNumber(revision, repository,
512:                            path);
513:                }
514:                if (revision == start && revision == SVNRevision.HEAD) {
515:                    startRevisionNumber = pegRevisionNumber;
516:                } else {
517:                    startRevisionNumber = getRevisionNumber(start, repository,
518:                            path);
519:                }
520:                if (!end.isValid()) {
521:                    endRevisionNumber = startRevisionNumber;
522:                } else {
523:                    endRevisionNumber = getRevisionNumber(end, repository, path);
524:                }
525:                if (endRevisionNumber == pegRevisionNumber
526:                        && startRevisionNumber == pegRevisionNumber) {
527:                    SVNRepositoryLocation[] result = new SVNRepositoryLocation[2];
528:                    result[0] = new SVNRepositoryLocation(url,
529:                            startRevisionNumber);
530:                    result[1] = new SVNRepositoryLocation(url,
531:                            endRevisionNumber);
532:                    return result;
533:                }
534:                SVNURL rootURL = repository.getRepositoryRoot(true);
535:                long[] revisionsRange = startRevisionNumber == endRevisionNumber ? new long[] { startRevisionNumber }
536:                        : new long[] { startRevisionNumber, endRevisionNumber };
537:
538:                Map locations = null;
539:                try {
540:                    locations = repository.getLocations("", (Map) null,
541:                            pegRevisionNumber, revisionsRange);
542:                } catch (SVNException e) {
543:                    if (e.getErrorMessage() != null
544:                            && e.getErrorMessage().getErrorCode() == SVNErrorCode.RA_NOT_IMPLEMENTED) {
545:                        locations = getLocations10(repository,
546:                                pegRevisionNumber, startRevisionNumber,
547:                                endRevisionNumber);
548:                    } else {
549:                        throw e;
550:                    }
551:                }
552:                // try to get locations with 'log' method.
553:                SVNLocationEntry startPath = (SVNLocationEntry) locations
554:                        .get(new Long(startRevisionNumber));
555:                SVNLocationEntry endPath = (SVNLocationEntry) locations
556:                        .get(new Long(endRevisionNumber));
557:
558:                if (startPath == null) {
559:                    Object source = path != null ? (Object) path : (Object) url;
560:                    SVNErrorMessage err = SVNErrorMessage
561:                            .create(
562:                                    SVNErrorCode.CLIENT_UNRELATED_RESOURCES,
563:                                    "Unable to find repository location for ''{0}'' in revision ''{1}''",
564:                                    new Object[] { source,
565:                                            new Long(startRevisionNumber) });
566:                    SVNErrorManager.error(err);
567:                }
568:                if (endPath == null) {
569:                    Object source = path != null ? (Object) path : (Object) url;
570:                    SVNErrorMessage err = SVNErrorMessage
571:                            .create(
572:                                    SVNErrorCode.CLIENT_UNRELATED_RESOURCES,
573:                                    "The location for ''{0}'' for revision {1} does not exist in the "
574:                                            + "repository or refers to an unrelated object",
575:                                    new Object[] { source,
576:                                            new Long(endRevisionNumber) });
577:                    SVNErrorManager.error(err);
578:                }
579:
580:                SVNRepositoryLocation[] result = new SVNRepositoryLocation[2];
581:                SVNURL startURL = SVNURL.parseURIEncoded(SVNPathUtil.append(
582:                        rootURL.toString(), SVNEncodingUtil.uriEncode(startPath
583:                                .getPath())));
584:                result[0] = new SVNRepositoryLocation(startURL,
585:                        startRevisionNumber);
586:                if (end.isValid()) {
587:                    SVNURL endURL = SVNURL.parseURIEncoded(SVNPathUtil.append(
588:                            rootURL.toString(), SVNEncodingUtil
589:                                    .uriEncode(endPath.getPath())));
590:                    result[1] = new SVNRepositoryLocation(endURL,
591:                            endRevisionNumber);
592:                }
593:                return result;
594:            }
595:
596:            private Map getLocations10(SVNRepository repos,
597:                    final long pegRevision, final long startRevision,
598:                    final long endRevision) throws SVNException {
599:                final String path = repos.getRepositoryPath("");
600:                final SVNNodeKind kind = repos.checkPath("", pegRevision);
601:                if (kind == SVNNodeKind.NONE) {
602:                    SVNErrorMessage err = SVNErrorMessage.create(
603:                            SVNErrorCode.FS_NOT_FOUND,
604:                            "path ''{0}'' doesn't exist at revision {1}",
605:                            new Object[] { path, new Long(pegRevision) });
606:                    SVNErrorManager.error(err);
607:                }
608:                long logStart = pegRevision;
609:                logStart = Math.max(startRevision, logStart);
610:                logStart = Math.max(endRevision, logStart);
611:                long logEnd = pegRevision;
612:                logStart = Math.min(startRevision, logStart);
613:                logStart = Math.min(endRevision, logStart);
614:
615:                LocationsLogEntryHandler handler = new LocationsLogEntryHandler(
616:                        path, startRevision, endRevision, pegRevision, kind,
617:                        getEventDispatcher());
618:                repos.log(new String[] { "" }, logStart, logEnd, true, false,
619:                        handler);
620:
621:                String pegPath = handler.myPegPath == null ? handler.myCurrentPath
622:                        : handler.myPegPath;
623:                String startPath = handler.myStartPath == null ? handler.myCurrentPath
624:                        : handler.myStartPath;
625:                String endPath = handler.myEndPath == null ? handler.myCurrentPath
626:                        : handler.myEndPath;
627:
628:                if (pegPath == null) {
629:                    SVNErrorMessage err = SVNErrorMessage
630:                            .create(
631:                                    SVNErrorCode.FS_NOT_FOUND,
632:                                    "path ''{0}'' in revision {1} is an unrelated object",
633:                                    new Object[] { path, new Long(logStart) });
634:                    SVNErrorManager.error(err);
635:                }
636:                Map result = new HashMap();
637:                result.put(new Long(startRevision), new SVNLocationEntry(-1,
638:                        startPath));
639:                result.put(new Long(endRevision), new SVNLocationEntry(-1,
640:                        endPath));
641:                return result;
642:            }
643:
644:            private static String getPreviousLogPath(String path,
645:                    SVNLogEntry logEntry, SVNNodeKind kind) throws SVNException {
646:                String prevPath = null;
647:                SVNLogEntryPath logPath = (SVNLogEntryPath) logEntry
648:                        .getChangedPaths().get(path);
649:                if (logPath != null) {
650:                    if (logPath.getType() != SVNLogEntryPath.TYPE_ADDED
651:                            && logPath.getType() != SVNLogEntryPath.TYPE_REPLACED) {
652:                        return logPath.getPath();
653:                    }
654:                    if (logPath.getCopyPath() != null) {
655:                        return logPath.getCopyPath();
656:                    }
657:                    return null;
658:                } else if (!logEntry.getChangedPaths().isEmpty()) {
659:                    Map sortedMap = new HashMap();
660:                    sortedMap.putAll(logEntry.getChangedPaths());
661:                    List pathsList = new ArrayList(sortedMap.keySet());
662:                    Collections.sort(pathsList, SVNPathUtil.PATH_COMPARATOR);
663:                    Collections.reverse(pathsList);
664:                    for (Iterator paths = pathsList.iterator(); paths.hasNext();) {
665:                        String p = (String) paths.next();
666:                        if (path.startsWith(p + "/")) {
667:                            SVNLogEntryPath lPath = (SVNLogEntryPath) sortedMap
668:                                    .get(p);
669:                            if (lPath.getCopyPath() != null) {
670:                                prevPath = SVNPathUtil.append(lPath
671:                                        .getCopyPath(), path.substring(p
672:                                        .length()));
673:                                break;
674:                            }
675:                        }
676:                    }
677:                }
678:                if (prevPath == null) {
679:                    if (kind == SVNNodeKind.DIR) {
680:                        prevPath = path;
681:                    } else {
682:                        SVNErrorMessage err = SVNErrorMessage
683:                                .create(
684:                                        SVNErrorCode.CLIENT_UNRELATED_RESOURCES,
685:                                        "Missing changed-path information for ''{0}'' in revision {1}",
686:                                        new Object[] {
687:                                                path,
688:                                                new Long(logEntry.getRevision()) });
689:                        SVNErrorManager.error(err);
690:                    }
691:                }
692:                return prevPath;
693:            }
694:
695:            protected SVNURL getURL(File path) throws SVNException {
696:                if (path == null) {
697:                    return null;
698:                }
699:                SVNWCAccess wcAccess = createWCAccess();
700:                try {
701:                    wcAccess.probeOpen(path, false, 0);
702:                    SVNEntry entry = wcAccess.getEntry(path, false);
703:                    return entry != null ? entry.getSVNURL() : null;
704:                } finally {
705:                    wcAccess.close();
706:                }
707:            }
708:
709:            private static final class LocationsLogEntryHandler implements 
710:                    ISVNLogEntryHandler {
711:
712:                private String myCurrentPath = null;
713:                private String myStartPath = null;
714:                private String myEndPath = null;
715:                private String myPegPath = null;
716:
717:                private long myStartRevision;
718:                private long myEndRevision;
719:                private long myPegRevision;
720:                private SVNNodeKind myKind;
721:                private ISVNEventHandler myEventHandler;
722:
723:                private LocationsLogEntryHandler(String path,
724:                        long startRevision, long endRevision, long pegRevision,
725:                        SVNNodeKind kind, ISVNEventHandler eventHandler) {
726:                    myCurrentPath = path;
727:                    myStartRevision = startRevision;
728:                    myEndRevision = endRevision;
729:                    myPegRevision = pegRevision;
730:                    myEventHandler = eventHandler;
731:                    myKind = kind;
732:                }
733:
734:                public void handleLogEntry(SVNLogEntry logEntry)
735:                        throws SVNException {
736:                    if (myEventHandler != null) {
737:                        myEventHandler.checkCancelled();
738:                    }
739:                    if (logEntry.getChangedPaths() == null) {
740:                        return;
741:                    }
742:                    if (myCurrentPath == null) {
743:                        return;
744:                    }
745:                    if (myStartPath == null
746:                            && logEntry.getRevision() <= myStartRevision) {
747:                        myStartPath = myCurrentPath;
748:                    }
749:                    if (myEndPath == null
750:                            && logEntry.getRevision() <= myEndRevision) {
751:                        myEndPath = myCurrentPath;
752:                    }
753:                    if (myPegPath == null
754:                            && logEntry.getRevision() <= myPegRevision) {
755:                        myPegPath = myCurrentPath;
756:                    }
757:                    myCurrentPath = getPreviousLogPath(myCurrentPath, logEntry,
758:                            myKind);
759:                }
760:            }
761:
762:            protected static class RepositoryReference {
763:
764:                public RepositoryReference(String url, long rev) {
765:                    URL = url;
766:                    Revision = rev;
767:                }
768:
769:                public String URL;
770:
771:                public long Revision;
772:            }
773:
774:            protected static class SVNRepositoryLocation {
775:
776:                private SVNURL myURL;
777:                private long myRevision;
778:
779:                public SVNRepositoryLocation(SVNURL url, long rev) {
780:                    myURL = url;
781:                    myRevision = rev;
782:                }
783:
784:                public long getRevisionNumber() {
785:                    return myRevision;
786:                }
787:
788:                public SVNURL getURL() {
789:                    return myURL;
790:                }
791:            }
792:
793:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.