Java tutorial
/******************************************************************************* * Copyright (c) 2010, 2014 Sonatype, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Sonatype, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.aether.ant; import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.maven.model.Model; import org.apache.maven.model.building.DefaultModelBuilderFactory; import org.apache.maven.model.building.DefaultModelBuildingRequest; import org.apache.maven.model.building.FileModelSource; import org.apache.maven.model.building.ModelBuilder; import org.apache.maven.model.building.ModelBuildingException; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.model.resolution.ModelResolver; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.apache.maven.settings.Server; 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.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.condition.Os; import org.apache.tools.ant.types.Reference; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.eclipse.aether.ConfigurationProperties; import org.eclipse.aether.DefaultRepositoryCache; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.ant.listeners.AntRepositoryListener; import org.eclipse.aether.ant.listeners.AntTransferListener; import org.eclipse.aether.ant.types.Authentication; import org.eclipse.aether.ant.types.Dependencies; import org.eclipse.aether.ant.types.Dependency; import org.eclipse.aether.ant.types.Exclusion; import org.eclipse.aether.ant.types.LocalRepository; import org.eclipse.aether.ant.types.Mirror; import org.eclipse.aether.ant.types.Pom; import org.eclipse.aether.ant.types.Proxy; import org.eclipse.aether.ant.types.RemoteRepositories; import org.eclipse.aether.ant.types.RemoteRepository; import org.eclipse.aether.ant.util.AetherUtils; import org.eclipse.aether.ant.util.ConverterUtils; import org.eclipse.aether.ant.util.SettingsUtils; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.CollectResult; import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; import org.eclipse.aether.impl.DefaultServiceLocator; import org.eclipse.aether.impl.RemoteRepositoryManager; import org.eclipse.aether.repository.AuthenticationSelector; import org.eclipse.aether.repository.LocalRepositoryManager; import org.eclipse.aether.repository.MirrorSelector; import org.eclipse.aether.repository.ProxySelector; import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; import org.eclipse.aether.spi.connector.transport.TransporterFactory; import org.eclipse.aether.spi.log.Logger; import org.eclipse.aether.transport.classpath.ClasspathTransporterFactory; import org.eclipse.aether.transport.file.FileTransporterFactory; import org.eclipse.aether.transport.http.HttpTransporterFactory; import org.eclipse.aether.util.repository.AuthenticationBuilder; import org.eclipse.aether.util.repository.ConservativeAuthenticationSelector; import org.eclipse.aether.util.repository.DefaultAuthenticationSelector; import org.eclipse.aether.util.repository.DefaultMirrorSelector; import org.eclipse.aether.util.repository.DefaultProxySelector; /** */ public class AntRepoSys { private static boolean OS_WINDOWS = Os.isFamily("windows"); private static final ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance(); private static final SettingsBuilder settingsBuilder = new DefaultSettingsBuilderFactory().newInstance(); private static final SettingsDecrypter settingsDecrypter = new AntSettingsDecryptorFactory().newInstance(); private final Project project; private final DefaultServiceLocator locator; private RepositorySystem repoSys; private RemoteRepositoryManager remoteRepoMan; private File userSettings; private File globalSettings; private Settings settings; private final List<Mirror> mirrors = new CopyOnWriteArrayList<Mirror>(); private final List<Proxy> proxies = new CopyOnWriteArrayList<Proxy>(); private final List<Authentication> authentications = new CopyOnWriteArrayList<Authentication>(); private LocalRepository localRepository; private Pom defaultPom; private static <T> boolean eq(T o1, T o2) { return (o1 == null) ? o2 == null : o1.equals(o2); } public static synchronized AntRepoSys getInstance(Project project) { Object obj = project.getReference(Names.ID); if (obj instanceof AntRepoSys) { return (AntRepoSys) obj; } AntRepoSys instance = new AntRepoSys(project); project.addReference(Names.ID, instance); instance.initDefaults(); return instance; } private AntRepoSys(Project project) { this.project = project; locator = MavenRepositorySystemUtils.newServiceLocator(); locator.setErrorHandler(new AntServiceLocatorErrorHandler(project)); locator.setServices(Logger.class, new AntLogger(project)); locator.setServices(ModelBuilder.class, modelBuilder); locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); locator.addService(TransporterFactory.class, FileTransporterFactory.class); locator.addService(TransporterFactory.class, HttpTransporterFactory.class); locator.addService(TransporterFactory.class, ClasspathTransporterFactory.class); } private void initDefaults() { RemoteRepository repo = new RemoteRepository(); repo.setProject(project); repo.setId("central"); repo.setUrl("http://repo1.maven.org/maven2/"); project.addReference(Names.ID_CENTRAL, repo); repo = new RemoteRepository(); repo.setProject(project); repo.setRefid(new Reference(project, Names.ID_CENTRAL)); RemoteRepositories repos = new RemoteRepositories(); repos.setProject(project); repos.addRemoterepo(repo); project.addReference(Names.ID_DEFAULT_REPOS, repos); } public synchronized RepositorySystem getSystem() { if (repoSys == null) { repoSys = locator.getService(RepositorySystem.class); if (repoSys == null) { throw new BuildException("The repository system could not be initialized"); } } return repoSys; } private synchronized RemoteRepositoryManager getRemoteRepoMan() { if (remoteRepoMan == null) { remoteRepoMan = locator.getService(RemoteRepositoryManager.class); if (remoteRepoMan == null) { throw new BuildException("The repository system could not be initialized"); } } return remoteRepoMan; } public RepositorySystemSession getSession(Task task, LocalRepository localRepo) { DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); Map<Object, Object> configProps = new LinkedHashMap<Object, Object>(); configProps.put(ConfigurationProperties.USER_AGENT, getUserAgent()); configProps.putAll((Map<?, ?>) project.getProperties()); processServerConfiguration(configProps); session.setConfigProperties(configProps); session.setOffline(isOffline()); session.setUserProperties(project.getUserProperties()); session.setProxySelector(getProxySelector()); session.setMirrorSelector(getMirrorSelector()); session.setAuthenticationSelector(getAuthSelector()); session.setCache(new DefaultRepositoryCache()); session.setRepositoryListener(new AntRepositoryListener(task)); session.setTransferListener(new AntTransferListener(task)); session.setLocalRepositoryManager(getLocalRepoMan(session, localRepo)); session.setWorkspaceReader(ProjectWorkspaceReader.getInstance()); return session; } private String getUserAgent() { StringBuilder buffer = new StringBuilder(128); buffer.append("Apache-Ant/").append(project.getProperty("ant.version")); buffer.append(" ("); buffer.append("Java ").append(System.getProperty("java.version")); buffer.append("; "); buffer.append(System.getProperty("os.name")).append(" ").append(System.getProperty("os.version")); buffer.append(")"); buffer.append(" Aether"); return buffer.toString(); } private boolean isOffline() { String prop = project.getProperty(Names.PROPERTY_OFFLINE); if (prop != null) { return Boolean.parseBoolean(prop); } return getSettings().isOffline(); } private void processServerConfiguration(Map<Object, Object> configProps) { Settings settings = getSettings(); for (Server server : settings.getServers()) { if (server.getConfiguration() != null) { Xpp3Dom dom = (Xpp3Dom) server.getConfiguration(); for (int i = dom.getChildCount() - 1; i >= 0; i--) { Xpp3Dom child = dom.getChild(i); if ("wagonProvider".equals(child.getName())) { dom.removeChild(i); } else if ("httpHeaders".equals(child.getName())) { configProps.put(ConfigurationProperties.HTTP_HEADERS + "." + server.getId(), getHttpHeaders(child)); } } configProps.put("aether.connector.wagon.config." + server.getId(), dom); } configProps.put("aether.connector.perms.fileMode." + server.getId(), server.getFilePermissions()); configProps.put("aether.connector.perms.dirMode." + server.getId(), server.getDirectoryPermissions()); } } private Map<String, String> getHttpHeaders(Xpp3Dom dom) { Map<String, String> headers = new HashMap<String, String>(); for (int i = 0; i < dom.getChildCount(); i++) { Xpp3Dom child = dom.getChild(i); Xpp3Dom name = child.getChild("name"); Xpp3Dom value = child.getChild("value"); if (name != null && name.getValue() != null) { headers.put(name.getValue(), (value != null) ? value.getValue() : null); } } return Collections.unmodifiableMap(headers); } private File getDefaultLocalRepoDir() { String dir = project.getProperty("maven.repo.local"); if (dir != null) { return project.resolveFile(dir); } Settings settings = getSettings(); if (settings.getLocalRepository() != null) { return new File(settings.getLocalRepository()); } return new File(new File(project.getProperty("user.home"), ".m2"), "repository"); } private LocalRepositoryManager getLocalRepoMan(RepositorySystemSession session, LocalRepository localRepo) { if (localRepo == null) { localRepo = localRepository; } File repoDir; if (localRepo != null && localRepo.getDir() != null) { repoDir = localRepo.getDir(); } else { repoDir = getDefaultLocalRepoDir(); } org.eclipse.aether.repository.LocalRepository repo = new org.eclipse.aether.repository.LocalRepository( repoDir); return getSystem().newLocalRepositoryManager(session, repo); } private synchronized Settings getSettings() { if (settings == null) { DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); request.setUserSettingsFile(getUserSettings()); request.setGlobalSettingsFile(getGlobalSettings()); request.setSystemProperties(getSystemProperties()); request.setUserProperties(getUserProperties()); try { settings = settingsBuilder.build(request).getEffectiveSettings(); } catch (SettingsBuildingException e) { project.log("Could not process settings.xml: " + e.getMessage(), e, Project.MSG_WARN); } SettingsDecryptionResult result = settingsDecrypter .decrypt(new DefaultSettingsDecryptionRequest(settings)); settings.setServers(result.getServers()); settings.setProxies(result.getProxies()); } return settings; } private ProxySelector getProxySelector() { DefaultProxySelector selector = new DefaultProxySelector(); for (Proxy proxy : proxies) { selector.add(ConverterUtils.toProxy(proxy), proxy.getNonProxyHosts()); } Settings settings = getSettings(); for (org.apache.maven.settings.Proxy proxy : settings.getProxies()) { AuthenticationBuilder auth = new AuthenticationBuilder(); auth.addUsername(proxy.getUsername()).addPassword(proxy.getPassword()); selector.add(new org.eclipse.aether.repository.Proxy(proxy.getProtocol(), proxy.getHost(), proxy.getPort(), auth.build()), proxy.getNonProxyHosts()); } return selector; } private MirrorSelector getMirrorSelector() { DefaultMirrorSelector selector = new DefaultMirrorSelector(); for (Mirror mirror : mirrors) { selector.add(mirror.getId(), mirror.getUrl(), mirror.getType(), false, mirror.getMirrorOf(), null); } Settings settings = getSettings(); for (org.apache.maven.settings.Mirror mirror : settings.getMirrors()) { selector.add(String.valueOf(mirror.getId()), mirror.getUrl(), mirror.getLayout(), false, mirror.getMirrorOf(), mirror.getMirrorOfLayouts()); } return selector; } private AuthenticationSelector getAuthSelector() { DefaultAuthenticationSelector selector = new DefaultAuthenticationSelector(); Collection<String> ids = new HashSet<String>(); for (Authentication auth : authentications) { List<String> servers = auth.getServers(); if (!servers.isEmpty()) { org.eclipse.aether.repository.Authentication a = ConverterUtils.toAuthentication(auth); for (String server : servers) { if (ids.add(server)) { selector.add(server, a); } } } } Settings settings = getSettings(); for (Server server : settings.getServers()) { AuthenticationBuilder auth = new AuthenticationBuilder(); auth.addUsername(server.getUsername()).addPassword(server.getPassword()); auth.addPrivateKey(server.getPrivateKey(), server.getPassphrase()); selector.add(server.getId(), auth.build()); } return new ConservativeAuthenticationSelector(selector); } public synchronized void setUserSettings(File file) { if (!eq(this.userSettings, file)) { settings = null; } this.userSettings = file; } /* UT */File getUserSettings() { if (userSettings == null) { userSettings = AetherUtils.findUserSettings(project); } return userSettings; } public void setGlobalSettings(File file) { if (!eq(this.globalSettings, file)) { settings = null; } this.globalSettings = file; } /* UT */File getGlobalSettings() { if (globalSettings == null) { globalSettings = AetherUtils.findGlobalSettings(project); } return globalSettings; } public void addProxy(Proxy proxy) { proxies.add(proxy); } public void addMirror(Mirror mirror) { mirrors.add(mirror); } public void addAuthentication(Authentication authentication) { authentications.add(authentication); } public void setLocalRepository(LocalRepository localRepository) { this.localRepository = localRepository; } public Model loadModel(Task task, File pomFile, boolean local, RemoteRepositories remoteRepositories) { RepositorySystemSession session = getSession(task, null); remoteRepositories = remoteRepositories == null ? AetherUtils.getDefaultRepositories(project) : remoteRepositories; List<org.eclipse.aether.repository.RemoteRepository> repositories = ConverterUtils .toRepositories(task.getProject(), session, remoteRepositories, getRemoteRepoMan()); ModelResolver modelResolver = new AntModelResolver(session, "project", getSystem(), getRemoteRepoMan(), repositories); Settings settings = getSettings(); try { DefaultModelBuildingRequest request = new DefaultModelBuildingRequest(); request.setLocationTracking(true); request.setProcessPlugins(false); if (local) { request.setPomFile(pomFile); request.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_STRICT); } else { request.setModelSource(new FileModelSource(pomFile)); request.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); } request.setSystemProperties(getSystemProperties()); request.setUserProperties(getUserProperties()); request.setProfiles(SettingsUtils.convert(settings.getProfiles())); request.setActiveProfileIds(settings.getActiveProfiles()); request.setModelResolver(modelResolver); return modelBuilder.build(request).getEffectiveModel(); } catch (ModelBuildingException e) { throw new BuildException("Could not load POM " + pomFile + ": " + e.getMessage(), e); } } private Properties getSystemProperties() { Properties props = new Properties(); getEnvProperties(props); props.putAll(System.getProperties()); ConverterUtils.addProperties(props, project.getProperties()); return props; } private Properties getEnvProperties(Properties props) { if (props == null) { props = new Properties(); } boolean envCaseInsensitive = OS_WINDOWS; for (Map.Entry<String, String> entry : System.getenv().entrySet()) { String key = entry.getKey(); if (envCaseInsensitive) { key = key.toUpperCase(Locale.ENGLISH); } key = "env." + key; props.put(key, entry.getValue()); } return props; } private Properties getUserProperties() { return ConverterUtils.addProperties(null, project.getUserProperties()); } /** * Sets the default POM. */ public void setDefaultPom(Pom pom) { this.defaultPom = pom; } /** * Returns the current default POM. */ public Pom getDefaultPom() { return defaultPom; } public CollectResult collectDependencies(Task task, Dependencies dependencies, LocalRepository localRepository, RemoteRepositories remoteRepositories) { RepositorySystemSession session = getSession(task, localRepository); remoteRepositories = remoteRepositories == null ? AetherUtils.getDefaultRepositories(project) : remoteRepositories; List<org.eclipse.aether.repository.RemoteRepository> repos = ConverterUtils.toRepositories(project, session, remoteRepositories, getRemoteRepoMan()); CollectRequest collectRequest = new CollectRequest(); collectRequest.setRequestContext("project"); for (org.eclipse.aether.repository.RemoteRepository repo : repos) { task.getProject().log("Using remote repository " + repo, Project.MSG_VERBOSE); collectRequest.addRepository(repo); } if (dependencies != null) { List<Exclusion> globalExclusions = dependencies.getExclusions(); Collection<String> ids = new HashSet<String>(); for (Dependency dep : dependencies.getDependencies()) { ids.add(dep.getVersionlessKey()); collectRequest.addDependency(ConverterUtils.toDependency(dep, globalExclusions, session)); } if (dependencies.getPom() != null) { Model model = dependencies.getPom().getModel(task); for (org.apache.maven.model.Dependency dep : model.getDependencies()) { Dependency dependency = new Dependency(); dependency.setArtifactId(dep.getArtifactId()); dependency.setClassifier(dep.getClassifier()); dependency.setGroupId(dep.getGroupId()); dependency.setScope(dep.getScope()); dependency.setType(dep.getType()); dependency.setVersion(dep.getVersion()); if (ids.contains(dependency.getVersionlessKey())) { continue; } if (dep.getSystemPath() != null && dep.getSystemPath().length() > 0) { dependency.setSystemPath(task.getProject().resolveFile(dep.getSystemPath())); } for (org.apache.maven.model.Exclusion exc : dep.getExclusions()) { Exclusion exclusion = new Exclusion(); exclusion.setGroupId(exc.getGroupId()); exclusion.setArtifactId(exc.getArtifactId()); exclusion.setClassifier("*"); exclusion.setExtension("*"); dependency.addExclusion(exclusion); } collectRequest .addDependency(ConverterUtils.toDependency(dependency, globalExclusions, session)); } } } task.getProject().log("Collecting dependencies", Project.MSG_VERBOSE); CollectResult result; try { result = getSystem().collectDependencies(session, collectRequest); } catch (DependencyCollectionException e) { throw new BuildException("Could not collect dependencies: " + e.getMessage(), e); } return result; } }