comparison src/org/tmatesoft/hg/core/HgAnnotateCommand.java @ 566:32453f30de07 v1.1m3

Annotate command with command-line example
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 09 Apr 2013 19:25:34 +0200
parents
children c4fd1037bc6f
comparison
equal deleted inserted replaced
565:78a9e26e670d 566:32453f30de07
1 /*
2 * Copyright (c) 2013 TMate Software Ltd
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * For information on how to redistribute this software under
14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com
16 */
17 package org.tmatesoft.hg.core;
18
19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION;
20
21 import java.util.Arrays;
22
23 import org.tmatesoft.hg.internal.Callback;
24 import org.tmatesoft.hg.internal.CsetParamKeeper;
25 import org.tmatesoft.hg.internal.Experimental;
26 import org.tmatesoft.hg.internal.FileAnnotation;
27 import org.tmatesoft.hg.internal.FileAnnotation.LineDescriptor;
28 import org.tmatesoft.hg.internal.FileAnnotation.LineInspector;
29 import org.tmatesoft.hg.repo.HgBlameFacility.BlockData;
30 import org.tmatesoft.hg.repo.HgDataFile;
31 import org.tmatesoft.hg.repo.HgRepository;
32 import org.tmatesoft.hg.util.CancelledException;
33
34 /**
35 * WORK IN PROGRESS. UNSTABLE API
36 *
37 * 'hg annotate' counterpart, report origin revision and file line-by-line
38 *
39 * @author Artem Tikhomirov
40 * @author TMate Software Ltd.
41 */
42 @Experimental(reason="Work in progress. Unstable API")
43 public class HgAnnotateCommand extends HgAbstractCommand<HgAnnotateCommand> {
44
45 private final HgRepository repo;
46 private final CsetParamKeeper annotateRevision;
47 private HgDataFile file;
48
49 public HgAnnotateCommand(HgRepository hgRepo) {
50 repo = hgRepo;
51 annotateRevision = new CsetParamKeeper(repo);
52 annotateRevision.doSet(HgRepository.TIP);
53 }
54
55 public HgAnnotateCommand changeset(Nodeid nodeid) throws HgBadArgumentException {
56 annotateRevision.set(nodeid);
57 return this;
58 }
59
60 public HgAnnotateCommand changeset(int changelogRevIndex) throws HgBadArgumentException {
61 annotateRevision.set(changelogRevIndex);
62 return this;
63 }
64
65 public HgAnnotateCommand file(HgDataFile fileNode) {
66 file = fileNode;
67 return this;
68 }
69
70 // TODO [1.1] set encoding and provide String line content from LineInfo
71
72 // FIXME [1.1] follow and no-follow parameters
73
74 public void execute(Inspector inspector) throws HgException, HgCallbackTargetException, CancelledException {
75 if (inspector == null) {
76 throw new IllegalArgumentException();
77 }
78 if (file == null) {
79 throw new HgBadArgumentException("Command needs file argument", null);
80 }
81 Collector c = new Collector();
82 FileAnnotation.annotate(file, annotateRevision.get(), c);
83 LineImpl li = new LineImpl();
84 for (int i = 0; i < c.lineRevisions.length; i++) {
85 li.init(i+1, c.lineRevisions[i], c.line(i));
86 inspector.next(li);
87 }
88 }
89
90 /**
91 * Callback to receive annotated lines
92 */
93 @Callback
94 public interface Inspector {
95 // start(FileDescriptor);
96 void next(LineInfo lineInfo);
97 // end(FileDescriptor);
98 }
99
100 /**
101 * Describes a line reported through {@link Inspector#next(LineInfo)}
102 *
103 * Clients shall not implement this interface
104 */
105 public interface LineInfo {
106 int getLineNumber();
107 int getChangesetIndex();
108 byte[] getContent();
109 }
110
111 // FIXME there's no need in FileAnnotation.LineInspector, merge it here
112 private static class Collector implements LineInspector {
113 private int[] lineRevisions;
114 private byte[][] lines;
115
116 Collector() {
117 }
118
119 public void line(int lineNumber, int changesetRevIndex, BlockData lineContent, LineDescriptor ld) {
120 if (lineRevisions == null) {
121 lineRevisions = new int [ld.totalLines()];
122 Arrays.fill(lineRevisions, NO_REVISION);
123 lines = new byte[ld.totalLines()][];
124 }
125 lineRevisions[lineNumber] = changesetRevIndex;
126 lines[lineNumber] = lineContent.asArray();
127 }
128
129 public byte[] line(int i) {
130 return lines[i];
131 }
132 }
133
134
135 private static class LineImpl implements LineInfo {
136 private int ln;
137 private int rev;
138 private byte[] content;
139
140 void init(int line, int csetRev, byte[] cnt) {
141 ln = line;
142 rev = csetRev;
143 content = cnt;
144 }
145
146 public int getLineNumber() {
147 return ln;
148 }
149
150 public int getChangesetIndex() {
151 return rev;
152 }
153
154 public byte[] getContent() {
155 return content;
156 }
157 }
158 }