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:
013: package org.tmatesoft.svn.cli.command;
014:
015: import java.io.File;
016: import java.io.IOException;
017: import java.io.InputStream;
018: import java.io.PrintStream;
019: import java.text.DateFormat;
020: import java.text.SimpleDateFormat;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.Iterator;
024: import java.util.Map;
025: import java.util.TreeMap;
026:
027: import org.tmatesoft.svn.cli.SVNArgument;
028: import org.tmatesoft.svn.cli.SVNCommand;
029: import org.tmatesoft.svn.core.ISVNLogEntryHandler;
030: import org.tmatesoft.svn.core.SVNException;
031: import org.tmatesoft.svn.core.SVNLogEntry;
032: import org.tmatesoft.svn.core.SVNLogEntryPath;
033: import org.tmatesoft.svn.core.SVNURL;
034: import org.tmatesoft.svn.core.wc.SVNLogClient;
035: import org.tmatesoft.svn.core.wc.SVNRevision;
036: import org.tmatesoft.svn.core.wc.xml.AbstractXMLHandler;
037: import org.tmatesoft.svn.core.wc.xml.SVNXMLLogHandler;
038: import org.tmatesoft.svn.core.wc.xml.SVNXMLSerializer;
039:
040: /**
041: * @version 1.1.1
042: * @author TMate Software Ltd.
043: */
044: public class SVNLogCommand extends SVNCommand implements
045: ISVNLogEntryHandler {
046:
047: private static final String SEPARATOR = "------------------------------------------------------------------------\n";
048: private static final DateFormat DATE_FORMAT = new SimpleDateFormat(
049: "yyyy-MM-dd HH:mm:ss Z");
050:
051: private PrintStream myPrintStream;
052: private boolean myReportPaths;
053: private boolean myIsQuiet;
054: private boolean myHasLogEntries;
055:
056: public void run(InputStream in, PrintStream out, PrintStream err)
057: throws SVNException {
058: run(out, err);
059: }
060:
061: public void run(PrintStream out, PrintStream err)
062: throws SVNException {
063: SVNRevision[] revRange = getStartEndRevisions();
064: SVNRevision startRevision = revRange[0];
065: SVNRevision endRevision = revRange[1];
066:
067: boolean stopOnCopy = getCommandLine().hasArgument(
068: SVNArgument.STOP_ON_COPY);
069: myReportPaths = getCommandLine().hasArgument(
070: SVNArgument.VERBOSE);
071: myIsQuiet = getCommandLine().hasArgument(SVNArgument.QUIET);
072: String limitStr = (String) getCommandLine().getArgumentValue(
073: SVNArgument.LIMIT);
074: myPrintStream = out;
075: long limit = 0;
076: if (limitStr != null) {
077: try {
078: limit = Long.parseLong(limitStr);
079: if (limit <= 0) {
080: err
081: .println("svn: Argument to --limit must be positive number");
082: return;
083: }
084: } catch (NumberFormatException nfe) {
085: err
086: .println("svn: Argument to --limit must be positive number");
087: return;
088: }
089: }
090: SVNLogClient logClient = getClientManager().getLogClient();
091: ISVNLogEntryHandler handler = this ;
092: SVNXMLSerializer serializer = null;
093: if (getCommandLine().hasArgument(SVNArgument.XML)) {
094: serializer = new SVNXMLSerializer(out);
095: handler = new SVNXMLLogHandler(serializer);
096: if (!getCommandLine().hasArgument(SVNArgument.INCREMENTAL)) {
097: ((AbstractXMLHandler) handler).startDocument();
098: }
099: }
100: if (getCommandLine().hasURLs()) {
101: String url = getCommandLine().getURL(0);
102: SVNRevision pegRevision = getCommandLine()
103: .getPegRevision(0);
104: Collection targets = new ArrayList();
105: for (int i = 0; i < getCommandLine().getPathCount(); i++) {
106: targets.add(getCommandLine().getPathAt(i));
107: }
108: String[] paths = (String[]) targets
109: .toArray(new String[targets.size()]);
110: logClient.doLog(SVNURL.parseURIEncoded(url), paths,
111: pegRevision, startRevision, endRevision,
112: stopOnCopy, myReportPaths, limit, handler);
113: } else if (getCommandLine().hasPaths()) {
114: Collection targets = new ArrayList();
115: SVNRevision[] pegRevisions = new SVNRevision[getCommandLine()
116: .getPathCount()];
117: for (int i = 0; i < getCommandLine().getPathCount(); i++) {
118: targets.add(new File(getCommandLine().getPathAt(i))
119: .getAbsoluteFile());
120: pegRevisions[i] = getCommandLine()
121: .getPathPegRevision(i);
122: }
123: File[] paths = (File[]) targets.toArray(new File[targets
124: .size()]);
125: logClient.doLog(paths, pegRevisions[0], startRevision,
126: endRevision, stopOnCopy, myReportPaths, limit,
127: handler);
128: }
129: if (getCommandLine().hasArgument(SVNArgument.XML)) {
130: if (!getCommandLine().hasArgument(SVNArgument.INCREMENTAL)) {
131: ((AbstractXMLHandler) handler).endDocument();
132: }
133: try {
134: serializer.flush();
135: } catch (IOException e) {
136: }
137: } else if (myHasLogEntries) {
138: myPrintStream.print(SEPARATOR);
139: myPrintStream.flush();
140: }
141: }
142:
143: public void handleLogEntry(SVNLogEntry logEntry) {
144: if (logEntry == null
145: || (logEntry.getMessage() == null && logEntry
146: .getRevision() == 0)) {
147: return;
148: }
149: myHasLogEntries = true;
150: StringBuffer result = new StringBuffer();
151: String author = logEntry.getAuthor() == null ? "(no author)"
152: : logEntry.getAuthor();
153: String date = logEntry.getDate() == null ? "(no date)"
154: : DATE_FORMAT.format(logEntry.getDate());
155: String message = logEntry.getMessage();
156: if (!myIsQuiet && message == null) {
157: message = "";
158: }
159: result.append(SEPARATOR);
160: result.append("r" + Long.toString(logEntry.getRevision())
161: + " | " + author + " | " + date);
162: if (!myIsQuiet) {
163: int count = getLinesCount(message);
164: result.append(" | " + count
165: + (count == 1 ? " line" : " lines"));
166: }
167: result.append("\n");
168: if (myReportPaths && logEntry.getChangedPaths() != null) {
169: Map sortedPaths = new TreeMap(logEntry.getChangedPaths());
170: result.append("Changed paths:\n");
171: for (Iterator paths = sortedPaths.keySet().iterator(); paths
172: .hasNext();) {
173: String path = (String) paths.next();
174: SVNLogEntryPath lPath = (SVNLogEntryPath) sortedPaths
175: .get(path);
176: result.append(" " + lPath.getType() + " " + path);
177: if (lPath.getCopyPath() != null) {
178: result.append(" (from " + lPath.getCopyPath() + ":"
179: + lPath.getCopyRevision() + ")");
180: }
181: result.append("\n");
182: }
183: }
184: if (!myIsQuiet) {
185: result.append("\n" + message + "\n");
186: }
187: myPrintStream.print(result.toString());
188: myPrintStream.flush();
189: }
190: }
|