Mercurial > jhg
view src/org/tmatesoft/hg/internal/remote/RemoteConnectorDescriptor.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 | 992fa84e7885 |
line wrap: on
line source
/* * Copyright (c) 2013 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * For information on how to redistribute this software under * the terms of a license other than GNU General Public License * contact TMate Software at support@hg4j.com */ package org.tmatesoft.hg.internal.remote; import java.net.URI; import java.util.HashMap; import java.util.Map; import org.tmatesoft.hg.core.HgBadArgumentException; import org.tmatesoft.hg.core.SessionContext; import org.tmatesoft.hg.repo.HgRemoteRepository; import org.tmatesoft.hg.util.Pair; /** * Connector-aware descriptor of remote repository, i.e. descriptor that uses * {@link Connector Connectors} to connect to a remote repository. * * <p>Candidate to become public API, with createConnector() method, so that {@link HgRemoteRepository} * may accept instances of that interfact directly * * * @author Artem Tikhomirov * @author TMate Software Ltd. */ public class RemoteConnectorDescriptor implements HgRemoteRepository.RemoteDescriptor { private Map<String, Pair<ClassLoader, String>> connFactory; private final URI uri; public RemoteConnectorDescriptor(Map<String,Pair<ClassLoader, String>> scheme2connectorMap, URI uriRemote) { this(uriRemote); connFactory = scheme2connectorMap; } protected RemoteConnectorDescriptor(URI uriRemote) { uri = uriRemote; } public URI getURI() { return uri; } public Connector createConnector() throws HgBadArgumentException { Pair<ClassLoader, String> connectorToBe = connFactory.get(uri.getScheme()); if (connectorToBe == null || connectorToBe.second() == null) { throw new HgBadArgumentException(String.format("Can't instantiate connector for scheme '%s'", uri.getScheme()), null); } try { Class<?> connClass = connectorToBe.first().loadClass(connectorToBe.second()); if (!Connector.class.isAssignableFrom(connClass)) { throw new HgBadArgumentException(String.format("Connector %s for scheme '%s' is not a subclass of %s", connectorToBe.second(), uri.getScheme(), Connector.class.getName()), null); } final Object connector = connClass.newInstance(); return Connector.class.cast(connector); } catch (ClassNotFoundException ex) { throw new HgBadArgumentException(String.format("Can't instantiate connector %s for scheme '%s'", connectorToBe.second(), uri.getScheme()), ex); } catch (InstantiationException ex) { throw new HgBadArgumentException(String.format("Can't instantiate connector %s for scheme '%s'", connectorToBe.second(), uri.getScheme()), ex); } catch (IllegalAccessException ex) { throw new HgBadArgumentException(String.format("Can't instantiate connector %s for scheme '%s'", connectorToBe.second(), uri.getScheme()), ex); } } // I don't see a reason to expose provider of RemoteDescriptors yet // although it might not be the best idea for session context to serve as provider intermediate public static class Provider { private final Map<String, Pair<ClassLoader, String>> knownConnectors = new HashMap<String, Pair<ClassLoader, String>>(5); { final ClassLoader cl = Provider.class.getClassLoader(); knownConnectors.put("http", new Pair<ClassLoader, String>(cl, HttpConnector.class.getName())); knownConnectors.put("https", new Pair<ClassLoader, String>(cl, HttpConnector.class.getName())); // FIXME replace SshConnector.class with fqn string to avoid dependency from the trilead library in runtime knownConnectors.put("ssh", new Pair<ClassLoader, String>(cl, SshConnector.class.getName())); } public HgRemoteRepository.RemoteDescriptor get(SessionContext ctx, URI uri) { if (knownConnectors.containsKey(uri.getScheme())) { return new RemoteConnectorDescriptor(knownConnectors, uri); } return null; } } }