Mercurial > jhg
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; |
