package de.saumya.mojo.mavengem.wagon; import java.io.File; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.Proxy.Type; import java.net.SocketAddress; import java.util.Map; import java.util.HashMap; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.maven.wagon.StreamWagon; import org.apache.maven.wagon.Wagon; import org.apache.maven.wagon.InputData; import org.apache.maven.wagon.OutputData; import org.apache.maven.wagon.authentication.AuthenticationException; import org.apache.maven.wagon.ConnectionException; import org.apache.maven.wagon.TransferFailedException; import org.apache.maven.wagon.resource.Resource; import org.apache.maven.wagon.ResourceDoesNotExistException; import org.apache.maven.wagon.authorization.AuthorizationException; import org.apache.maven.wagon.proxy.ProxyInfo; import de.saumya.mojo.mavengem.RubygemsFactory; import de.saumya.mojo.mavengem.MavenGemURLConnection; public class MavenGemWagon extends StreamWagon { public static final String MAVEN_GEM_PREFIX = "mavengem:"; private Proxy proxy = Proxy.NO_PROXY; private RubygemsFactory _factory_; // configurable via the settings.xml private File cachedir; private String mirror; private void warn(String msg) { System.err.println("WARNING: " + msg); } @Override public void fillInputData(InputData inputData) throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException { Resource resource = inputData.getResource(); try { if (proxy != Proxy.NO_PROXY) { warn("proxy support is not implemented - ignoring proxy settings"); } URLConnection urlConnection = newConnection(resource.getName()); InputStream is = urlConnection.getInputStream(); inputData.setInputStream(is); resource.setLastModified(urlConnection.getLastModified()); resource.setContentLength(urlConnection.getContentLength()); } catch(MalformedURLException e) { throw new TransferFailedException("Invalid repository URL: " + e.getMessage(), e); } catch(FileNotFoundException e) { throw new ResourceDoesNotExistException("Unable to locate resource in repository", e); } catch(IOException e) { throw new TransferFailedException("Error transferring file: " + e.getMessage(), e); } } private RubygemsFactory rubygemsFactory() throws MalformedURLException { if (_factory_ == null) { // use the default if not set if (cachedir == null) { cachedir = RubygemsFactory.DEFAULT_CACHEDIR; } if (mirror != null) { _factory_ = new RubygemsFactory(cachedir, withAuthentication(mirror)); } else { _factory_ = new RubygemsFactory(cachedir); } } return _factory_; } public URLConnection newConnection(String resourceName) throws MalformedURLException { return new MavenGemURLConnection(rubygemsFactory(), getRepositoryURL(), "/" + resourceName); } @Override public boolean resourceExists(String resourceName) throws TransferFailedException, AuthorizationException { try { newConnection(resourceName).connect(); return true; } catch (FileNotFoundException e) { return false; } catch(MalformedURLException e) { throw new TransferFailedException("Invalid repository URL: " + e.getMessage(), e); } catch (IOException e) { throw new TransferFailedException("Error transferring file: " + e.getMessage(), e); } } @Override public void fillOutputData(OutputData outputData) throws TransferFailedException { throw new RuntimeException("only download is provided"); } @Override public void closeConnection() throws ConnectionException { } private URL withAuthentication(String url) throws MalformedURLException { if (authenticationInfo != null && authenticationInfo.getUserName() != null) { String credentials = authenticationInfo.getUserName() + ":" + authenticationInfo.getPassword(); url = url.replaceFirst("^(https?://)(.*)$", "$1" + credentials + "@$2"); } return new URL(url); } private URL getRepositoryURL() throws MalformedURLException { String url = getRepository().getUrl().substring(MAVEN_GEM_PREFIX.length()); return withAuthentication(url); } private Proxy getProxy(ProxyInfo proxyInfo) { return new Proxy(getProxyType(proxyInfo), getSocketAddress(proxyInfo)); } private Type getProxyType(ProxyInfo proxyInfo) { if (ProxyInfo.PROXY_SOCKS4.equals(proxyInfo.getType()) || ProxyInfo.PROXY_SOCKS5.equals(proxyInfo.getType())) { return Type.SOCKS; } else { return Type.HTTP; } } private SocketAddress getSocketAddress(ProxyInfo proxyInfo) { return InetSocketAddress.createUnresolved(proxyInfo.getHost(), proxyInfo.getPort()); } @Override protected void openConnectionInternal() throws ConnectionException, AuthenticationException { try { final ProxyInfo proxyInfo = getProxyInfo(getRepositoryURL().getProtocol(), getRepository().getHost()); if (proxyInfo != null) { this.proxy = getProxy( proxyInfo ); } } catch (MalformedURLException e) { throw new ConnectionException("cannot create repository url", e); } } }