Mercurial > jhg
comparison src/com/tmate/hgkit/ll/Changeset.java @ 47:b01500fe2604
Log command output to match 'hg log'
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> | 
|---|---|
| date | Fri, 14 Jan 2011 20:03:14 +0100 | 
| parents | 21e26da142fa | 
| children | 26e3eeaa3962 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 46:4022c34a4804 | 47:b01500fe2604 | 
|---|---|
| 3 */ | 3 */ | 
| 4 package com.tmate.hgkit.ll; | 4 package com.tmate.hgkit.ll; | 
| 5 | 5 | 
| 6 import java.io.UnsupportedEncodingException; | 6 import java.io.UnsupportedEncodingException; | 
| 7 import java.util.ArrayList; | 7 import java.util.ArrayList; | 
| 8 import java.util.Collections; | |
| 8 import java.util.Date; | 9 import java.util.Date; | 
| 10 import java.util.Formatter; | |
| 11 import java.util.List; | |
| 9 import java.util.Locale; | 12 import java.util.Locale; | 
| 13 import java.util.Map; | |
| 10 | 14 | 
| 11 /** | 15 /** | 
| 12 * @see mercurial/changelog.py:read() | 16 * @see mercurial/changelog.py:read() | 
| 13 * <pre> | 17 * <pre> | 
| 14 format used: | 18 format used: | 
| 22 | 26 | 
| 23 changelog v0 doesn't use extra | 27 changelog v0 doesn't use extra | 
| 24 * </pre> | 28 * </pre> | 
| 25 * @author artem | 29 * @author artem | 
| 26 */ | 30 */ | 
| 27 public class Changeset { | 31 public class Changeset implements Cloneable /*for those that would like to keep a copy*/ { | 
| 28 // TODO immutable | 32 // TODO immutable | 
| 29 private /*final*/ Nodeid manifest; | 33 private /*final*/ Nodeid manifest; | 
| 30 private String user; | 34 private String user; | 
| 31 private String comment; | 35 private String comment; | 
| 32 private ArrayList<String> files; | 36 private List<String> files; // unmodifiable collection (otherwise #files() and implicit #clone() shall be revised) | 
| 33 private Date time; | 37 private Date time; | 
| 38 private int timezone; // not sure it's of any use | |
| 34 private String extras; // TODO branch, etc. | 39 private String extras; // TODO branch, etc. | 
| 35 | 40 | 
| 36 public void dump() { | 41 private Changeset() { | 
| 37 System.out.println("User: " + user); | 42 } | 
| 38 System.out.println("Comment: " + comment); | 43 | 
| 39 System.out.println("Manifest: " + manifest); | 44 public Nodeid manifest() { | 
| 40 System.out.printf(Locale.US, "Date: %ta %<tb %<td %<tH:%<tM:%<tS %<tY %<tz\n", time); | 45 return manifest; | 
| 41 System.out.println("Files: " + files.size()); | 46 } | 
| 47 | |
| 48 public String user() { | |
| 49 return user; | |
| 50 } | |
| 51 | |
| 52 public String comment() { | |
| 53 return comment; | |
| 54 } | |
| 55 | |
| 56 public List<String> files() { | |
| 57 return files; | |
| 58 } | |
| 59 | |
| 60 public Date date() { | |
| 61 return time; | |
| 62 } | |
| 63 | |
| 64 public String dateString() { | |
| 65 StringBuilder sb = new StringBuilder(30); | |
| 66 Formatter f = new Formatter(sb, Locale.US); | |
| 67 f.format("%ta %<tb %<td %<tH:%<tM:%<tS %<tY %<tz", time); | |
| 68 return sb.toString(); | |
| 69 } | |
| 70 | |
| 71 public Map<String, String> extras() { | |
| 72 return null; // TODO | |
| 73 } | |
| 74 | |
| 75 @Override | |
| 76 public String toString() { | |
| 77 StringBuilder sb = new StringBuilder(); | |
| 78 sb.append("Changeset {"); | |
| 79 sb.append("User: ").append(user).append(", "); | |
| 80 sb.append("Comment: ").append(comment).append(", "); | |
| 81 sb.append("Manifest: ").append(manifest).append(", "); | |
| 82 sb.append("Date: ").append(time).append(", "); | |
| 83 sb.append("Files: ").append(files.size()); | |
| 84 for (String s : files) { | |
| 85 sb.append(", ").append(s); | |
| 86 } | |
| 42 if (extras != null) { | 87 if (extras != null) { | 
| 43 System.out.println("Extra: " + extras); | 88 sb.append(", Extra: ").append(extras); | 
| 44 } | 89 } | 
| 45 for (String s : files) { | 90 sb.append("}"); | 
| 46 System.out.print('\t'); | 91 return sb.toString(); | 
| 47 System.out.println(s); | |
| 48 } | |
| 49 } | 92 } | 
| 50 | 93 | 
| 51 public static Changeset parse(byte[] data, int offset, int length) { | 94 public static Changeset parse(byte[] data, int offset, int length) { | 
| 52 Changeset rv = new Changeset(); | 95 Changeset rv = new Changeset(); | 
| 53 rv.init(data, offset, length); | 96 rv.init(data, offset, length); | 
| 79 int space2 = _timeString.indexOf(' ', space1+1); | 122 int space2 = _timeString.indexOf(' ', space1+1); | 
| 80 if (space2 == -1) { | 123 if (space2 == -1) { | 
| 81 space2 = _timeString.length(); | 124 space2 = _timeString.length(); | 
| 82 } | 125 } | 
| 83 long unixTime = Long.parseLong(_timeString.substring(0, space1)); // XXX Float, perhaps | 126 long unixTime = Long.parseLong(_timeString.substring(0, space1)); // XXX Float, perhaps | 
| 84 int timezone = Integer.parseInt(_timeString.substring(space1+1, space2)); | 127 int _timezone = Integer.parseInt(_timeString.substring(space1+1, space2)); | 
| 85 // XXX not sure need to add timezone here - I can't figure out whether Hg keeps GMT time, and records timezone just for info, or unixTime is taken local | 128 // XXX not sure need to add timezone here - I can't figure out whether Hg keeps GMT time, and records timezone just for info, or unixTime is taken local | 
| 86 // on commit and timezone is recorded to adjust it to UTC. | 129 // on commit and timezone is recorded to adjust it to UTC. | 
| 87 Date _time = new Date((unixTime + timezone) * 1000); | 130 Date _time = new Date(unixTime * 1000); | 
| 88 String _extras = space2 < _timeString.length() ? _timeString.substring(space2+1) : null; | 131 String _extras = space2 < _timeString.length() ? _timeString.substring(space2+1) : null; | 
| 89 | 132 | 
| 90 // | 133 // | 
| 91 int lastStart = breakIndex3 + 1; | 134 int lastStart = breakIndex3 + 1; | 
| 92 int breakIndex4 = indexOf(data, lineBreak, lastStart, bufferEndIndex); | 135 int breakIndex4 = indexOf(data, lineBreak, lastStart, bufferEndIndex); | 
| 113 } | 156 } | 
| 114 // change this instance at once, don't leave it partially changes in case of error | 157 // change this instance at once, don't leave it partially changes in case of error | 
| 115 this.manifest = _nodeid; | 158 this.manifest = _nodeid; | 
| 116 this.user = _user; | 159 this.user = _user; | 
| 117 this.time = _time; | 160 this.time = _time; | 
| 118 this.files = _files; | 161 this.timezone = _timezone; | 
| 162 this.files = Collections.unmodifiableList(_files); | |
| 119 this.comment = _comment; | 163 this.comment = _comment; | 
| 120 this.extras = _extras; | 164 this.extras = _extras; | 
| 121 } | 165 } | 
| 122 | 166 | 
| 123 private static int indexOf(byte[] src, byte what, int startOffset, int endIndex) { | 167 private static int indexOf(byte[] src, byte what, int startOffset, int endIndex) { | 
| 130 } | 174 } | 
| 131 | 175 | 
| 132 public interface Inspector { | 176 public interface Inspector { | 
| 133 // first(), last(), single(). | 177 // first(), last(), single(). | 
| 134 // <T> | 178 // <T> | 
| 135 void next(Changeset cset); | 179 // TODO describe whether cset is new instance each time | 
| 180 void next(int revisionNumber, Nodeid nodeid, Changeset cset); | |
| 136 } | 181 } | 
| 137 } | 182 } | 
