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.examples.repository;
013:
014: import java.util.Collection;
015: import java.util.Iterator;
016: import java.util.Set;
017:
018: import org.tmatesoft.svn.core.SVNException;
019: import org.tmatesoft.svn.core.SVNLogEntry;
020: import org.tmatesoft.svn.core.SVNLogEntryPath;
021: import org.tmatesoft.svn.core.SVNURL;
022: import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
023: import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
024: import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
025: import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
026: import org.tmatesoft.svn.core.io.SVNRepository;
027: import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
028: import org.tmatesoft.svn.core.wc.SVNWCUtil;
029:
030: /*
031: * The following example program demonstrates how you can use SVNRepository to
032: * obtain a history for a range of revisions including (for each revision): all
033: * changed paths, log message, the author of the commit, the timestamp when the
034: * commit was made. It is similar to the "svn log" command supported by the
035: * Subversion client library.
036: *
037: * As an example here's a part of one of the program layouts (for the default
038: * values):
039: *
040: * ---------------------------------------------
041: * revision: 1240
042: * author: alex
043: * date: Tue Aug 02 19:52:49 NOVST 2005
044: * log message: 0.9.0 is now trunk
045: *
046: * changed paths:
047: * A /trunk (from /branches/0.9.0 revision 1239)
048: * ---------------------------------------------
049: * revision: 1263
050: * author: sa
051: * date: Wed Aug 03 21:19:55 NOVST 2005
052: * log message: updated examples, javadoc files
053: *
054: * changed paths:
055: * M /trunk/doc/javadoc-files/javadoc.css
056: * M /trunk/doc/javadoc-files/overview.html
057: * M /trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/StatusHandler.java
058: * ...
059: *
060: */
061: public class History {
062: /*
063: * args parameter is used to obtain a repository location URL, a start
064: * revision number, an end revision number, user's account name & password
065: * to authenticate him to the server.
066: */
067: public static void main(String[] args) {
068: /*
069: * Default values:
070: */
071: String url = "http://svn.svnkit.com/repos/svnkit/trunk/doc";
072: String name = "anonymous";
073: String password = "anonymous";
074: long startRevision = 0;
075: long endRevision = -1;//HEAD (the latest) revision
076: /*
077: * Initializes the library (it must be done before ever using the
078: * library itself)
079: */
080: setupLibrary();
081:
082: if (args != null) {
083: /*
084: * Obtains a repository location URL
085: */
086: url = (args.length >= 1) ? args[0] : url;
087: /*
088: * Obtains the start point of the revisions range
089: */
090: startRevision = (args.length >= 2) ? Long
091: .parseLong(args[1]) : startRevision;
092: /*
093: * Obtains the end point of the revisions range
094: */
095: endRevision = (args.length >= 3) ? Long.parseLong(args[2])
096: : endRevision;
097: /*
098: * Obtains an account name (will be used to authenticate the user to
099: * the server)
100: */
101: name = (args.length >= 4) ? args[3] : name;
102: /*
103: * Obtains a password
104: */
105: password = (args.length >= 5) ? args[4] : password;
106: }
107:
108: SVNRepository repository = null;
109:
110: try {
111: /*
112: * Creates an instance of SVNRepository to work with the repository.
113: * All user's requests to the repository are relative to the
114: * repository location used to create this SVNRepository.
115: * SVNURL is a wrapper for URL strings that refer to repository locations.
116: */
117: repository = SVNRepositoryFactory.create(SVNURL
118: .parseURIEncoded(url));
119: } catch (SVNException svne) {
120: /*
121: * Perhaps a malformed URL is the cause of this exception.
122: */
123: System.err
124: .println("error while creating an SVNRepository for the location '"
125: + url + "': " + svne.getMessage());
126: System.exit(1);
127: }
128:
129: /*
130: * User's authentication information (name/password) is provided via an
131: * ISVNAuthenticationManager instance. SVNWCUtil creates a default
132: * authentication manager given user's name and password.
133: *
134: * Default authentication manager first attempts to use provided user name
135: * and password and then falls back to the credentials stored in the
136: * default Subversion credentials storage that is located in Subversion
137: * configuration area. If you'd like to use provided user name and password
138: * only you may use BasicAuthenticationManager class instead of default
139: * authentication manager:
140: *
141: * authManager = new BasicAuthenticationsManager(userName, userPassword);
142: *
143: * You may also skip this point - anonymous access will be used.
144: */
145: ISVNAuthenticationManager authManager = SVNWCUtil
146: .createDefaultAuthenticationManager(name, password);
147: repository.setAuthenticationManager(authManager);
148:
149: /*
150: * Gets the latest revision number of the repository
151: */
152: try {
153: endRevision = repository.getLatestRevision();
154: } catch (SVNException svne) {
155: System.err
156: .println("error while fetching the latest repository revision: "
157: + svne.getMessage());
158: System.exit(1);
159: }
160:
161: Collection logEntries = null;
162: try {
163: /*
164: * Collects SVNLogEntry objects for all revisions in the range
165: * defined by its start and end points [startRevision, endRevision].
166: * For each revision commit information is represented by
167: * SVNLogEntry.
168: *
169: * the 1st parameter (targetPaths - an array of path strings) is set
170: * when restricting the [startRevision, endRevision] range to only
171: * those revisions when the paths in targetPaths were changed.
172: *
173: * the 2nd parameter if non-null - is a user's Collection that will
174: * be filled up with found SVNLogEntry objects; it's just another
175: * way to reach the scope.
176: *
177: * startRevision, endRevision - to define a range of revisions you are
178: * interested in; by default in this program - startRevision=0, endRevision=
179: * the latest (HEAD) revision of the repository.
180: *
181: * the 5th parameter - a boolean flag changedPath - if true then for
182: * each revision a corresponding SVNLogEntry will contain a map of
183: * all paths which were changed in that revision.
184: *
185: * the 6th parameter - a boolean flag strictNode - if false and a
186: * changed path is a copy (branch) of an existing one in the repository
187: * then the history for its origin will be traversed; it means the
188: * history of changes of the target URL (and all that there's in that
189: * URL) will include the history of the origin path(s).
190: * Otherwise if strictNode is true then the origin path history won't be
191: * included.
192: *
193: * The return value is a Collection filled up with SVNLogEntry Objects.
194: */
195: logEntries = repository.log(new String[] { "" }, null,
196: startRevision, endRevision, true, true);
197:
198: } catch (SVNException svne) {
199: System.out
200: .println("error while collecting log information for '"
201: + url + "': " + svne.getMessage());
202: System.exit(1);
203: }
204: for (Iterator entries = logEntries.iterator(); entries
205: .hasNext();) {
206: /*
207: * gets a next SVNLogEntry
208: */
209: SVNLogEntry logEntry = (SVNLogEntry) entries.next();
210: System.out
211: .println("---------------------------------------------");
212: /*
213: * gets the revision number
214: */
215: System.out.println("revision: " + logEntry.getRevision());
216: /*
217: * gets the author of the changes made in that revision
218: */
219: System.out.println("author: " + logEntry.getAuthor());
220: /*
221: * gets the time moment when the changes were committed
222: */
223: System.out.println("date: " + logEntry.getDate());
224: /*
225: * gets the commit log message
226: */
227: System.out.println("log message: " + logEntry.getMessage());
228: /*
229: * displaying all paths that were changed in that revision; cahnged
230: * path information is represented by SVNLogEntryPath.
231: */
232: if (logEntry.getChangedPaths().size() > 0) {
233: System.out.println();
234: System.out.println("changed paths:");
235: /*
236: * keys are changed paths
237: */
238: Set changedPathsSet = logEntry.getChangedPaths()
239: .keySet();
240:
241: for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths
242: .hasNext();) {
243: /*
244: * obtains a next SVNLogEntryPath
245: */
246: SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry
247: .getChangedPaths().get(changedPaths.next());
248: /*
249: * SVNLogEntryPath.getPath returns the changed path itself;
250: *
251: * SVNLogEntryPath.getType returns a charecter describing
252: * how the path was changed ('A' - added, 'D' - deleted or
253: * 'M' - modified);
254: *
255: * If the path was copied from another one (branched) then
256: * SVNLogEntryPath.getCopyPath &
257: * SVNLogEntryPath.getCopyRevision tells where it was copied
258: * from and what revision the origin path was at.
259: */
260: System.out
261: .println(" "
262: + entryPath.getType()
263: + " "
264: + entryPath.getPath()
265: + ((entryPath.getCopyPath() != null) ? " (from "
266: + entryPath.getCopyPath()
267: + " revision "
268: + entryPath
269: .getCopyRevision()
270: + ")"
271: : ""));
272: }
273: }
274: }
275: }
276:
277: /*
278: * Initializes the library to work with a repository via
279: * different protocols.
280: */
281: private static void setupLibrary() {
282: /*
283: * For using over http:// and https://
284: */
285: DAVRepositoryFactory.setup();
286: /*
287: * For using over svn:// and svn+xxx://
288: */
289: SVNRepositoryFactoryImpl.setup();
290:
291: /*
292: * For using over file:///
293: */
294: FSRepositoryFactory.setup();
295: }
296: }
|