Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgRemoteRepository.java @ 699:a483b2b68a2e
Provisional APIs and respective implementation for http, https and ssh remote repositories
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 08 Aug 2013 19:18:50 +0200 |
parents | 822f3a83ff57 |
children |
comparison
equal
deleted
inserted
replaced
698:822f3a83ff57 | 699:a483b2b68a2e |
---|---|
25 import java.io.IOException; | 25 import java.io.IOException; |
26 import java.io.InputStream; | 26 import java.io.InputStream; |
27 import java.io.InputStreamReader; | 27 import java.io.InputStreamReader; |
28 import java.io.OutputStream; | 28 import java.io.OutputStream; |
29 import java.io.StreamTokenizer; | 29 import java.io.StreamTokenizer; |
30 import java.net.URI; | |
30 import java.util.ArrayList; | 31 import java.util.ArrayList; |
31 import java.util.Arrays; | 32 import java.util.Arrays; |
32 import java.util.Collection; | 33 import java.util.Collection; |
33 import java.util.Collections; | 34 import java.util.Collections; |
34 import java.util.HashSet; | 35 import java.util.HashSet; |
37 import java.util.LinkedList; | 38 import java.util.LinkedList; |
38 import java.util.List; | 39 import java.util.List; |
39 import java.util.Map; | 40 import java.util.Map; |
40 import java.util.Set; | 41 import java.util.Set; |
41 | 42 |
43 import org.tmatesoft.hg.auth.HgAuthFailedException; | |
42 import org.tmatesoft.hg.core.HgBadArgumentException; | 44 import org.tmatesoft.hg.core.HgBadArgumentException; |
43 import org.tmatesoft.hg.core.HgIOException; | 45 import org.tmatesoft.hg.core.HgIOException; |
44 import org.tmatesoft.hg.core.HgRemoteConnectionException; | 46 import org.tmatesoft.hg.core.HgRemoteConnectionException; |
45 import org.tmatesoft.hg.core.HgRepositoryNotFoundException; | 47 import org.tmatesoft.hg.core.HgRepositoryNotFoundException; |
46 import org.tmatesoft.hg.core.Nodeid; | 48 import org.tmatesoft.hg.core.Nodeid; |
47 import org.tmatesoft.hg.core.SessionContext; | 49 import org.tmatesoft.hg.core.SessionContext; |
48 import org.tmatesoft.hg.internal.BundleSerializer; | 50 import org.tmatesoft.hg.internal.BundleSerializer; |
49 import org.tmatesoft.hg.internal.DataSerializer; | 51 import org.tmatesoft.hg.internal.DataSerializer; |
50 import org.tmatesoft.hg.internal.DataSerializer.OutputStreamSerializer; | 52 import org.tmatesoft.hg.internal.DataSerializer.OutputStreamSerializer; |
51 import org.tmatesoft.hg.internal.EncodingHelper; | 53 import org.tmatesoft.hg.internal.EncodingHelper; |
54 import org.tmatesoft.hg.internal.Experimental; | |
52 import org.tmatesoft.hg.internal.FileUtils; | 55 import org.tmatesoft.hg.internal.FileUtils; |
53 import org.tmatesoft.hg.internal.Internals; | 56 import org.tmatesoft.hg.internal.Internals; |
54 import org.tmatesoft.hg.internal.PropertyMarshal; | 57 import org.tmatesoft.hg.internal.PropertyMarshal; |
55 import org.tmatesoft.hg.internal.remote.Connector; | 58 import org.tmatesoft.hg.internal.remote.Connector; |
56 import org.tmatesoft.hg.internal.remote.RemoteConnectorDescriptor; | 59 import org.tmatesoft.hg.internal.remote.RemoteConnectorDescriptor; |
57 import org.tmatesoft.hg.repo.HgLookup.RemoteDescriptor; | 60 import org.tmatesoft.hg.util.Adaptable; |
58 import org.tmatesoft.hg.util.LogFacility.Severity; | 61 import org.tmatesoft.hg.util.LogFacility.Severity; |
59 import org.tmatesoft.hg.util.Outcome; | 62 import org.tmatesoft.hg.util.Outcome; |
60 import org.tmatesoft.hg.util.Pair; | 63 import org.tmatesoft.hg.util.Pair; |
61 | 64 |
62 /** | 65 /** |
75 private final SessionContext sessionContext; | 78 private final SessionContext sessionContext; |
76 private Set<String> remoteCapabilities; | 79 private Set<String> remoteCapabilities; |
77 private Connector remote; | 80 private Connector remote; |
78 | 81 |
79 HgRemoteRepository(SessionContext ctx, RemoteDescriptor rd) throws HgBadArgumentException { | 82 HgRemoteRepository(SessionContext ctx, RemoteDescriptor rd) throws HgBadArgumentException { |
80 if (false == rd instanceof RemoteConnectorDescriptor) { | 83 RemoteConnectorDescriptor rcd = Adaptable.Factory.getAdapter(rd, RemoteConnectorDescriptor.class, null); |
84 if (rcd == null) { | |
81 throw new IllegalArgumentException(String.format("Present implementation supports remote connections via %s only", Connector.class.getName())); | 85 throw new IllegalArgumentException(String.format("Present implementation supports remote connections via %s only", Connector.class.getName())); |
82 } | 86 } |
83 sessionContext = ctx; | 87 sessionContext = ctx; |
84 debug = new PropertyMarshal(ctx).getBoolean("hg4j.remote.debug", false); | 88 debug = new PropertyMarshal(ctx).getBoolean("hg4j.remote.debug", false); |
85 remote = ((RemoteConnectorDescriptor) rd).createConnector(); | 89 remote = rcd.createConnector(); |
86 remote.init(rd.getURI(), ctx, null); | 90 remote.init(rd /*sic! pass original*/, ctx, null); |
87 } | 91 } |
88 | 92 |
89 public boolean isInvalid() throws HgRemoteConnectionException { | 93 public boolean isInvalid() throws HgRemoteConnectionException { |
90 initCapabilities(); | 94 initCapabilities(); |
91 return remoteCapabilities.isEmpty(); | 95 return remoteCapabilities.isEmpty(); |
367 | 371 |
368 private void initCapabilities() throws HgRemoteConnectionException { | 372 private void initCapabilities() throws HgRemoteConnectionException { |
369 if (remoteCapabilities != null) { | 373 if (remoteCapabilities != null) { |
370 return; | 374 return; |
371 } | 375 } |
372 remote.connect(); | 376 try { |
377 remote.connect(); | |
378 } catch (HgAuthFailedException ex) { | |
379 throw new HgRemoteConnectionException("Failed to authenticate", ex).setServerInfo(remote.getServerLocation()); | |
380 } | |
373 try { | 381 try { |
374 remote.sessionBegin(); | 382 remote.sessionBegin(); |
375 String capsLine = remote.getCapabilities(); | 383 String capsLine = remote.getCapabilities(); |
376 String[] caps = capsLine.split("\\s"); | 384 String[] caps = capsLine.split("\\s"); |
377 remoteCapabilities = new HashSet<String>(Arrays.asList(caps)); | 385 remoteCapabilities = new HashSet<String>(Arrays.asList(caps)); |
538 */ | 546 */ |
539 public boolean isPublishingServer() { | 547 public boolean isPublishingServer() { |
540 return pub; | 548 return pub; |
541 } | 549 } |
542 } | 550 } |
551 | |
552 /** | |
553 * Session context ({@link SessionContext#getRemoteDescriptor(URI)} gives descriptor of remote when asked. | |
554 * Clients may supply own descriptors e.g. if need to pass extra information into Authenticator. | |
555 * Present implementation of {@link HgRemoteRepository} will be happy with any {@link RemoteDescriptor} subclass | |
556 * as long as it's {@link Adaptable adaptable} to {@link RemoteConnectorDescriptor} | |
557 * @since 1.2 | |
558 */ | |
559 @Experimental(reason="Provisional API. Work in progress") | |
560 public interface RemoteDescriptor { | |
561 /** | |
562 * @return remote location, never <code>null</code> | |
563 */ | |
564 URI getURI(); | |
565 } | |
543 } | 566 } |