comparison src/org/tmatesoft/hg/repo/HgRemoteRepository.java @ 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
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Sat, 02 Apr 2011 03:01:14 +0200
parents 87f40938c9b2
children e10225daface
comparison
equal deleted inserted replaced
175:7653bdf82cf0 176:a8df7162ec75
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.repo; 17 package org.tmatesoft.hg.repo;
18 18
19 import java.io.File; 19 import java.io.File;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.StreamTokenizer;
23 import java.net.MalformedURLException;
20 import java.net.URL; 24 import java.net.URL;
25 import java.net.URLConnection;
26 import java.security.cert.CertificateException;
27 import java.security.cert.X509Certificate;
28 import java.util.Collection;
21 import java.util.Collections; 29 import java.util.Collections;
30 import java.util.LinkedHashMap;
31 import java.util.LinkedList;
22 import java.util.List; 32 import java.util.List;
33 import java.util.Map;
34 import java.util.prefs.BackingStoreException;
35 import java.util.prefs.Preferences;
36
37 import javax.net.ssl.HttpsURLConnection;
38 import javax.net.ssl.SSLContext;
39 import javax.net.ssl.TrustManager;
40 import javax.net.ssl.X509TrustManager;
23 41
24 import org.tmatesoft.hg.core.HgException; 42 import org.tmatesoft.hg.core.HgException;
25 import org.tmatesoft.hg.core.Nodeid; 43 import org.tmatesoft.hg.core.Nodeid;
26 44
27 /** 45 /**
32 * @author Artem Tikhomirov 50 * @author Artem Tikhomirov
33 * @author TMate Software Ltd. 51 * @author TMate Software Ltd.
34 */ 52 */
35 public class HgRemoteRepository { 53 public class HgRemoteRepository {
36 54
37 HgRemoteRepository(URL url) { 55 private final URL url;
56 private final SSLContext sslContext;
57 private final String authInfo;
58
59 HgRemoteRepository(URL url) throws HgException {
60 if (url == null) {
61 throw new IllegalArgumentException();
62 }
63 this.url = url;
64 if ("https".equals(url.getProtocol())) {
65 try {
66 sslContext = SSLContext.getInstance("SSL");
67 class TrustEveryone implements X509TrustManager {
68 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
69 System.out.println("checkClientTrusted " + authType);
70 }
71 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
72 System.out.println("checkServerTrusted" + authType);
73 }
74 public X509Certificate[] getAcceptedIssuers() {
75 return new X509Certificate[0];
76 }
77 };
78 sslContext.init(null, new TrustManager[] { new TrustEveryone() }, null);
79 } catch (Exception ex) {
80 throw new HgException(ex);
81 }
82 } else {
83 sslContext = null;
84 }
85 if (url.getUserInfo() != null) {
86 String ai = null;
87 try {
88 // Hack to get Base64-encoded credentials
89 Preferences tempNode = Preferences.userRoot().node("xxx");
90 tempNode.putByteArray("xxx", url.getUserInfo().getBytes());
91 ai = tempNode.get("xxx", null);
92 tempNode.removeNode();
93 } catch (BackingStoreException ex) {
94 ex.printStackTrace();
95 // IGNORE
96 }
97 authInfo = ai;
98 } else {
99 authInfo = null;
100 }
38 } 101 }
39 102
40 public List<Nodeid> heads() { 103 public List<Nodeid> heads() {
41 return Collections.singletonList(Nodeid.fromAscii("71ddbf8603e8e09d54ac9c5fe4bb5ae824589f1d")); 104 return Collections.singletonList(Nodeid.fromAscii("71ddbf8603e8e09d54ac9c5fe4bb5ae824589f1d"));
42 // return Collections.emptyList(); 105 // return Collections.emptyList();
43 } 106 }
44 107
45 public List<Nodeid> between(Nodeid base, Nodeid tip) { 108 public List<Nodeid> between(Nodeid tip, Nodeid base) throws HgException {
46 return Collections.emptyList(); 109 try {
110 LinkedList<Nodeid> rv = new LinkedList<Nodeid>();
111 URL u = new URL(url, url.getPath() + "?cmd=between&pairs=" + tip.toString() + '-' + base.toString());
112 URLConnection c = setupConnection(u.openConnection());
113 c.connect();
114 System.out.println("Query:" + u.getQuery());
115 System.out.println("Response headers:");
116 final Map<String, List<String>> headerFields = c.getHeaderFields();
117 for (String s : headerFields.keySet()) {
118 System.out.printf("%s: %s\n", s, c.getHeaderField(s));
119 }
120 InputStream is = c.getInputStream();
121 StreamTokenizer st = new StreamTokenizer(is);
122 st.ordinaryChars('0', '9');
123 st.wordChars('0', '9');
124 while (st.nextToken() != StreamTokenizer.TT_EOF) {
125 System.out.println(st.sval);
126 Nodeid nid = Nodeid.fromAscii(st.sval);
127 rv.addLast(nid);
128 }
129 is.close();
130 return rv;
131 } catch (MalformedURLException ex) {
132 throw new HgException(ex);
133 } catch (IOException ex) {
134 throw new HgException(ex);
135 }
136 }
137
138 /**
139 * @param ranges
140 * @return map, where keys are input instances, values are corresponding server reply
141 * @throws HgException
142 */
143 public Map<Range, List<Nodeid>> between(Collection<Range> ranges) throws HgException {
144 // if fact, shall do other way round, this method shall send
145 LinkedHashMap<Range, List<Nodeid>> rv = new LinkedHashMap<HgRemoteRepository.Range, List<Nodeid>>(ranges.size() * 4 / 3);
146 for (Range r : ranges) {
147 List<Nodeid> between = between(r.end, r.start);
148 rv.put(r, between);
149 }
150 return rv;
47 } 151 }
48 152
49 public List<RemoteBranch> branches(List<Nodeid> nodes) { 153 public List<RemoteBranch> branches(List<Nodeid> nodes) {
50 return Collections.emptyList(); 154 return Collections.emptyList();
51 } 155 }
52 156
53 // WireProtocol wiki: roots = a list of the latest nodes on every service side changeset branch that both the client and server know about. 157 // WireProtocol wiki: roots = a list of the latest nodes on every service side changeset branch that both the client and server know about.
54 public HgBundle getChanges(List<Nodeid> roots) throws HgException { 158 public HgBundle getChanges(List<Nodeid> roots) throws HgException {
55 return new HgLookup().loadBundle(new File("/temp/hg/hg-bundle-000000000000-gz.tmp")); 159 return new HgLookup().loadBundle(new File("/temp/hg/hg-bundle-000000000000-gz.tmp"));
56 } 160 }
57 161
162 private URLConnection setupConnection(URLConnection urlConnection) {
163 urlConnection.addRequestProperty("User-Agent", "hg4j/0.5.0");
164 urlConnection.addRequestProperty("Accept", "application/mercurial-0.1");
165 if (authInfo != null) {
166 urlConnection.addRequestProperty("Authorization", "Basic " + authInfo);
167 }
168 if (sslContext != null) {
169 ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslContext.getSocketFactory());
170 }
171 return urlConnection;
172 }
173
174 public static final class Range {
175 /**
176 * Root of the range, earlier revision
177 */
178 public final Nodeid start;
179 /**
180 * Head of the range, later revision.
181 */
182 public final Nodeid end;
183
184 /**
185 * @param from - root/base revision
186 * @param to - head/tip revision
187 */
188 public Range(Nodeid from, Nodeid to) {
189 start = from;
190 end = to;
191 }
192 }
58 public static final class RemoteBranch { 193 public static final class RemoteBranch {
59 public final Nodeid head, root, p1, p2; 194 public final Nodeid head, root, p1, p2;
60 195
61 public RemoteBranch(Nodeid h, Nodeid r, Nodeid parent1, Nodeid parent2) { 196 public RemoteBranch(Nodeid h, Nodeid r, Nodeid parent1, Nodeid parent2) {
62 head = h; 197 head = h;