annotate src/org/tmatesoft/hg/repo/HgRemoteRepository.java @ 434:7e1912b4ce99 v0.9.0

Record few known issues while skimming through TODOs
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 30 Mar 2012 17:11:39 +0200
parents ead6c67f3319
children 2a08466838d3
rev   line source
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
407
30922c728341 Better multiline log printout; options to tune default log output
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
2 * Copyright (c) 2011-2012 TMate Software Ltd
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.repo;
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
428
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
19 import java.io.BufferedReader;
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
20 import java.io.File;
179
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
21 import java.io.FileOutputStream;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
22 import java.io.IOException;
179
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
23 import java.io.InputStream;
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
24 import java.io.InputStreamReader;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
25 import java.io.OutputStream;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
26 import java.io.StreamTokenizer;
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
27 import java.net.HttpURLConnection;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
28 import java.net.MalformedURLException;
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
29 import java.net.URL;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
30 import java.net.URLConnection;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
31 import java.security.cert.CertificateException;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
32 import java.security.cert.X509Certificate;
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
33 import java.util.ArrayList;
428
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
34 import java.util.Arrays;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
35 import java.util.Collection;
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
36 import java.util.Collections;
428
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
37 import java.util.HashSet;
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
38 import java.util.Iterator;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
39 import java.util.LinkedHashMap;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
40 import java.util.LinkedList;
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41 import java.util.List;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
42 import java.util.Map;
428
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
43 import java.util.Set;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
44 import java.util.prefs.BackingStoreException;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
45 import java.util.prefs.Preferences;
179
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
46 import java.util.zip.InflaterInputStream;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
47
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
48 import javax.net.ssl.HttpsURLConnection;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
49 import javax.net.ssl.SSLContext;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
50 import javax.net.ssl.TrustManager;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
51 import javax.net.ssl.X509TrustManager;
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
52
181
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
53 import org.tmatesoft.hg.core.HgBadArgumentException;
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
54 import org.tmatesoft.hg.core.HgRemoteConnectionException;
425
48f993aa2f41 FIXMEs: exceptions, javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
55 import org.tmatesoft.hg.core.HgRepositoryNotFoundException;
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 import org.tmatesoft.hg.core.Nodeid;
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 274
diff changeset
57 import org.tmatesoft.hg.core.SessionContext;
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
58
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
59 /**
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
60 * WORK IN PROGRESS, DO NOT USE
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 *
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62 * @see http://mercurial.selenic.com/wiki/WireProtocol
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
63 *
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
64 * @author Artem Tikhomirov
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
65 * @author TMate Software Ltd.
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
66 */
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
67 public class HgRemoteRepository {
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
68
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
69 private final URL url;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
70 private final SSLContext sslContext;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
71 private final String authInfo;
407
30922c728341 Better multiline log printout; options to tune default log output
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
72 private final boolean debug;
186
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
73 private HgLookup lookupHelper;
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 274
diff changeset
74 private final SessionContext sessionContext;
428
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
75 private Set<String> remoteCapabilities;
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
76
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 274
diff changeset
77 HgRemoteRepository(SessionContext ctx, URL url) throws HgBadArgumentException {
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 274
diff changeset
78 if (url == null || ctx == null) {
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
79 throw new IllegalArgumentException();
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
80 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
81 this.url = url;
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 274
diff changeset
82 sessionContext = ctx;
407
30922c728341 Better multiline log printout; options to tune default log output
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
83 Object debugProp = ctx.getProperty("hg4j.remote.debug", false);
30922c728341 Better multiline log printout; options to tune default log output
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
84 debug = debugProp instanceof Boolean ? ((Boolean) debugProp).booleanValue() : Boolean.parseBoolean(String.valueOf(debugProp));
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
85 if ("https".equals(url.getProtocol())) {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
86 try {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
87 sslContext = SSLContext.getInstance("SSL");
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
88 class TrustEveryone implements X509TrustManager {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
89 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
207
1bf0a5af2d5d Conditional debug printouts
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 203
diff changeset
90 if (debug) {
1bf0a5af2d5d Conditional debug printouts
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 203
diff changeset
91 System.out.println("checkClientTrusted:" + authType);
1bf0a5af2d5d Conditional debug printouts
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 203
diff changeset
92 }
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
93 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
94 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
207
1bf0a5af2d5d Conditional debug printouts
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 203
diff changeset
95 if (debug) {
1bf0a5af2d5d Conditional debug printouts
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 203
diff changeset
96 System.out.println("checkServerTrusted:" + authType);
1bf0a5af2d5d Conditional debug printouts
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 203
diff changeset
97 }
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
98 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
99 public X509Certificate[] getAcceptedIssuers() {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
100 return new X509Certificate[0];
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
101 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
102 };
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
103 sslContext.init(null, new TrustManager[] { new TrustEveryone() }, null);
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
104 } catch (Exception ex) {
181
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
105 throw new HgBadArgumentException("Can't initialize secure connection", ex);
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
106 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
107 } else {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
108 sslContext = null;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
109 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
110 if (url.getUserInfo() != null) {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
111 String ai = null;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
112 try {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
113 // Hack to get Base64-encoded credentials
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
114 Preferences tempNode = Preferences.userRoot().node("xxx");
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
115 tempNode.putByteArray("xxx", url.getUserInfo().getBytes());
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
116 ai = tempNode.get("xxx", null);
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
117 tempNode.removeNode();
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
118 } catch (BackingStoreException ex) {
357
dfb8405d996f Clean debug stacktraces
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
119 sessionContext.getLog().info(getClass(), ex, null);
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
120 // IGNORE
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
121 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
122 authInfo = ai;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
123 } else {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
124 authInfo = null;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
125 }
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
126 }
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
127
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
128 public boolean isInvalid() throws HgRemoteConnectionException {
428
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
129 if (remoteCapabilities == null) {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
130 remoteCapabilities = new HashSet<String>();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
131 // say hello to server, check response
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
132 try {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
133 URL u = new URL(url, url.getPath() + "?cmd=hello");
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
134 HttpURLConnection c = setupConnection(u.openConnection());
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
135 c.connect();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
136 if (debug) {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
137 dumpResponseHeader(u, c);
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
138 }
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
139 BufferedReader r = new BufferedReader(new InputStreamReader(c.getInputStream(), "US-ASCII"));
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
140 String line = r.readLine();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
141 c.disconnect();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
142 final String capsPrefix = "capabilities:";
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
143 if (line == null || !line.startsWith(capsPrefix)) {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
144 // for whatever reason, some servers do not respond to hello command (e.g. svnkit)
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
145 // but respond to 'capabilities' instead. Try it.
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
146 // TODO [post-1.0] tests needed
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
147 u = new URL(url, url.getPath() + "?cmd=capabilities");
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
148 c = setupConnection(u.openConnection());
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
149 c.connect();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
150 if (debug) {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
151 dumpResponseHeader(u, c);
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
152 }
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
153 r = new BufferedReader(new InputStreamReader(c.getInputStream(), "US-ASCII"));
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
154 line = r.readLine();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
155 c.disconnect();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
156 if (line == null || line.trim().isEmpty()) {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
157 return true;
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
158 }
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
159 } else {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
160 line = line.substring(capsPrefix.length()).trim();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
161 }
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
162 String[] caps = line.split("\\s");
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
163 remoteCapabilities.addAll(Arrays.asList(caps));
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
164 c.disconnect();
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
165 } catch (MalformedURLException ex) {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
166 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("hello").setServerInfo(getLocation());
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
167 } catch (IOException ex) {
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
168 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("hello").setServerInfo(getLocation());
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
169 }
181
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
170 }
428
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
171 return remoteCapabilities.isEmpty();
181
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
172 }
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
173
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
174 /**
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
175 * @return human-readable address of the server, without user credentials or any other security information
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
176 */
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
177 public String getLocation() {
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
178 if (url.getUserInfo() == null) {
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
179 return url.toExternalForm();
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
180 }
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
181 if (url.getPort() != -1) {
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
182 return String.format("%s://%s:%d%s", url.getProtocol(), url.getHost(), url.getPort(), url.getPath());
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
183 } else {
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
184 return String.format("%s://%s%s", url.getProtocol(), url.getHost(), url.getPath());
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
185 }
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
186 }
cd3371670f0b Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 179
diff changeset
187
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
188 public List<Nodeid> heads() throws HgRemoteConnectionException {
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
189 try {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
190 URL u = new URL(url, url.getPath() + "?cmd=heads");
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
191 HttpURLConnection c = setupConnection(u.openConnection());
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
192 c.connect();
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
193 if (debug) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
194 dumpResponseHeader(u, c);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
195 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
196 InputStreamReader is = new InputStreamReader(c.getInputStream(), "US-ASCII");
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
197 StreamTokenizer st = new StreamTokenizer(is);
428
ead6c67f3319 Actual 'hello' check of the remote server/connection
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 425
diff changeset
198 st.ordinaryChars('0', '9'); // wordChars performs |, hence need to 0 first
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
199 st.wordChars('0', '9');
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
200 st.eolIsSignificant(false);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
201 LinkedList<Nodeid> parseResult = new LinkedList<Nodeid>();
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
202 while (st.nextToken() != StreamTokenizer.TT_EOF) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
203 parseResult.add(Nodeid.fromAscii(st.sval));
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
204 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
205 return parseResult;
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
206 } catch (MalformedURLException ex) {
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
207 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("heads").setServerInfo(getLocation());
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
208 } catch (IOException ex) {
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
209 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("heads").setServerInfo(getLocation());
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
210 }
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
211 }
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
212
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
213 public List<Nodeid> between(Nodeid tip, Nodeid base) throws HgRemoteConnectionException {
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
214 Range r = new Range(base, tip);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
215 // XXX shall handle errors like no range key in the returned map, not sure how.
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
216 return between(Collections.singletonList(r)).get(r);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
217 }
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
218
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
219 /**
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
220 * @param ranges
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
221 * @return map, where keys are input instances, values are corresponding server reply
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
222 * @throws HgRemoteConnectionException
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
223 */
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
224 public Map<Range, List<Nodeid>> between(Collection<Range> ranges) throws HgRemoteConnectionException {
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
225 if (ranges.isEmpty()) {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
226 return Collections.emptyMap();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
227 }
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
228 // if fact, shall do other way round, this method shall send
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
229 LinkedHashMap<Range, List<Nodeid>> rv = new LinkedHashMap<HgRemoteRepository.Range, List<Nodeid>>(ranges.size() * 4 / 3);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
230 StringBuilder sb = new StringBuilder(20 + ranges.size() * 82);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
231 sb.append("pairs=");
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
232 for (Range r : ranges) {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
233 sb.append(r.end.toString());
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
234 sb.append('-');
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
235 sb.append(r.start.toString());
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
236 sb.append('+');
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
237 }
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
238 if (sb.charAt(sb.length() - 1) == '+') {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
239 // strip last space
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
240 sb.setLength(sb.length() - 1);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
241 }
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
242 try {
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
243 boolean usePOST = ranges.size() > 3;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
244 URL u = new URL(url, url.getPath() + "?cmd=between" + (usePOST ? "" : '&' + sb.toString()));
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
245 HttpURLConnection c = setupConnection(u.openConnection());
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
246 if (usePOST) {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
247 c.setRequestMethod("POST");
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
248 c.setRequestProperty("Content-Length", String.valueOf(sb.length()/*nodeids are ASCII, bytes == characters */));
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
249 c.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
250 c.setDoOutput(true);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
251 c.connect();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
252 OutputStream os = c.getOutputStream();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
253 os.write(sb.toString().getBytes());
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
254 os.flush();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
255 os.close();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
256 } else {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
257 c.connect();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
258 }
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
259 if (debug) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
260 System.out.printf("%d ranges, method:%s \n", ranges.size(), c.getRequestMethod());
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
261 dumpResponseHeader(u, c);
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
262 }
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
263 InputStreamReader is = new InputStreamReader(c.getInputStream(), "US-ASCII");
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
264 StreamTokenizer st = new StreamTokenizer(is);
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
265 st.ordinaryChars('0', '9');
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
266 st.wordChars('0', '9');
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
267 st.eolIsSignificant(true);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
268 Iterator<Range> rangeItr = ranges.iterator();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
269 LinkedList<Nodeid> currRangeList = null;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
270 Range currRange = null;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
271 boolean possiblyEmptyNextLine = true;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
272 while (st.nextToken() != StreamTokenizer.TT_EOF) {
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
273 if (st.ttype == StreamTokenizer.TT_EOL) {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
274 if (possiblyEmptyNextLine) {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
275 // newline follows newline;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
276 assert currRange == null;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
277 assert currRangeList == null;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
278 if (!rangeItr.hasNext()) {
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 414
diff changeset
279 throw new HgInvalidStateException("Internal error"); // TODO revisit-1.1
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
280 }
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
281 rv.put(rangeItr.next(), Collections.<Nodeid>emptyList());
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
282 } else {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
283 if (currRange == null || currRangeList == null) {
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 414
diff changeset
284 throw new HgInvalidStateException("Internal error"); // TODO revisit-1.1
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
285 }
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
286 // indicate next range value is needed
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
287 currRange = null;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
288 currRangeList = null;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
289 possiblyEmptyNextLine = true;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
290 }
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
291 } else {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
292 possiblyEmptyNextLine = false;
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
293 if (currRange == null) {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
294 if (!rangeItr.hasNext()) {
423
9c9c442b5f2e Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 414
diff changeset
295 throw new HgInvalidStateException("Internal error"); // TODO revisit-1.1
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
296 }
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
297 currRange = rangeItr.next();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
298 currRangeList = new LinkedList<Nodeid>();
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
299 rv.put(currRange, currRangeList);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
300 }
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
301 Nodeid nid = Nodeid.fromAscii(st.sval);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
302 currRangeList.addLast(nid);
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
303 }
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
304 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
305 is.close();
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
306 return rv;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
307 } catch (MalformedURLException ex) {
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
308 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("between").setServerInfo(getLocation());
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
309 } catch (IOException ex) {
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
310 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("between").setServerInfo(getLocation());
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
311 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
312 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
313
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
314 public List<RemoteBranch> branches(List<Nodeid> nodes) throws HgRemoteConnectionException {
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
315 StringBuilder sb = new StringBuilder(20 + nodes.size() * 41);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
316 sb.append("nodes=");
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
317 for (Nodeid n : nodes) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
318 sb.append(n.toString());
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
319 sb.append('+');
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
320 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
321 if (sb.charAt(sb.length() - 1) == '+') {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
322 // strip last space
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
323 sb.setLength(sb.length() - 1);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
324 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
325 try {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
326 URL u = new URL(url, url.getPath() + "?cmd=branches&" + sb.toString());
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
327 HttpURLConnection c = setupConnection(u.openConnection());
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
328 c.connect();
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
329 if (debug) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
330 dumpResponseHeader(u, c);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
331 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
332 InputStreamReader is = new InputStreamReader(c.getInputStream(), "US-ASCII");
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
333 StreamTokenizer st = new StreamTokenizer(is);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
334 st.ordinaryChars('0', '9');
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
335 st.wordChars('0', '9');
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
336 st.eolIsSignificant(false);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
337 ArrayList<Nodeid> parseResult = new ArrayList<Nodeid>(nodes.size() * 4);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
338 while (st.nextToken() != StreamTokenizer.TT_EOF) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
339 parseResult.add(Nodeid.fromAscii(st.sval));
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
340 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
341 if (parseResult.size() != nodes.size() * 4) {
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
342 throw new HgRemoteConnectionException(String.format("Bad number of nodeids in result (shall be factor 4), expected %d, got %d", nodes.size()*4, parseResult.size()));
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
343 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
344 ArrayList<RemoteBranch> rv = new ArrayList<RemoteBranch>(nodes.size());
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
345 for (int i = 0; i < nodes.size(); i++) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
346 RemoteBranch rb = new RemoteBranch(parseResult.get(i*4), parseResult.get(i*4 + 1), parseResult.get(i*4 + 2), parseResult.get(i*4 + 3));
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
347 rv.add(rb);
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
348 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
349 return rv;
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
350 } catch (MalformedURLException ex) {
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
351 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("branches").setServerInfo(getLocation());
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
352 } catch (IOException ex) {
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
353 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("branches").setServerInfo(getLocation());
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
354 }
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
355 }
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
356
186
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
357 /*
202
706bcc7cfee4 Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 190
diff changeset
358 * XXX need to describe behavior when roots arg is empty; our RepositoryComparator code currently returns empty lists when
706bcc7cfee4 Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 190
diff changeset
359 * no common elements found, which in turn means we need to query changes starting with NULL nodeid.
706bcc7cfee4 Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 190
diff changeset
360 *
186
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
361 * WireProtocol wiki: roots = a list of the latest nodes on every service side changeset branch that both the client and server know about.
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
362 *
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
363 * Perhaps, shall be named 'changegroup'
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
364
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
365 * Changegroup:
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
366 * http://mercurial.selenic.com/wiki/Merge
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
367 * http://mercurial.selenic.com/wiki/WireProtocol
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
368 *
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
369 * according to latter, bundleformat data is sent through zlib
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
370 * (there's no header like HG10?? with the server output, though,
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
371 * as one may expect according to http://mercurial.selenic.com/wiki/BundleFormat)
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
372 */
425
48f993aa2f41 FIXMEs: exceptions, javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
373 public HgBundle getChanges(List<Nodeid> roots) throws HgRemoteConnectionException, HgRuntimeException {
202
706bcc7cfee4 Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 190
diff changeset
374 List<Nodeid> _roots = roots.isEmpty() ? Collections.singletonList(Nodeid.NULL) : roots;
706bcc7cfee4 Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 190
diff changeset
375 StringBuilder sb = new StringBuilder(20 + _roots.size() * 41);
179
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
376 sb.append("roots=");
202
706bcc7cfee4 Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 190
diff changeset
377 for (Nodeid n : _roots) {
179
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
378 sb.append(n.toString());
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
379 sb.append('+');
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
380 }
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
381 if (sb.charAt(sb.length() - 1) == '+') {
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
382 // strip last space
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
383 sb.setLength(sb.length() - 1);
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
384 }
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
385 try {
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
386 URL u = new URL(url, url.getPath() + "?cmd=changegroup&" + sb.toString());
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
387 HttpURLConnection c = setupConnection(u.openConnection());
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
388 c.connect();
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
389 if (debug) {
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
390 dumpResponseHeader(u, c);
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
391 }
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
392 File tf = writeBundle(c.getInputStream(), false, "HG10GZ" /*didn't see any other that zip*/);
190
9b99d27aeddc More debug printouts
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 186
diff changeset
393 if (debug) {
210
6a2481866491 Wrong parent assignment when building branch chain
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 207
diff changeset
394 System.out.printf("Wrote bundle %s for roots %s\n", tf, sb);
190
9b99d27aeddc More debug printouts
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 186
diff changeset
395 }
186
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
396 return getLookupHelper().loadBundle(tf);
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
397 } catch (MalformedURLException ex) { // XXX in fact, this exception might be better to be re-thrown as RuntimeEx,
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
398 // as there's little user can do about this issue (URLs are constructed by our code)
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
399 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("changegroup").setServerInfo(getLocation());
179
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
400 } catch (IOException ex) {
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 210
diff changeset
401 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("changegroup").setServerInfo(getLocation());
425
48f993aa2f41 FIXMEs: exceptions, javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
402 } catch (HgRepositoryNotFoundException ex) {
48f993aa2f41 FIXMEs: exceptions, javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 423
diff changeset
403 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("changegroup").setServerInfo(getLocation());
179
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
404 }
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
405 }
186
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
406
203
66fd2c73c56f Basic test for HgOutgoingCommand. Handle cases with no outgoing changes in RepositoryComparator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 202
diff changeset
407 @Override
66fd2c73c56f Basic test for HgOutgoingCommand. Handle cases with no outgoing changes in RepositoryComparator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 202
diff changeset
408 public String toString() {
66fd2c73c56f Basic test for HgOutgoingCommand. Handle cases with no outgoing changes in RepositoryComparator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 202
diff changeset
409 return getClass().getSimpleName() + '[' + getLocation() + ']';
66fd2c73c56f Basic test for HgOutgoingCommand. Handle cases with no outgoing changes in RepositoryComparator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 202
diff changeset
410 }
66fd2c73c56f Basic test for HgOutgoingCommand. Handle cases with no outgoing changes in RepositoryComparator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 202
diff changeset
411
186
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
412 private HgLookup getLookupHelper() {
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
413 if (lookupHelper == null) {
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 274
diff changeset
414 lookupHelper = new HgLookup(sessionContext);
186
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
415 }
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
416 return lookupHelper;
44a34baabea0 Clone refactored into a command. HgBundle needs means to control its lifecycle, to be deleted when no longer needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 184
diff changeset
417 }
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
418
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
419 private HttpURLConnection setupConnection(URLConnection urlConnection) {
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
420 urlConnection.setRequestProperty("User-Agent", "hg4j/0.5.0");
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
421 urlConnection.addRequestProperty("Accept", "application/mercurial-0.1");
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
422 if (authInfo != null) {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
423 urlConnection.addRequestProperty("Authorization", "Basic " + authInfo);
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
424 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
425 if (sslContext != null) {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
426 ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslContext.getSocketFactory());
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
427 }
177
e10225daface Use POST for long between queries. Batch between queries (pass multiple pairs to a server) to minimize number thereof
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 176
diff changeset
428 return (HttpURLConnection) urlConnection;
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
429 }
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
430
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
431 private void dumpResponseHeader(URL u, HttpURLConnection c) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
432 System.out.printf("Query (%d bytes):%s\n", u.getQuery().length(), u.getQuery());
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
433 System.out.println("Response headers:");
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
434 final Map<String, List<String>> headerFields = c.getHeaderFields();
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
435 for (String s : headerFields.keySet()) {
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
436 System.out.printf("%s: %s\n", s, c.getHeaderField(s));
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
437 }
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
438 }
179
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
439
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
440 private static File writeBundle(InputStream is, boolean decompress, String header) throws IOException {
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
441 InputStream zipStream = decompress ? new InflaterInputStream(is) : is;
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
442 File tf = File.createTempFile("hg-bundle-", null);
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
443 FileOutputStream fos = new FileOutputStream(tf);
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
444 fos.write(header.getBytes());
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
445 int r;
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
446 byte[] buf = new byte[8*1024];
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
447 while ((r = zipStream.read(buf)) != -1) {
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
448 fos.write(buf, 0, r);
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
449 }
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
450 fos.close();
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
451 zipStream.close();
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
452 return tf;
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
453 }
da426c2fe1ec Support for changegroup wire command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 178
diff changeset
454
178
62665d8f0686 Complete logic to discover all branches missing locally. Most of wire protocol in HgRemoteRepository
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 177
diff changeset
455
176
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
456 public static final class Range {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
457 /**
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
458 * Root of the range, earlier revision
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
459 */
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
460 public final Nodeid start;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
461 /**
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
462 * Head of the range, later revision.
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
463 */
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
464 public final Nodeid end;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
465
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
466 /**
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
467 * @param from - root/base revision
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
468 * @param to - head/tip revision
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
469 */
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
470 public Range(Nodeid from, Nodeid to) {
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
471 start = from;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
472 end = to;
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
473 }
a8df7162ec75 Extracting complete branch using remote between call to detect incoming changes is done. Arguments reorderd in remote repo to better match Hg server ideology, not my mental convenience
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 172
diff changeset
474 }
184
ec1820f64d2b Complete incoming cmdline client, with both lite (revisions) and complete (full changeset) information dump
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 181
diff changeset
475
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
476 public static final class RemoteBranch {
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
477 public final Nodeid head, root, p1, p2;
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
478
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
479 public RemoteBranch(Nodeid h, Nodeid r, Nodeid parent1, Nodeid parent2) {
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
480 head = h;
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
481 root = r;
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
482 p1 = parent1;
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
483 p2 = parent2;
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
484 }
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
485
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
486 @Override
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
487 public boolean equals(Object obj) {
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
488 if (this == obj) {
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
489 return true;
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
490 }
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
491 if (false == obj instanceof RemoteBranch) {
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
492 return false;
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
493 }
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
494 RemoteBranch o = (RemoteBranch) obj;
274
9fb50c04f03c Use Nodeid.isNull check instead of NULL.equals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 215
diff changeset
495 // in fact, p1 and p2 are not supposed to be null, ever (at least for RemoteBranch created from server output)
171
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
496 return head.equals(o.head) && root.equals(o.root) && (p1 == null && o.p1 == null || p1.equals(o.p1)) && (p2 == null && o.p2 == null || p2.equals(o.p2));
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
497 }
2c3e96674e2a Towards outgoing changes - initial detection logic, get connected with remote repo stub
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
498 }
170
71ddbf8603e8 Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
499 }