Source Code Cross Referenced for SVNLogClient.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.Collection;
016:        import java.util.HashMap;
017:        import java.util.Iterator;
018:        import java.util.Map;
019:        import java.util.TreeSet;
020:
021:        import org.tmatesoft.svn.core.ISVNDirEntryHandler;
022:        import org.tmatesoft.svn.core.ISVNLogEntryHandler;
023:        import org.tmatesoft.svn.core.SVNAnnotationGenerator;
024:        import org.tmatesoft.svn.core.SVNDirEntry;
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.SVNLock;
029:        import org.tmatesoft.svn.core.SVNLogEntry;
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.util.SVNURLUtil;
036:        import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
037:        import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
038:        import org.tmatesoft.svn.core.internal.wc.admin.SVNEntry;
039:        import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess;
040:        import org.tmatesoft.svn.core.io.SVNRepository;
041:
042:        /**
043:         * The <b>SVNLogClient</b> class is intended for such purposes as getting
044:         * revisions history, browsing repository entries and annotating file contents.
045:         * 
046:         * <p>
047:         * Here's a list of the <b>SVNLogClient</b>'s methods 
048:         * matched against corresponing commands of the <b>SVN</b> command line 
049:         * client:
050:         * 
051:         * <table cellpadding="3" cellspacing="1" border="0" width="40%" bgcolor="#999933">
052:         * <tr bgcolor="#ADB8D9" align="left">
053:         * <td><b>SVNKit</b></td>
054:         * <td><b>Subversion</b></td>
055:         * </tr>   
056:         * <tr bgcolor="#EAEAEA" align="left">
057:         * <td>doLog()</td><td>'svn log'</td>
058:         * </tr>
059:         * <tr bgcolor="#EAEAEA" align="left">
060:         * <td>doList()</td><td>'svn list'</td>
061:         * </tr>
062:         * <tr bgcolor="#EAEAEA" align="left">
063:         * <td>doAnnotate()</td><td>'svn blame'</td>
064:         * </tr>
065:         * </table>
066:         * 
067:         * @version 1.1.1
068:         * @author  TMate Software Ltd.
069:         */
070:        public class SVNLogClient extends SVNBasicClient {
071:
072:            private SVNDiffOptions myDiffOptions;
073:
074:            /**
075:             * Constructs and initializes an <b>SVNLogClient</b> object
076:             * with the specified run-time configuration and authentication 
077:             * drivers.
078:             * 
079:             * <p>
080:             * If <code>options</code> is <span class="javakeyword">null</span>,
081:             * then this <b>SVNLogClient</b> will be using a default run-time
082:             * configuration driver  which takes client-side settings from the 
083:             * default SVN's run-time configuration area but is not able to
084:             * change those settings (read more on {@link ISVNOptions} and {@link SVNWCUtil}).  
085:             * 
086:             * <p>
087:             * If <code>authManager</code> is <span class="javakeyword">null</span>,
088:             * then this <b>SVNLogClient</b> will be using a default authentication
089:             * and network layers driver (see {@link SVNWCUtil#createDefaultAuthenticationManager()})
090:             * which uses server-side settings and auth storage from the 
091:             * default SVN's run-time configuration area (or system properties
092:             * if that area is not found).
093:             * 
094:             * @param authManager an authentication and network layers driver
095:             * @param options     a run-time configuration options driver     
096:             */
097:            public SVNLogClient(ISVNAuthenticationManager authManager,
098:                    ISVNOptions options) {
099:                super (authManager, options);
100:            }
101:
102:            public SVNLogClient(ISVNRepositoryPool repositoryPool,
103:                    ISVNOptions options) {
104:                super (repositoryPool, options);
105:            }
106:
107:            /**
108:             * Sets diff options for this client to use in annotate operations.
109:             * 
110:             * @param diffOptions diff options object
111:             */
112:            public void setDiffOptions(SVNDiffOptions diffOptions) {
113:                myDiffOptions = diffOptions;
114:            }
115:
116:            /**
117:             * Gets the diff options that are used in annotate operations 
118:             * by this client. Creates a new one if none was used before.
119:             * 
120:             * @return diff options
121:             */
122:            public SVNDiffOptions getDiffOptions() {
123:                if (myDiffOptions == null) {
124:                    myDiffOptions = new SVNDiffOptions();
125:                }
126:                return myDiffOptions;
127:            }
128:
129:            /**
130:             * Obtains annotation information for each file text line from a repository
131:             * (using a Working Copy path to get a corresponding URL) and passes it to a 
132:             * provided annotation handler. 
133:             * 
134:             * <p>
135:             * If <code>startRevision</code> is invalid (for example, 
136:             * <code>startRevision = </code>{@link SVNRevision#UNDEFINED UNDEFINED}) then
137:             * it's set to revision 1.
138:             * 
139:             * <p>
140:             * Calling this method is equivalent to 
141:             * <code>doAnnotate(path, pegRevision, startRevision, endRevision, false, handler)</code>.
142:             * 
143:             * @param  path           a WC file item to be annotated
144:             * @param  pegRevision    a revision in which <code>path</code> is first looked up
145:             *                        in the repository
146:             * @param  startRevision  a revision for an operation to start from
147:             * @param  endRevision    a revision for an operation to stop at
148:             * @param  handler        a caller's handler to process annotation information
149:             * @throws SVNException   if <code>startRevision > endRevision</code>
150:             * @see                   #doAnnotate(SVNURL, SVNRevision, SVNRevision, SVNRevision, ISVNAnnotateHandler)
151:             */
152:            public void doAnnotate(File path, SVNRevision pegRevision,
153:                    SVNRevision startRevision, SVNRevision endRevision,
154:                    ISVNAnnotateHandler handler) throws SVNException {
155:                doAnnotate(path, pegRevision, startRevision, endRevision,
156:                        false, handler);
157:            }
158:
159:            /**
160:             * Obtains annotation information for each file text line from a repository
161:             * (using a Working Copy path to get a corresponding URL) and passes it to a 
162:             * provided annotation handler. 
163:             * 
164:             * <p>
165:             * If <code>startRevision</code> is invalid (for example, 
166:             * <code>startRevision = </code>{@link SVNRevision#UNDEFINED UNDEFINED}) then
167:             * it's set to revision 1.
168:             * 
169:             * @param  path           a WC file item to be annotated
170:             * @param  pegRevision    a revision in which <code>path</code> is first looked up
171:             *                        in the repository
172:             * @param  startRevision  a revision for an operation to start from
173:             * @param  endRevision    a revision for an operation to stop at
174:             * @param  force          forces operation to run (all files to be treated as 
175:             *                        text, no matter what SVNKit has inferred from the mime-type 
176:             *                        property) 
177:             * @param  handler        a caller's handler to process annotation information
178:             * @throws SVNException
179:             * @since                 1.1
180:             */
181:            public void doAnnotate(File path, SVNRevision pegRevision,
182:                    SVNRevision startRevision, SVNRevision endRevision,
183:                    boolean force, ISVNAnnotateHandler handler)
184:                    throws SVNException {
185:                if (startRevision == null || !startRevision.isValid()) {
186:                    startRevision = SVNRevision.create(1);
187:                }
188:                if (endRevision == null || !endRevision.isValid()) {
189:                    endRevision = pegRevision;
190:                }
191:                SVNRepository repos = createRepository(null, path, pegRevision,
192:                        endRevision);
193:                long endRev = getRevisionNumber(endRevision, repos, path);
194:                long startRev = getRevisionNumber(startRevision, repos, path);
195:                if (endRev < startRev) {
196:                    SVNErrorManager.error(SVNErrorMessage.create(
197:                            SVNErrorCode.CLIENT_BAD_REVISION,
198:                            "Start revision must precede end revision"));
199:                }
200:                File tmpFile = new File(path.getParentFile(), SVNFileUtil
201:                        .getAdminDirectoryName());
202:                tmpFile = new File(tmpFile, "tmp/text-base");
203:                if (!tmpFile.isDirectory()) {
204:                    tmpFile = SVNFileUtil.createTempDirectory("annotate");
205:                }
206:                doAnnotate(path.getAbsolutePath(), startRev, tmpFile, repos,
207:                        endRev, force, handler, null);
208:            }
209:
210:            /**
211:             * Obtains annotation information for each file text line from a repository
212:             * and passes it to a provided annotation handler. 
213:             * 
214:             * <p>
215:             * If <code>startRevision</code> is invalid (for example, 
216:             * <code>startRevision = </code>{@link SVNRevision#UNDEFINED UNDEFINED}) then
217:             * it's set to revision 1.
218:             * 
219:             * <p>
220:             * Calling this method is equivalent to  
221:             * <code>doAnnotate(url, pegRevision, startRevision, endRevision, handler, null)</code>.
222:             * 
223:             * @param  url            a URL of a text file that is to be annotated 
224:             * @param  pegRevision    a revision in which <code>path</code> is first looked up
225:             *                        in the repository
226:             * @param  startRevision  a revision for an operation to start from
227:             * @param  endRevision    a revision for an operation to stop at
228:             * @param  handler        a caller's handler to process annotation information
229:             * @throws SVNException   if <code>startRevision > endRevision</code>
230:             * @see                   #doAnnotate(File, SVNRevision, SVNRevision, SVNRevision, ISVNAnnotateHandler)
231:             */
232:            public void doAnnotate(SVNURL url, SVNRevision pegRevision,
233:                    SVNRevision startRevision, SVNRevision endRevision,
234:                    ISVNAnnotateHandler handler) throws SVNException {
235:                doAnnotate(url, pegRevision, startRevision, endRevision,
236:                        handler, null);
237:            }
238:
239:            /**
240:             * Obtains annotation information for each file text line from a repository
241:             * and passes it to a provided annotation handler. 
242:             * 
243:             * <p>
244:             * If <code>startRevision</code> is invalid (for example, 
245:             * <code>startRevision = </code>{@link SVNRevision#UNDEFINED UNDEFINED}) then
246:             * it's set to revision 1.
247:             * 
248:             * <p>
249:             * Calling this method is equivalent to  
250:             * <code>doAnnotate(url, pegRevision, startRevision, endRevision, false, handler, inputEncoding)</code>.
251:             * 
252:             * @param  url            a URL of a text file that is to be annotated 
253:             * @param  pegRevision    a revision in which <code>path</code> is first looked up
254:             *                        in the repository
255:             * @param  startRevision  a revision for an operation to start from
256:             * @param  endRevision    a revision for an operation to stop at
257:             * @param  handler        a caller's handler to process annotation information
258:             * @param  inputEncoding  a desired character set (encoding) of text lines
259:             * @throws SVNException
260:             */
261:            public void doAnnotate(SVNURL url, SVNRevision pegRevision,
262:                    SVNRevision startRevision, SVNRevision endRevision,
263:                    ISVNAnnotateHandler handler, String inputEncoding)
264:                    throws SVNException {
265:                doAnnotate(url, pegRevision, startRevision, endRevision, false,
266:                        handler, inputEncoding);
267:            }
268:
269:            /**
270:             * Obtains annotation information for each file text line from a repository
271:             * and passes it to a provided annotation handler. 
272:             * 
273:             * <p>
274:             * If <code>startRevision</code> is invalid (for example, 
275:             * <code>startRevision = </code>{@link SVNRevision#UNDEFINED UNDEFINED}) then
276:             * it's set to revision 1.
277:             *
278:             * <p>
279:             * If <code>inputEncoding</code> is <span class="javakeyword">null</span> then 
280:             * <span class="javastring">"file.encoding"</span> system property is used.
281:             *  
282:             * @param  url            a URL of a text file that is to be annotated 
283:             * @param  pegRevision    a revision in which <code>path</code> is first looked up
284:             *                        in the repository
285:             * @param  startRevision  a revision for an operation to start from
286:             * @param  endRevision    a revision for an operation to stop at
287:             * @param  force          forces operation to run (all files to be treated as 
288:             *                        text, no matter what SVNKit has inferred from the mime-type 
289:             *                        property) 
290:             * @param  handler        a caller's handler to process annotation information
291:             * @param  inputEncoding  a desired character set (encoding) of text lines
292:             * @throws SVNException
293:             * @since                 1.1
294:             */
295:            public void doAnnotate(SVNURL url, SVNRevision pegRevision,
296:                    SVNRevision startRevision, SVNRevision endRevision,
297:                    boolean force, ISVNAnnotateHandler handler,
298:                    String inputEncoding) throws SVNException {
299:                if (startRevision == null || !startRevision.isValid()) {
300:                    startRevision = SVNRevision.create(1);
301:                }
302:                if (endRevision == null || !endRevision.isValid()) {
303:                    endRevision = pegRevision;
304:                }
305:                SVNRepository repos = createRepository(url, null, pegRevision,
306:                        endRevision);
307:                long endRev = getRevisionNumber(endRevision, repos, null);
308:                long startRev = getRevisionNumber(startRevision, repos, null);
309:                if (endRev < startRev) {
310:                    SVNErrorManager.error(SVNErrorMessage.create(
311:                            SVNErrorCode.CLIENT_BAD_REVISION,
312:                            "Start revision must precede end revision"));
313:                }
314:                File tmpFile = SVNFileUtil.createTempDirectory("annotate");
315:                doAnnotate(repos.getLocation().toDecodedString(), startRev,
316:                        tmpFile, repos, endRev, force, handler, inputEncoding);
317:            }
318:
319:            private void doAnnotate(String path, long startRev, File tmpFile,
320:                    SVNRepository repos, long endRev, boolean force,
321:                    ISVNAnnotateHandler handler, String inputEncoding)
322:                    throws SVNException {
323:                SVNAnnotationGenerator generator = new SVNAnnotationGenerator(
324:                        path, tmpFile, startRev, force, getDiffOptions(), this );
325:                try {
326:                    repos.getFileRevisions("", startRev > 0 ? startRev - 1
327:                            : startRev, endRev, generator);
328:                    generator.reportAnnotations(handler, inputEncoding);
329:                } finally {
330:                    generator.dispose();
331:                    SVNFileUtil.deleteAll(tmpFile, !"text-base".equals(tmpFile
332:                            .getName()), null);
333:                }
334:            }
335:
336:            /**
337:             * Gets commit log messages with other revision specific 
338:             * information from a repository (using Working Copy paths to get 
339:             * corresponding URLs) and passes them to a log entry handler for
340:             * processing. Useful for observing the history of affected paths,
341:             * author, date and log comments information per revision.
342:             * 
343:             * <p>
344:             * If <code>paths</code> is not empty then the result will be restricted
345:             * to only those revisions from the specified range [<code>startRevision</code>, <code>endRevision</code>], 
346:             * where <code>paths</code> were changed in the repository. To cover the
347:             * entire range set <code>paths</code> just to an empty array:
348:             * <pre class="javacode">
349:             *     logClient.doLog(<span class="javakeyword">new</span> File[]{<span class="javastring">""</span>},..);</pre><br />
350:             * <p>
351:             * If <code>startRevision</code> is valid but <code>endRevision</code> is
352:             * not (for example, <code>endRevision = </code>{@link SVNRevision#UNDEFINED UNDEFINED})
353:             * then <code>endRevision</code> is equated to <code>startRevision</code>.
354:             * 
355:             * <p>
356:             * If <code>startRevision</code> is invalid (for example, {@link SVNRevision#UNDEFINED UNDEFINED}) 
357:             * then it's equated to {@link SVNRevision#BASE BASE}. In this case if <code>endRevision</code> is
358:             * also invalid, then <code>endRevision</code> is set to revision 0.
359:             * 
360:             * <p>
361:             * Calling this method is equivalent to 
362:             * <code>doLog(paths, SVNRevision.UNDEFINED, startRevision, endRevision, stopOnCopy, reportPaths, limit, handler)</code>.
363:             * 
364:             * @param  paths           an array of Working Copy paths,
365:             *                         should not be <span class="javakeyword">null</span>
366:             * @param  startRevision   a revision for an operation to start from (including
367:             *                         this revision)    
368:             * @param  endRevision     a revision for an operation to stop at (including
369:             *                         this revision)
370:             * @param  stopOnCopy      <span class="javakeyword">true</span> not to cross
371:             *                         copies while traversing history, otherwise copies history
372:             *                         will be also included into processing
373:             * @param  reportPaths     <span class="javakeyword">true</span> to report
374:             *                         of all changed paths for every revision being processed 
375:             *                         (those paths will be available by calling 
376:             *                         {@link org.tmatesoft.svn.core.SVNLogEntry#getChangedPaths()})
377:             * @param  limit           a maximum number of log entries to be processed 
378:             * @param  handler         a caller's log entry handler
379:             * @throws SVNException    if one of the following is true:
380:             *                         <ul>
381:             *                         <li>a path is not under version control
382:             *                         <li>can not obtain a URL of a WC path - there's no such
383:             *                         entry in the Working Copy
384:             *                         <li><code>paths</code> contain entries that belong to
385:             *                         different repositories
386:             *                         </ul>
387:             * @see                    #doLog(SVNURL, String[], SVNRevision, SVNRevision, SVNRevision, boolean, boolean, long, ISVNLogEntryHandler)                        
388:             */
389:            public void doLog(File[] paths, SVNRevision startRevision,
390:                    SVNRevision endRevision, boolean stopOnCopy,
391:                    boolean reportPaths, long limit,
392:                    final ISVNLogEntryHandler handler) throws SVNException {
393:                doLog(paths, SVNRevision.UNDEFINED, startRevision, endRevision,
394:                        stopOnCopy, reportPaths, limit, handler);
395:            }
396:
397:            /**
398:             * Gets commit log messages with other revision specific 
399:             * information from a repository (using Working Copy paths to get 
400:             * corresponding URLs) and passes them to a log entry handler for
401:             * processing. Useful for observing the history of affected paths,
402:             * author, date and log comments information per revision.
403:             * 
404:             * <p>
405:             * If <code>paths</code> is not empty then the result will be restricted
406:             * to only those revisions from the specified range [<code>startRevision</code>, <code>endRevision</code>], 
407:             * where <code>paths</code> were changed in the repository. To cover the
408:             * entire range set <code>paths</code> just to an empty array:
409:             * <pre class="javacode">
410:             *     logClient.doLog(<span class="javakeyword">new</span> File[]{<span class="javastring">""</span>},..);</pre><br />
411:             * <p>
412:             * If <code>startRevision</code> is valid but <code>endRevision</code> is
413:             * not (for example, <code>endRevision = </code>{@link SVNRevision#UNDEFINED UNDEFINED})
414:             * then <code>endRevision</code> is equated to <code>startRevision</code>.
415:             * 
416:             * <p>
417:             * If <code>startRevision</code> is invalid (for example, {@link SVNRevision#UNDEFINED UNDEFINED}) 
418:             * then it's equated to {@link SVNRevision#BASE BASE}. In this case if <code>endRevision</code> is
419:             * also invalid, then <code>endRevision</code> is set to revision 0.
420:             * 
421:             * @param  paths           an array of Working Copy paths,
422:             *                         should not be <span class="javakeyword">null</span>
423:             * @param  pegRevision     a revision in which <code>path</code> is first looked up
424:             *                         in the repository
425:             * @param  startRevision   a revision for an operation to start from (including
426:             *                         this revision)    
427:             * @param  endRevision     a revision for an operation to stop at (including
428:             *                         this revision)
429:             * @param  stopOnCopy      <span class="javakeyword">true</span> not to cross
430:             *                         copies while traversing history, otherwise copies history
431:             *                         will be also included into processing
432:             * @param  reportPaths     <span class="javakeyword">true</span> to report
433:             *                         of all changed paths for every revision being processed 
434:             *                         (those paths will be available by calling 
435:             *                         {@link org.tmatesoft.svn.core.SVNLogEntry#getChangedPaths()})
436:             * @param  limit           a maximum number of log entries to be processed 
437:             * @param  handler         a caller's log entry handler
438:             * @throws SVNException    if one of the following is true:
439:             *                         <ul>
440:             *                         <li>a path is not under version control
441:             *                         <li>can not obtain a URL of a WC path - there's no such
442:             *                         entry in the Working Copy
443:             *                         <li><code>paths</code> contain entries that belong to
444:             *                         different repositories
445:             *                         </ul>
446:             */
447:            public void doLog(File[] paths, SVNRevision pegRevision,
448:                    SVNRevision startRevision, SVNRevision endRevision,
449:                    boolean stopOnCopy, boolean reportPaths, long limit,
450:                    final ISVNLogEntryHandler handler) throws SVNException {
451:                if (paths == null || paths.length == 0) {
452:                    return;
453:                }
454:                if (startRevision.isValid() && !endRevision.isValid()) {
455:                    endRevision = startRevision;
456:                } else if (!startRevision.isValid()) {
457:                    if (!pegRevision.isValid()) {
458:                        startRevision = SVNRevision.BASE;
459:                    } else {
460:                        startRevision = pegRevision;
461:                    }
462:                    if (!endRevision.isValid()) {
463:                        endRevision = SVNRevision.create(0);
464:                    }
465:                }
466:                ISVNLogEntryHandler wrappingHandler = new ISVNLogEntryHandler() {
467:                    public void handleLogEntry(SVNLogEntry logEntry)
468:                            throws SVNException {
469:                        checkCancelled();
470:                        handler.handleLogEntry(logEntry);
471:                    }
472:                };
473:                SVNURL[] urls = new SVNURL[paths.length];
474:                SVNWCAccess wcAccess = createWCAccess();
475:                for (int i = 0; i < paths.length; i++) {
476:                    checkCancelled();
477:                    File path = paths[i];
478:                    wcAccess.probeOpen(path, false, 0);
479:                    SVNEntry entry = wcAccess.getEntry(path, false);
480:                    if (entry == null) {
481:                        SVNErrorMessage err = SVNErrorMessage.create(
482:                                SVNErrorCode.UNVERSIONED_RESOURCE,
483:                                "''{0}'' is not under version control", path);
484:                        SVNErrorManager.error(err);
485:                    }
486:                    if (entry.getURL() == null) {
487:                        SVNErrorMessage err = SVNErrorMessage.create(
488:                                SVNErrorCode.ENTRY_MISSING_URL,
489:                                "Entry ''{0}'' has no URL", path);
490:                        SVNErrorManager.error(err);
491:                    }
492:                    urls[i] = entry.getSVNURL();
493:                    wcAccess.closeAdminArea(path);
494:                }
495:                if (urls.length == 0) {
496:                    return;
497:                }
498:                Collection targets = new TreeSet();
499:                SVNURL baseURL = SVNURLUtil.condenceURLs(urls, targets, true);
500:                if (baseURL == null) {
501:                    SVNErrorMessage err = SVNErrorMessage
502:                            .create(SVNErrorCode.ILLEGAL_TARGET,
503:                                    "target log paths belong to different repositories");
504:                    SVNErrorManager.error(err);
505:                }
506:                if (targets.isEmpty()) {
507:                    targets.add("");
508:                }
509:                SVNRevision rev = SVNRevision.UNDEFINED;
510:                if (startRevision.getNumber() >= 0
511:                        && endRevision.getNumber() >= 0) {
512:                    rev = startRevision.getNumber() > endRevision.getNumber() ? startRevision
513:                            : endRevision;
514:                } else if (startRevision.getDate() != null
515:                        && endRevision.getDate() != null) {
516:                    rev = startRevision.getDate().compareTo(
517:                            endRevision.getDate()) > 0 ? startRevision
518:                            : endRevision;
519:                }
520:                SVNRepository repos = rev.isValid() ? //!startRevision.isLocal() && !pegRevision.isLocal() ?
521:                createRepository(baseURL, null, pegRevision, rev)
522:                        : createRepository(baseURL, true);
523:                String[] targetPaths = (String[]) targets
524:                        .toArray(new String[targets.size()]);
525:                for (int i = 0; i < targetPaths.length; i++) {
526:                    targetPaths[i] = SVNEncodingUtil.uriDecode(targetPaths[i]);
527:                }
528:                if (startRevision.isLocal() || endRevision.isLocal()) {
529:                    for (int i = 0; i < paths.length; i++) {
530:                        checkCancelled();
531:                        long startRev = getRevisionNumber(startRevision, repos,
532:                                paths[i]);
533:                        long endRev = getRevisionNumber(endRevision, repos,
534:                                paths[i]);
535:                        repos.log(targetPaths, startRev, endRev, reportPaths,
536:                                stopOnCopy, limit, wrappingHandler);
537:                    }
538:                } else {
539:                    long startRev = getRevisionNumber(startRevision, repos,
540:                            null);
541:                    long endRev = getRevisionNumber(endRevision, repos, null);
542:                    repos.log(targetPaths, startRev, endRev, reportPaths,
543:                            stopOnCopy, limit, wrappingHandler);
544:                }
545:            }
546:
547:            /**
548:             * Gets commit log messages with other revision specific 
549:             * information from a repository and passes them to a log entry 
550:             * handler for processing. Useful for observing the history of 
551:             * affected paths, author, date and log comments information per revision.
552:             * 
553:             * <p>
554:             * If <code>paths</code> is <span class="javakeyword">null</span> or empty
555:             * then <code>url</code> is the target path that is used to restrict the result
556:             * to only those revisions from the specified range [<code>startRevision</code>, <code>endRevision</code>], 
557:             * where <code>url</code> was changed in the repository. Otherwise if <code>paths</code> is
558:             * not empty then <code>url</code> is the root for all those paths (that are
559:             * used for restricting the result).
560:             * 
561:             * <p>
562:             * If <code>startRevision</code> is valid but <code>endRevision</code> is
563:             * not (for example, <code>endRevision = </code>{@link SVNRevision#UNDEFINED UNDEFINED})
564:             * then <code>endRevision</code> is equated to <code>startRevision</code>.
565:             * 
566:             * <p>
567:             * If <code>startRevision</code> is invalid (for example, {@link SVNRevision#UNDEFINED UNDEFINED}) 
568:             * then it's equated to {@link SVNRevision#HEAD HEAD}. In this case if <code>endRevision</code> is
569:             * also invalid, then <code>endRevision</code> is set to revision 0.
570:             * 
571:             * 
572:             * @param  url             a target URL            
573:             * @param  paths           an array of paths relative to the target 
574:             *                         <code>url</code>
575:             * @param  pegRevision     a revision in which <code>url</code> is first looked up
576:             * @param  startRevision   a revision for an operation to start from (including
577:             *                         this revision)    
578:             * @param  endRevision     a revision for an operation to stop at (including
579:             *                         this revision)
580:             * @param  stopOnCopy      <span class="javakeyword">true</span> not to cross
581:             *                         copies while traversing history, otherwise copies history
582:             *                         will be also included into processing
583:             * @param  reportPaths     <span class="javakeyword">true</span> to report
584:             *                         of all changed paths for every revision being processed 
585:             *                         (those paths will be available by calling 
586:             *                         {@link org.tmatesoft.svn.core.SVNLogEntry#getChangedPaths()})
587:             * @param  limit           a maximum number of log entries to be processed 
588:             * @param  handler         a caller's log entry handler
589:             * @throws SVNException
590:             * @see                    #doLog(File[], SVNRevision, SVNRevision, boolean, boolean, long, ISVNLogEntryHandler)
591:             * @since                  1.1, new in Subversion 1.4
592:             */
593:            public void doLog(SVNURL url, String[] paths,
594:                    SVNRevision pegRevision, SVNRevision startRevision,
595:                    SVNRevision endRevision, boolean stopOnCopy,
596:                    boolean reportPaths, long limit,
597:                    final ISVNLogEntryHandler handler) throws SVNException {
598:                if (startRevision.isValid() && !endRevision.isValid()) {
599:                    endRevision = startRevision;
600:                } else if (!startRevision.isValid()) {
601:                    if (!pegRevision.isValid()) {
602:                        startRevision = SVNRevision.HEAD;
603:                    } else {
604:                        startRevision = pegRevision;
605:                    }
606:                    if (!endRevision.isValid()) {
607:                        endRevision = SVNRevision.create(0);
608:                    }
609:                }
610:                paths = paths == null || paths.length == 0 ? new String[] { "" }
611:                        : paths;
612:                ISVNLogEntryHandler wrappingHandler = new ISVNLogEntryHandler() {
613:                    public void handleLogEntry(SVNLogEntry logEntry)
614:                            throws SVNException {
615:                        checkCancelled();
616:                        handler.handleLogEntry(logEntry);
617:                    }
618:                };
619:                SVNRevision rev = SVNRevision.UNDEFINED;
620:                if (startRevision.getNumber() >= 0
621:                        && endRevision.getNumber() >= 0) {
622:                    rev = startRevision.getNumber() > endRevision.getNumber() ? startRevision
623:                            : endRevision;
624:                } else if (startRevision.getDate() != null
625:                        && endRevision.getDate() != null) {
626:                    rev = startRevision.getDate().compareTo(
627:                            endRevision.getDate()) > 0 ? startRevision
628:                            : endRevision;
629:                }
630:                SVNRepository repos = rev.isValid() ? createRepository(url,
631:                        null, pegRevision, rev) : createRepository(url, true);
632:                checkCancelled();
633:                long startRev = getRevisionNumber(startRevision, repos, null);
634:                checkCancelled();
635:                long endRev = getRevisionNumber(endRevision, repos, null);
636:                checkCancelled();
637:                repos.log(paths, startRev, endRev, reportPaths, stopOnCopy,
638:                        limit, wrappingHandler);
639:            }
640:
641:            /**
642:             * Browses directory entries from a repository (using Working 
643:             * Copy paths to get corresponding URLs) and uses the provided dir 
644:             * entry handler to process them.
645:             * 
646:             * <p>
647:             * On every entry that this method stops it gets some useful entry 
648:             * information which is packed into an {@link org.tmatesoft.svn.core.SVNDirEntry}
649:             * object and passed to the <code>handler</code>'s 
650:             * {@link org.tmatesoft.svn.core.ISVNDirEntryHandler#handleDirEntry(SVNDirEntry) handleDirEntry()} method.
651:             *  
652:             * @param  path           a WC item to get its repository location            
653:             * @param  pegRevision    a revision in which the item's URL is first looked up
654:             * @param  revision       a target revision
655:             * @param  fetchLocks     <span class="javakeyword">true</span> to fetch locks 
656:             *                        information from a repository
657:             * @param  recursive      <span class="javakeyword">true</span> to
658:             *                        descend recursively (relevant for directories)    
659:             * @param  handler        a caller's directory entry handler (to process
660:             *                        info on an entry)
661:             * @throws SVNException 
662:             * @see                   #doList(SVNURL, SVNRevision, SVNRevision, boolean, ISVNDirEntryHandler)  
663:             */
664:            public void doList(File path, SVNRevision pegRevision,
665:                    SVNRevision revision, boolean fetchLocks,
666:                    boolean recursive, ISVNDirEntryHandler handler)
667:                    throws SVNException {
668:                if (revision == null || !revision.isValid()) {
669:                    revision = SVNRevision.BASE;
670:                }
671:                SVNRepository repos = createRepository(null, path, pegRevision,
672:                        revision);
673:                long rev = getRevisionNumber(revision, repos, path);
674:                doList(repos, rev, handler, fetchLocks, recursive);
675:            }
676:
677:            /**
678:             * Browses directory entries from a repository (using Working 
679:             * Copy paths to get corresponding URLs) and uses the provided dir 
680:             * entry handler to process them.
681:             * 
682:             * <p>
683:             * On every entry that this method stops it gets some useful entry 
684:             * information which is packed into an {@link org.tmatesoft.svn.core.SVNDirEntry}
685:             * object and passed to the <code>handler</code>'s 
686:             * {@link org.tmatesoft.svn.core.ISVNDirEntryHandler#handleDirEntry(SVNDirEntry) handleDirEntry()} method.
687:             *  
688:             * @param  path           a WC item to get its repository location            
689:             * @param  pegRevision    a revision in which the item's URL is first looked up
690:             * @param  revision       a target revision
691:             * @param  recursive      <span class="javakeyword">true</span> to
692:             *                        descend recursively (relevant for directories)    
693:             * @param  handler        a caller's directory entry handler (to process
694:             *                        info on an entry)
695:             * @throws SVNException 
696:             * @see                   #doList(SVNURL, SVNRevision, SVNRevision, boolean, ISVNDirEntryHandler)  
697:             */
698:            public void doList(File path, SVNRevision pegRevision,
699:                    SVNRevision revision, boolean recursive,
700:                    ISVNDirEntryHandler handler) throws SVNException {
701:                doList(path, pegRevision, revision, false, recursive, handler);
702:
703:            }
704:
705:            /**
706:             * Browses directory entries from a repository and uses the provided 
707:             * dir entry handler to process them. This method is 
708:             * especially useful when having no Working Copy. 
709:             * 
710:             * <p>
711:             * On every entry that this method stops it gets some useful entry 
712:             * information which is packed into an {@link org.tmatesoft.svn.core.SVNDirEntry}
713:             * object and passed to the <code>handler</code>'s 
714:             * {@link org.tmatesoft.svn.core.ISVNDirEntryHandler#handleDirEntry(SVNDirEntry) handleDirEntry()} method.
715:             * 
716:             * @param  url            a repository location to be "listed"
717:             * @param  pegRevision    a revision in which the item's URL is first looked up
718:             * @param  revision       a target revision
719:             * @param  fetchLocks     <span class="javakeyword">true</span> to 
720:             *                        fetch locks information from repository
721:             * @param  recursive      <span class="javakeyword">true</span> to
722:             *                        descend recursively (relevant for directories)    
723:             * @param  handler        a caller's directory entry handler (to process
724:             *                        info on an entry)
725:             * @throws SVNException
726:             * @see                   #doList(File, SVNRevision, SVNRevision, boolean, ISVNDirEntryHandler)   
727:             */
728:            public void doList(SVNURL url, SVNRevision pegRevision,
729:                    SVNRevision revision, boolean fetchLocks,
730:                    boolean recursive, ISVNDirEntryHandler handler)
731:                    throws SVNException {
732:                long[] pegRev = new long[] { -1 };
733:                SVNRepository repos = createRepository(url, null, pegRevision,
734:                        revision, pegRev);
735:                if (pegRev[0] < 0) {
736:                    pegRev[0] = getRevisionNumber(revision, repos, null);
737:                }
738:                doList(repos, pegRev[0], handler, fetchLocks, recursive);
739:            }
740:
741:            /**
742:             * Browses directory entries from a repository and uses the provided 
743:             * dir entry handler to process them. This method is 
744:             * especially useful when having no Working Copy. 
745:             * 
746:             * <p>
747:             * On every entry that this method stops it gets some useful entry 
748:             * information which is packed into an {@link org.tmatesoft.svn.core.SVNDirEntry}
749:             * object and passed to the <code>handler</code>'s 
750:             * {@link org.tmatesoft.svn.core.ISVNDirEntryHandler#handleDirEntry(SVNDirEntry) handleDirEntry()} method.
751:             * 
752:             * @param  url            a repository location to be "listed"
753:             * @param  pegRevision    a revision in which the item's URL is first looked up
754:             * @param  revision       a target revision
755:             * @param  recursive      <span class="javakeyword">true</span> to
756:             *                        descend recursively (relevant for directories)    
757:             * @param  handler        a caller's directory entry handler (to process
758:             *                        info on an entry)
759:             * @throws SVNException
760:             * @see                   #doList(File, SVNRevision, SVNRevision, boolean, ISVNDirEntryHandler)   
761:             */
762:            public void doList(SVNURL url, SVNRevision pegRevision,
763:                    SVNRevision revision, boolean recursive,
764:                    ISVNDirEntryHandler handler) throws SVNException {
765:                doList(url, pegRevision, revision, false, recursive, handler);
766:            }
767:
768:            private void doList(SVNRepository repos, long rev,
769:                    final ISVNDirEntryHandler handler, boolean fetchLocks,
770:                    boolean recursive) throws SVNException {
771:                final Map locksMap = new HashMap();
772:                if (fetchLocks) {
773:                    SVNLock[] locks = new SVNLock[0];
774:                    try {
775:                        locks = repos.getLocks("");
776:                    } catch (SVNException e) {
777:                        if (!(e.getErrorMessage() != null && e
778:                                .getErrorMessage().getErrorCode() == SVNErrorCode.RA_NOT_IMPLEMENTED)) {
779:                            throw e;
780:                        }
781:                    }
782:
783:                    if (locks != null && locks.length > 0) {
784:                        SVNURL root = repos.getRepositoryRoot(true);
785:                        for (int i = 0; i < locks.length; i++) {
786:                            String repositoryPath = locks[i].getPath();
787:                            locksMap.put(
788:                                    root.appendPath(repositoryPath, false),
789:                                    locks[i]);
790:                        }
791:                    }
792:                }
793:                ISVNDirEntryHandler nestedHandler = new ISVNDirEntryHandler() {
794:                    public void handleDirEntry(SVNDirEntry dirEntry)
795:                            throws SVNException {
796:                        dirEntry.setLock((SVNLock) locksMap.get(dirEntry
797:                                .getURL()));
798:                        handler.handleDirEntry(dirEntry);
799:                    }
800:                };
801:                if (repos.checkPath("", rev) == SVNNodeKind.FILE) {
802:                    String name = SVNPathUtil.tail(repos.getLocation()
803:                            .getPath());
804:                    SVNURL fileULR = repos.getLocation();
805:                    repos.setLocation(repos.getLocation().removePathTail(),
806:                            false);
807:                    Collection dirEntries = repos.getDir("", rev, null,
808:                            (Collection) null);
809:
810:                    SVNDirEntry fileEntry = null;
811:                    for (Iterator ents = dirEntries.iterator(); ents.hasNext();) {
812:                        SVNDirEntry dirEntry = (SVNDirEntry) ents.next();
813:                        if (name.equals(dirEntry.getName())) {
814:                            fileEntry = dirEntry;
815:                            break;
816:                        }
817:                    }
818:                    if (fileEntry != null) {
819:                        fileEntry.setRelativePath(name);
820:                        nestedHandler.handleDirEntry(fileEntry);
821:                    } else {
822:                        SVNErrorMessage err = SVNErrorMessage.create(
823:                                SVNErrorCode.FS_NOT_FOUND,
824:                                "URL ''{0}'' non-existent in that revision",
825:                                fileULR);
826:                        SVNErrorManager.error(err);
827:                    }
828:                } else {
829:                    list(repos, "", rev, recursive, nestedHandler);
830:                }
831:            }
832:
833:            private static void list(SVNRepository repository, String path,
834:                    long rev, boolean recursive, ISVNDirEntryHandler handler)
835:                    throws SVNException {
836:                Collection entries = new TreeSet();
837:                entries = repository.getDir(path, rev, null, entries);
838:
839:                for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
840:                    SVNDirEntry entry = (SVNDirEntry) iterator.next();
841:                    String childPath = SVNPathUtil
842:                            .append(path, entry.getName());
843:                    entry.setRelativePath(childPath);
844:                    handler.handleDirEntry(entry);
845:                    if (entry.getKind() == SVNNodeKind.DIR
846:                            && entry.getDate() != null && recursive) {
847:                        list(repository, childPath, rev, recursive, handler);
848:                    }
849:                }
850:            }
851:
852:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.