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 } |
