package org.bundlemaker.core.mvn.internal.config; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.maven.repository.internal.MavenRepositorySystemSession; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Settings; import org.apache.maven.settings.building.DefaultSettingsBuilderFactory; import org.apache.maven.settings.building.DefaultSettingsBuildingRequest; import org.apache.maven.settings.building.SettingsBuilder; import org.apache.maven.settings.building.SettingsBuildingException; import org.bundlemaker.core.mvn.internal.aether.ManualRepositorySystemFactory; import org.eclipse.core.runtime.Assert; import org.sonatype.aether.RepositorySystem; import org.sonatype.aether.RepositorySystemSession; import org.sonatype.aether.repository.Authentication; import org.sonatype.aether.repository.LocalRepository; import org.sonatype.aether.repository.MirrorSelector; import org.sonatype.aether.repository.ProxySelector; import org.sonatype.aether.repository.RemoteRepository; import org.sonatype.aether.util.repository.DefaultMirrorSelector; import org.sonatype.aether.util.repository.DefaultProxySelector; /** * Aether based, drop in replacement for mvn protocol */ public class MvnSettingsBasedRepositoryAdapter implements IAetherRepositoryAdapter { /** - */ private static final SettingsBuilder settingsBuilder = new DefaultSettingsBuilderFactory() .newInstance(); /** - */ private File _userSettingsFile; /** - */ private File _globalSettingsFile; private static final String LATEST_VERSION_RANGE = "(0.0,]"; private static final String REPO_TYPE = "default"; final private MirrorSelector _mirrorSelector; final private ProxySelector _proxySelector; final private RepositorySystem _repositorySystem; private Settings _settings; /** * <p> * Creates a new instance of type {@link MvnSettingsBasedRepositoryAdapter}. * </p> * * @param userSettingsFile * @param globalSettingsFile */ public MvnSettingsBasedRepositoryAdapter(File userSettingsFile, File globalSettingsFile) { // _userSettingsFile = userSettingsFile; _globalSettingsFile = globalSettingsFile; // _settings = getSettings(userSettingsFile, globalSettingsFile); // _proxySelector = selectProxies(); _mirrorSelector = selectMirrors(); _repositorySystem = ManualRepositorySystemFactory.newRepositorySystem(); } /** * <p> * </p> * * @return */ public File getUserSettingsFile() { return _userSettingsFile; } /** * <p> * </p> * * @return */ public File getGlobalSettingsFile() { return _globalSettingsFile; } /** * <p> * </p> * * @return */ public LocalRepository getLocalRepository() { Assert.isNotNull(_settings.getLocalRepository()); File local = new File(_settings.getLocalRepository()); MavenRepositorySystemSession session = new MavenRepositorySystemSession(); return new LocalRepository(local); } /** * <p> * </p> * * @return * @throws IOException */ public List<RemoteRepository> getRemoteRepositories() { // List<RemoteRepository> remoteRepos = AetherUtils.getRemoteRepositories(_settings); // add the default repo RemoteRepository defaultRepo = new RemoteRepository(); defaultRepo.setId("central"); defaultRepo.setContentType("default"); defaultRepo.setUrl("http://repo1.maven.org/maven2"); defaultRepo.setPolicy(false, null); remoteRepos.add(defaultRepo); assignProxyAndMirrors(remoteRepos); // for (RemoteRepository repository : remoteRepos) { // repository.getId(); } // return remoteRepos; } /** * <p> * </p> * * @return */ public RepositorySystem getRepositorySystem() { return _repositorySystem; } /** * <p> * </p> * * @return */ public RepositorySystemSession newSession() { Assert.isNotNull(_settings.getLocalRepository()); File local = new File(_settings.getLocalRepository()); MavenRepositorySystemSession session = new MavenRepositorySystemSession(); LocalRepository localRepo = new LocalRepository(local); session.setLocalRepositoryManager(_repositorySystem.newLocalRepositoryManager(localRepo)); session.setMirrorSelector(_mirrorSelector); session.setProxySelector(_proxySelector); return session; } /** * <p> * </p> * * @param remoteRepos */ private void assignProxyAndMirrors(List<RemoteRepository> remoteRepos) { Map<String, List<String>> map = new HashMap<String, List<String>>(); Map<String, RemoteRepository> naming = new HashMap<String, RemoteRepository>(); for (RemoteRepository r : remoteRepos) { naming.put(r.getId(), r); r.setProxy(_proxySelector.getProxy(r)); RemoteRepository mirror = _mirrorSelector.getMirror(r); if (mirror != null) { String key = mirror.getId(); naming.put(key, mirror); if (!map.containsKey(key)) { map.put(key, new ArrayList<String>()); } List<String> mirrored = map.get(key); mirrored.add(r.getId()); } } for (String mirrorId : map.keySet()) { RemoteRepository mirror = naming.get(mirrorId); List<RemoteRepository> mirroedRepos = new ArrayList<RemoteRepository>(); for (String rep : map.get(mirrorId)) { mirroedRepos.add(naming.get(rep)); } mirror.setMirroredRepositories(mirroedRepos); remoteRepos.removeAll(mirroedRepos); remoteRepos.add(0, mirror); } } private ProxySelector selectProxies() { DefaultProxySelector proxySelector = new DefaultProxySelector(); // for (Proxy proxy : _settings.getProxies()) { // The fields are user, pass, host, port, nonProxyHosts, protocol. String nonProxyHosts = proxy.getNonProxyHosts(); org.sonatype.aether.repository.Proxy proxyObj = new org.sonatype.aether.repository.Proxy(proxy.getProtocol(), proxy.getHost(), proxy.getPort(), getAuthentication(proxy) ); proxySelector.add(proxyObj, nonProxyHosts); } // return proxySelector; } private MirrorSelector selectMirrors() { // configure mirror DefaultMirrorSelector selector = new DefaultMirrorSelector(); // for (Mirror mirror : _settings.getMirrors()) { // type can be null in this implementation (1.11) selector.add(mirror.getId(), mirror.getUrl(), null, false, mirror.getMirrorOf(), "*"); } return selector; } // private List<RemoteRepository> selectRepositories(List<MavenRepositoryURL> repos) // { // List<RemoteRepository> list = new ArrayList<RemoteRepository>(); // for (MavenRepositoryURL r : repos) { // if (r.isMulti()) { // addSubDirs(list, r.getFile()); // } else { // addRepo(list, r); // } // } // return list; // } // // private void addSubDirs(List<RemoteRepository> list, File parentDir) { // if (!parentDir.isDirectory()) { // LOG.debug("Repository marked with @multi does not resolve to a directory: " + parentDir); // return; // } // for (File repo : parentDir.listFiles()) { // if (repo.isDirectory()) { // try { // String repoURI = repo.toURI().toString() + "@id=" + repo.getName(); // LOG.debug("Adding repo from inside multi dir: " + repoURI); // addRepo(list, new MavenRepositoryURL(repoURI)); // } catch (MalformedURLException e) { // LOG.error("Error resolving repo url of a multi repo " + repo.toURI()); // } // } // } // } // // private void addRepo(List<RemoteRepository> list, MavenRepositoryURL repoUrl) { // list.add(new RemoteRepository(repoUrl.getId(), REPO_TYPE, repoUrl.getURL().toExternalForm())); // } // private File resolve(RepositorySystemSession session, List<RemoteRepository> remoteRepos, Artifact artifact) // throws IOException // { // try { // artifact = resolveLatestVersionRange(session, remoteRepos, artifact); // return m_repoSystem.resolveArtifact(session, new ArtifactRequest(artifact, remoteRepos, null)).getArtifact() // .getFile(); // } catch (ArtifactResolutionException e) { // /** // * Do not add root exception to avoid NotSerializableException on DefaultArtifact. To avoid loosing information // * log the root cause. We can remove this again as soon as DefaultArtifact is serializeable. See // * http://team.ops4j.org/browse/PAXURL-206 // */ // LOG.warn("Error resolving artifact + artifact.toString() :" + e.getMessage(), e); // throw new IOException("Error resolving artifact " + artifact.toString() + ": " + e.getMessage()); // } catch (RepositoryException e) { // throw new IOException("Error resolving artifact " + artifact.toString(), e); // } // } // /** // * Tries to resolve versions = LATEST using an open range version query. If it succeeds, version of artifact is set // to // * the highest available version. // * // * @param session // * to be used. // * @param artifact // * to be used // * // * @return an artifact with version set properly (highest if available) // * // * @throws org.sonatype.aether.resolution.VersionRangeResolutionException // * in case of resolver errors. // */ // private Artifact resolveLatestVersionRange(RepositorySystemSession session, List<RemoteRepository> remoteRepos, // Artifact artifact) // throws VersionRangeResolutionException // { // if (artifact.getVersion().equals(VERSION_LATEST)) { // artifact = artifact.setVersion(LATEST_VERSION_RANGE); // // VersionRangeResult versionResult = m_repoSystem.resolveVersionRange(session, new VersionRangeRequest(artifact, // remoteRepos, null)); // if (versionResult != null) { // Version v = versionResult.getHighestVersion(); // if (v != null) { // // artifact = artifact.setVersion(v.toString()); // } // else { // throw new VersionRangeResolutionException(versionResult, "Not highest version found for " + artifact); // } // } // } // return artifact; // } /** * <p> * </p> * * @param proxy * @return */ private Authentication getAuthentication(Proxy proxy) { // user, pass if (proxy.getUsername() != null) { return new Authentication(proxy.getUsername(), proxy.getPassword()); } // return null; } /** * <p> * </p> * * @return */ public static Settings getSettings(File userSettingsFile, File globalSettingsFile) { // Settings settings; // DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); request.setUserSettingsFile(userSettingsFile); request.setGlobalSettingsFile(globalSettingsFile); // TODO: // request.setSystemProperties(getSystemProperties()); // request.setUserProperties(getUserProperties()); try { settings = settingsBuilder.build(request).getEffectiveSettings(); // SettingsDecryptionResult result = // settingDecrypter.decrypt(new DefaultSettingsDecryptionRequest(settings)); // settings.setServers(result.getServers()); // settings.setProxies(result.getProxies()); return settings; } catch (SettingsBuildingException e) { e.printStackTrace(); // project.log("Could not process settings.xml: " + e.getMessage(), e, Project.MSG_WARN); throw new RuntimeException(e.getMessage(), e); } } }