comparison src/org/tmatesoft/hg/core/HgIncomingCommand.java @ 215:41a778e3fd31

Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 17 May 2011 00:56:54 +0200
parents ef8eba4aa215
children 6d1804fe0ed7
comparison
equal deleted inserted replaced
214:4252faa556cd 215:41a778e3fd31
32 import org.tmatesoft.hg.repo.HgChangelog; 32 import org.tmatesoft.hg.repo.HgChangelog;
33 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset; 33 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
34 import org.tmatesoft.hg.repo.HgRemoteRepository; 34 import org.tmatesoft.hg.repo.HgRemoteRepository;
35 import org.tmatesoft.hg.repo.HgRepository; 35 import org.tmatesoft.hg.repo.HgRepository;
36 import org.tmatesoft.hg.util.CancelledException; 36 import org.tmatesoft.hg.util.CancelledException;
37 import org.tmatesoft.hg.util.ProgressSupport;
37 38
38 /** 39 /**
39 * Command to find out changes available in a remote repository, missing locally. 40 * Command to find out changes available in a remote repository, missing locally.
40 * 41 *
41 * @author Artem Tikhomirov 42 * @author Artem Tikhomirov
42 * @author TMate Software Ltd. 43 * @author TMate Software Ltd.
43 */ 44 */
44 public class HgIncomingCommand { 45 public class HgIncomingCommand extends HgAbstractCommand<HgIncomingCommand> {
45 46
46 private final HgRepository localRepo; 47 private final HgRepository localRepo;
47 private HgRemoteRepository remoteRepo; 48 private HgRemoteRepository remoteRepo;
48 @SuppressWarnings("unused") 49 @SuppressWarnings("unused")
49 private boolean includeSubrepo; 50 private boolean includeSubrepo;
96 97
97 /** 98 /**
98 * Lightweight check for incoming changes, gives only list of revisions to pull. 99 * Lightweight check for incoming changes, gives only list of revisions to pull.
99 * Reported changes are from any branch (limits set by {@link #branch(String)} are not taken into account. 100 * Reported changes are from any branch (limits set by {@link #branch(String)} are not taken into account.
100 * 101 *
101 * @param context anything hg4j can use to get progress and/or cancel support
102 * @return list of nodes present at remote and missing locally 102 * @return list of nodes present at remote and missing locally
103 * @throws HgException 103 * @throws HgException
104 * @throws CancelledException 104 * @throws CancelledException
105 */ 105 */
106 public List<Nodeid> executeLite(Object context) throws HgException, CancelledException { 106 public List<Nodeid> executeLite() throws HgException, CancelledException {
107 LinkedHashSet<Nodeid> result = new LinkedHashSet<Nodeid>(); 107 LinkedHashSet<Nodeid> result = new LinkedHashSet<Nodeid>();
108 RepositoryComparator repoCompare = getComparator(context); 108 RepositoryComparator repoCompare = getComparator();
109 for (BranchChain bc : getMissingBranches(context)) { 109 for (BranchChain bc : getMissingBranches()) {
110 List<Nodeid> missing = repoCompare.visitBranches(bc); 110 List<Nodeid> missing = repoCompare.visitBranches(bc);
111 HashSet<Nodeid> common = new HashSet<Nodeid>(); // ordering is irrelevant 111 HashSet<Nodeid> common = new HashSet<Nodeid>(); // ordering is irrelevant
112 repoCompare.collectKnownRoots(bc, common); 112 repoCompare.collectKnownRoots(bc, common);
113 // missing could only start with common elements. Once non-common, rest is just distinct branch revision trails. 113 // missing could only start with common elements. Once non-common, rest is just distinct branch revision trails.
114 for (Iterator<Nodeid> it = missing.iterator(); it.hasNext() && common.contains(it.next()); it.remove()) ; 114 for (Iterator<Nodeid> it = missing.iterator(); it.hasNext() && common.contains(it.next()); it.remove()) ;
122 * Full information about incoming changes 122 * Full information about incoming changes
123 * 123 *
124 * @throws HgException 124 * @throws HgException
125 * @throws CancelledException 125 * @throws CancelledException
126 */ 126 */
127 public void executeFull(final HgChangesetHandler handler) throws HgException, CancelledException { 127 public void executeFull(final HgChangesetHandler handler) throws HgException/*FIXME specific type*/, HgCallbackTargetException, CancelledException {
128 if (handler == null) { 128 if (handler == null) {
129 throw new IllegalArgumentException("Delegate can't be null"); 129 throw new IllegalArgumentException("Delegate can't be null");
130 } 130 }
131 final List<Nodeid> common = getCommon(handler); 131 final List<Nodeid> common = getCommon();
132 HgBundle changegroup = remoteRepo.getChanges(common); 132 HgBundle changegroup = remoteRepo.getChanges(common);
133 final ProgressSupport ps = getProgressSupport(handler);
133 try { 134 try {
135 final ChangesetTransformer transformer = new ChangesetTransformer(localRepo, handler, getParentHelper(), ps, getCancelSupport(handler));
136 transformer.limitBranches(branches);
134 changegroup.changes(localRepo, new HgChangelog.Inspector() { 137 changegroup.changes(localRepo, new HgChangelog.Inspector() {
135 private int localIndex; 138 private int localIndex;
136 private final HgChangelog.ParentWalker parentHelper; 139 private final HgChangelog.ParentWalker parentHelper;
137 private final ChangesetTransformer transformer;
138 140
139 { 141 {
140 transformer = new ChangesetTransformer(localRepo, handler, getParentHelper());
141 transformer.limitBranches(branches);
142 parentHelper = getParentHelper(); 142 parentHelper = getParentHelper();
143 // new revisions, if any, would be added after all existing, and would get numbered started with last+1 143 // new revisions, if any, would be added after all existing, and would get numbered started with last+1
144 localIndex = localRepo.getChangelog().getRevisionCount(); 144 localIndex = localRepo.getChangelog().getRevisionCount();
145 } 145 }
146 146
152 return; 152 return;
153 } 153 }
154 transformer.next(localIndex++, nodeid, cset); 154 transformer.next(localIndex++, nodeid, cset);
155 } 155 }
156 }); 156 });
157 transformer.checkFailure();
157 } catch (IOException ex) { 158 } catch (IOException ex) {
158 throw new HgException(ex); 159 throw new HgException(ex);
159 } 160 } finally {
160 } 161 ps.done();
161 162 }
162 private RepositoryComparator getComparator(Object context) throws HgException, CancelledException { 163 }
164
165 private RepositoryComparator getComparator() throws CancelledException {
163 if (remoteRepo == null) { 166 if (remoteRepo == null) {
164 throw new HgBadArgumentException("Shall specify remote repository to compare against", null); 167 throw new IllegalArgumentException("Shall specify remote repository to compare against", null);
165 } 168 }
166 if (comparator == null) { 169 if (comparator == null) {
167 comparator = new RepositoryComparator(getParentHelper(), remoteRepo); 170 comparator = new RepositoryComparator(getParentHelper(), remoteRepo);
168 // comparator.compare(context); // XXX meanwhile we use distinct path to calculate common 171 // comparator.compare(context); // XXX meanwhile we use distinct path to calculate common
169 } 172 }
176 parentHelper.init(); 179 parentHelper.init();
177 } 180 }
178 return parentHelper; 181 return parentHelper;
179 } 182 }
180 183
181 private List<BranchChain> getMissingBranches(Object context) throws HgException, CancelledException { 184 private List<BranchChain> getMissingBranches() throws HgRemoteConnectionException, CancelledException {
182 if (missingBranches == null) { 185 if (missingBranches == null) {
183 missingBranches = getComparator(context).calculateMissingBranches(); 186 missingBranches = getComparator().calculateMissingBranches();
184 } 187 }
185 return missingBranches; 188 return missingBranches;
186 } 189 }
187 190
188 private List<Nodeid> getCommon(Object context) throws HgException, CancelledException { 191 private List<Nodeid> getCommon() throws HgRemoteConnectionException, CancelledException {
189 // return getComparator(context).getCommon(); 192 // return getComparator(context).getCommon();
190 final LinkedHashSet<Nodeid> common = new LinkedHashSet<Nodeid>(); 193 final LinkedHashSet<Nodeid> common = new LinkedHashSet<Nodeid>();
191 // XXX common can be obtained from repoCompare, but at the moment it would almost duplicate work of calculateMissingBranches 194 // XXX common can be obtained from repoCompare, but at the moment it would almost duplicate work of calculateMissingBranches
192 // once I refactor latter, common shall be taken from repoCompare. 195 // once I refactor latter, common shall be taken from repoCompare.
193 RepositoryComparator repoCompare = getComparator(context); 196 RepositoryComparator repoCompare = getComparator();
194 for (BranchChain bc : getMissingBranches(context)) { 197 for (BranchChain bc : getMissingBranches()) {
195 repoCompare.collectKnownRoots(bc, common); 198 repoCompare.collectKnownRoots(bc, common);
196 } 199 }
197 return new LinkedList<Nodeid>(common); 200 return new LinkedList<Nodeid>(common);
198 } 201 }
199 } 202 }