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.Date;
022: import java.util.Locale;
023:
024: import org.tmatesoft.svn.cli.SVNArgument;
025: import org.tmatesoft.svn.cli.SVNCommand;
026: import org.tmatesoft.svn.core.SVNException;
027: import org.tmatesoft.svn.core.SVNLock;
028: import org.tmatesoft.svn.core.SVNNodeKind;
029: import org.tmatesoft.svn.core.SVNURL;
030: import org.tmatesoft.svn.core.internal.util.SVNFormatUtil;
031: import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
032: import org.tmatesoft.svn.core.wc.ISVNInfoHandler;
033: import org.tmatesoft.svn.core.wc.SVNInfo;
034: import org.tmatesoft.svn.core.wc.SVNRevision;
035: import org.tmatesoft.svn.core.wc.SVNWCClient;
036: import org.tmatesoft.svn.core.wc.xml.SVNXMLInfoHandler;
037: import org.tmatesoft.svn.core.wc.xml.SVNXMLSerializer;
038:
039: /**
040: * @version 1.1.1
041: * @author TMate Software Ltd.
042: */
043: public class SVNInfoCommand extends SVNCommand implements
044: ISVNInfoHandler {
045:
046: private static final DateFormat DATE_FORMAT = new SimpleDateFormat(
047: "yyyy-MM-dd HH:mm:ss Z (EE, d MMM yyyy)", Locale
048: .getDefault());
049:
050: private PrintStream myOut;
051: private File myBaseFile;
052:
053: public void run(InputStream in, PrintStream out, PrintStream err)
054: throws SVNException {
055: run(out, err);
056: }
057:
058: public final void run(final PrintStream out, PrintStream err)
059: throws SVNException {
060: final boolean recursive = getCommandLine().hasArgument(
061: SVNArgument.RECURSIVE);
062: SVNRevision revision = SVNRevision.UNDEFINED;
063:
064: if (getCommandLine().hasArgument(SVNArgument.REVISION)) {
065: revision = SVNRevision.parse((String) getCommandLine()
066: .getArgumentValue(SVNArgument.REVISION));
067: }
068: SVNWCClient wcClient = getClientManager().getWCClient();
069: myOut = out;
070: SVNXMLSerializer serializer = new SVNXMLSerializer(myOut);
071: SVNXMLInfoHandler handler = new SVNXMLInfoHandler(serializer);
072: if (getCommandLine().hasArgument(SVNArgument.XML)
073: && !getCommandLine().hasArgument(
074: SVNArgument.INCREMENTAL)) {
075: handler.startDocument();
076: }
077: ISVNInfoHandler infoHandler = getCommandLine().hasArgument(
078: SVNArgument.XML) ? handler : (ISVNInfoHandler) this ;
079: for (int i = 0; i < getCommandLine().getPathCount(); i++) {
080: myBaseFile = new File(getCommandLine().getPathAt(i));
081: SVNRevision peg = getCommandLine().getPathPegRevision(i);
082: handler.setTargetPath(myBaseFile);
083: wcClient.doInfo(myBaseFile, peg, revision, recursive,
084: infoHandler);
085: }
086: myBaseFile = null;
087: for (int i = 0; i < getCommandLine().getURLCount(); i++) {
088: String url = getCommandLine().getURL(i);
089: SVNRevision peg = getCommandLine().getPegRevision(i);
090: wcClient.doInfo(SVNURL.parseURIEncoded(url), peg, revision,
091: recursive, infoHandler);
092: }
093: if (getCommandLine().hasArgument(SVNArgument.XML)
094: && !getCommandLine().hasArgument(
095: SVNArgument.INCREMENTAL)) {
096: handler.endDocument();
097: }
098: if (getCommandLine().hasArgument(SVNArgument.XML)) {
099: try {
100: serializer.flush();
101: } catch (IOException e) {
102: }
103: }
104: }
105:
106: private static void print(String str, PrintStream out) {
107: out.println(str);
108: }
109:
110: public void handleInfo(SVNInfo info) {
111: if (!info.isRemote()) {
112: print("Path: " + SVNFormatUtil.formatPath(info.getFile()),
113: myOut);
114: } else if (info.getPath() != null) {
115: String path = info.getPath();
116: if (myBaseFile != null) {
117: File file = new File(myBaseFile, path);
118: path = SVNFormatUtil.formatPath(file);
119: } else {
120: path = path.replace('/', File.separatorChar);
121: }
122: print("Path: " + path, myOut);
123: }
124: if (info.getKind() != SVNNodeKind.DIR) {
125: if (info.isRemote()) {
126: print("Name: " + SVNPathUtil.tail(info.getPath()),
127: myOut);
128: } else {
129: print("Name: " + info.getFile().getName(), myOut);
130: }
131: }
132: print("URL: " + info.getURL(), myOut);
133: if (info.getRepositoryRootURL() != null) {
134: print("Repository Root: " + info.getRepositoryRootURL(),
135: myOut);
136: }
137: if (info.isRemote() && info.getRepositoryUUID() != null) {
138: print("Repository UUID: " + info.getRepositoryUUID(), myOut);
139: }
140: if (info.getRevision() != null && info.getRevision().isValid()) {
141: print("Revision: " + info.getRevision(), myOut);
142: }
143: if (info.getKind() == SVNNodeKind.DIR) {
144: print("Node Kind: directory", myOut);
145: } else if (info.getKind() == SVNNodeKind.FILE) {
146: print("Node Kind: file", myOut);
147: } else if (info.getKind() == SVNNodeKind.NONE) {
148: print("Node Kind: none", myOut);
149: } else {
150: print("Node Kind: unknown", myOut);
151: }
152: if (info.getSchedule() == null && !info.isRemote()) {
153: print("Schedule: normal", myOut);
154: } else if (!info.isRemote()) {
155: print("Schedule: " + info.getSchedule(), myOut);
156: }
157: if (info.getAuthor() != null) {
158: print("Last Changed Author: " + info.getAuthor(), myOut);
159: }
160: if (info.getCommittedRevision() != null
161: && info.getCommittedRevision().getNumber() >= 0) {
162: print("Last Changed Rev: " + info.getCommittedRevision(),
163: myOut);
164: }
165: if (info.getCommittedDate() != null) {
166: print("Last Changed Date: "
167: + formatDate(info.getCommittedDate()), myOut);
168: }
169: if (!info.isRemote()) {
170: if (info.getTextTime() != null) {
171: print("Text Last Updated: "
172: + formatDate(info.getTextTime()), myOut);
173: }
174: if (info.getPropTime() != null) {
175: print("Properties Last Updated: "
176: + formatDate(info.getPropTime()), myOut);
177: }
178: if (info.getChecksum() != null) {
179: print("Checksum: " + info.getChecksum(), myOut);
180: }
181: if (info.getCopyFromURL() != null) {
182: print("Copied From URL: " + info.getCopyFromURL(),
183: myOut);
184: }
185: if (info.getCopyFromRevision() != null
186: && info.getCopyFromRevision().getNumber() >= 0) {
187: print("Copied From Rev: " + info.getCopyFromRevision(),
188: myOut);
189: }
190: if (info.getConflictOldFile() != null) {
191: print("Conflict Previous Base File: "
192: + info.getConflictOldFile().getName(), myOut);
193: }
194: if (info.getConflictWrkFile() != null) {
195: print("Conflict Previous Working File: "
196: + info.getConflictWrkFile().getName(), myOut);
197: }
198: if (info.getConflictNewFile() != null) {
199: print("Conflict Current Base File: "
200: + info.getConflictNewFile().getName(), myOut);
201: }
202: if (info.getPropConflictFile() != null) {
203: print("Conflict Properties File: "
204: + info.getPropConflictFile().getName(), myOut);
205: }
206: }
207: if (info.getLock() != null) {
208: SVNLock lock = info.getLock();
209: print("Lock Token: " + lock.getID(), myOut);
210: print("Lock Owner: " + lock.getOwner(), myOut);
211: print(
212: "Lock Created: "
213: + formatDate(lock.getCreationDate()), myOut);
214: if (lock.getComment() != null) {
215: myOut.print("Lock Comment ");
216: int lineCount = getLinesCount(lock.getComment());
217: if (lineCount == 1) {
218: myOut.print("(1 line)");
219: } else {
220: myOut.print("(" + lineCount + " lines)");
221: }
222: myOut.print(":\n" + lock.getComment() + "\n");
223: }
224: }
225: println(myOut);
226: }
227:
228: private static String formatDate(Date date) {
229: return DATE_FORMAT.format(date);
230: }
231: }
|