View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.resolver.internal.ant;
20  
21  import java.io.BufferedReader;
22  import java.io.File;
23  import java.io.IOException;
24  import java.io.InputStreamReader;
25  import java.nio.charset.StandardCharsets;
26  import java.nio.file.Files;
27  import java.util.ArrayList;
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.Date;
31  import java.util.HashMap;
32  import java.util.HashSet;
33  import java.util.LinkedHashMap;
34  import java.util.List;
35  import java.util.Locale;
36  import java.util.Map;
37  import java.util.Objects;
38  import java.util.Properties;
39  import java.util.concurrent.CopyOnWriteArrayList;
40  
41  import org.apache.maven.model.Model;
42  import org.apache.maven.model.building.DefaultModelBuildingRequest;
43  import org.apache.maven.model.building.FileModelSource;
44  import org.apache.maven.model.building.ModelBuildingException;
45  import org.apache.maven.model.building.ModelBuildingRequest;
46  import org.apache.maven.model.resolution.ModelResolver;
47  import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
48  import org.apache.maven.resolver.internal.ant.types.Artifact;
49  import org.apache.maven.resolver.internal.ant.types.Artifacts;
50  import org.apache.maven.resolver.internal.ant.types.Authentication;
51  import org.apache.maven.resolver.internal.ant.types.Dependencies;
52  import org.apache.maven.resolver.internal.ant.types.Dependency;
53  import org.apache.maven.resolver.internal.ant.types.DependencyContainer;
54  import org.apache.maven.resolver.internal.ant.types.Exclusion;
55  import org.apache.maven.resolver.internal.ant.types.LocalRepository;
56  import org.apache.maven.resolver.internal.ant.types.Mirror;
57  import org.apache.maven.resolver.internal.ant.types.Pom;
58  import org.apache.maven.resolver.internal.ant.types.Proxy;
59  import org.apache.maven.resolver.internal.ant.types.RemoteRepositories;
60  import org.apache.maven.resolver.internal.ant.types.RemoteRepository;
61  import org.apache.maven.resolver.internal.ant.types.RemoteRepository.Policy;
62  import org.apache.maven.settings.Profile;
63  import org.apache.maven.settings.Repository;
64  import org.apache.maven.settings.RepositoryPolicy;
65  import org.apache.maven.settings.Server;
66  import org.apache.maven.settings.Settings;
67  import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
68  import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
69  import org.apache.maven.settings.building.SettingsBuilder;
70  import org.apache.maven.settings.building.SettingsBuildingException;
71  import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
72  import org.apache.maven.settings.crypto.SettingsDecrypter;
73  import org.apache.maven.settings.crypto.SettingsDecryptionResult;
74  import org.apache.tools.ant.BuildException;
75  import org.apache.tools.ant.Project;
76  import org.apache.tools.ant.Task;
77  import org.apache.tools.ant.taskdefs.condition.Os;
78  import org.apache.tools.ant.types.Reference;
79  import org.codehaus.plexus.util.xml.Xpp3Dom;
80  import org.eclipse.aether.ConfigurationProperties;
81  import org.eclipse.aether.DefaultRepositoryCache;
82  import org.eclipse.aether.DefaultRepositorySystemSession;
83  import org.eclipse.aether.RepositorySystem;
84  import org.eclipse.aether.RepositorySystemSession;
85  import org.eclipse.aether.artifact.DefaultArtifact;
86  import org.eclipse.aether.collection.CollectRequest;
87  import org.eclipse.aether.collection.CollectResult;
88  import org.eclipse.aether.collection.DependencyCollectionException;
89  import org.eclipse.aether.deployment.DeployRequest;
90  import org.eclipse.aether.deployment.DeploymentException;
91  import org.eclipse.aether.impl.RemoteRepositoryManager;
92  import org.eclipse.aether.installation.InstallRequest;
93  import org.eclipse.aether.installation.InstallationException;
94  import org.eclipse.aether.repository.AuthenticationSelector;
95  import org.eclipse.aether.repository.LocalRepositoryManager;
96  import org.eclipse.aether.repository.MirrorSelector;
97  import org.eclipse.aether.repository.ProxySelector;
98  import org.eclipse.aether.util.repository.AuthenticationBuilder;
99  import org.eclipse.aether.util.repository.ConservativeAuthenticationSelector;
100 import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
101 import org.eclipse.aether.util.repository.DefaultMirrorSelector;
102 import org.eclipse.aether.util.repository.DefaultProxySelector;
103 
104 /**
105  */
106 public class AntRepoSys {
107     private static final Date STARTED = new Date();
108 
109     private static final boolean OS_WINDOWS = Os.isFamily("windows");
110 
111     private static final SettingsBuilder SETTINGS_BUILDER = new DefaultSettingsBuilderFactory().newInstance();
112 
113     private static final SettingsDecrypter SETTINGS_DECRYPTER = new AntSettingsDecryptorFactory().newInstance();
114 
115     private final Project project;
116 
117     private final AntRepositorySystemSupplier antRepositorySystemSupplier;
118 
119     private final RepositorySystem repoSys;
120 
121     private File userSettings;
122 
123     private File globalSettings;
124 
125     private Settings settings;
126 
127     private final List<Mirror> mirrors = new CopyOnWriteArrayList<>();
128 
129     private final List<Proxy> proxies = new CopyOnWriteArrayList<>();
130 
131     private final List<Authentication> authentications = new CopyOnWriteArrayList<>();
132 
133     private LocalRepository localRepository;
134 
135     private Pom defaultPom;
136 
137     private static <T> boolean eq(T o1, T o2) {
138         return Objects.equals(o1, o2);
139     }
140 
141     public static synchronized AntRepoSys getInstance(Project project) {
142         Object obj = project.getReference(Names.ID);
143         if (obj instanceof AntRepoSys) {
144             return (AntRepoSys) obj;
145         }
146         AntRepoSys instance = new AntRepoSys(project);
147         project.addReference(Names.ID, instance);
148         instance.initDefaults();
149         return instance;
150     }
151 
152     private AntRepoSys(Project project) {
153         this.project = project;
154         this.antRepositorySystemSupplier = new AntRepositorySystemSupplier();
155         this.repoSys = antRepositorySystemSupplier.get();
156     }
157 
158     private void initDefaults() {
159         RemoteRepository repo = new RemoteRepository();
160         repo.setProject(project);
161         repo.setId("central");
162         repo.setUrl("https://repo1.maven.org/maven2/");
163         project.addReference(Names.ID_CENTRAL, repo);
164 
165         repo = new RemoteRepository();
166         repo.setProject(project);
167         repo.setRefid(new Reference(project, Names.ID_CENTRAL));
168 
169         RemoteRepositories repos = new RemoteRepositories();
170         repos.setProject(project);
171         repos.addRemoterepo(repo);
172         project.addReference(Names.ID_DEFAULT_REPOS, repos);
173     }
174 
175     public synchronized RepositorySystem getSystem() {
176         return repoSys;
177     }
178 
179     private synchronized RemoteRepositoryManager getRemoteRepoMan() {
180         return antRepositorySystemSupplier.remoteRepositoryManager;
181     }
182 
183     public RepositorySystemSession getSession(Task task, LocalRepository localRepo) {
184         DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
185 
186         final Map<Object, Object> configProps = new LinkedHashMap<>();
187         configProps.put(ConfigurationProperties.USER_AGENT, getUserAgent());
188         configProps.put("maven.startTime", STARTED);
189         configProps.putAll(getSystemProperties());
190         configProps.putAll(getUserProperties());
191         processServerConfiguration(configProps);
192 
193         session.setConfigProperties(configProps);
194         session.setSystemProperties(getSystemProperties());
195         session.setUserProperties(getUserProperties());
196         session.setOffline(isOffline());
197 
198         session.setProxySelector(getProxySelector());
199         session.setMirrorSelector(getMirrorSelector());
200         session.setAuthenticationSelector(getAuthSelector());
201 
202         session.setCache(new DefaultRepositoryCache());
203 
204         session.setRepositoryListener(new AntRepositoryListener(task));
205         session.setTransferListener(new AntTransferListener(task));
206 
207         session.setLocalRepositoryManager(getLocalRepoMan(session, localRepo));
208 
209         session.setWorkspaceReader(ProjectWorkspaceReader.getInstance());
210 
211         return session;
212     }
213 
214     private String getUserAgent() {
215         return "Apache-Ant/" + project.getProperty("ant.version")
216                 + " ("
217                 + "Java " + System.getProperty("java.version")
218                 + "; "
219                 + System.getProperty("os.name") + " " + System.getProperty("os.version")
220                 + ")"
221                 + " Aether";
222     }
223 
224     private boolean isOffline() {
225         String prop = project.getProperty(Names.PROPERTY_OFFLINE);
226         if (prop != null) {
227             return Boolean.parseBoolean(prop);
228         }
229         return getSettings().isOffline();
230     }
231 
232     private void processServerConfiguration(Map<Object, Object> configProps) {
233         Settings settings = getSettings();
234         for (Server server : settings.getServers()) {
235             if (server.getConfiguration() != null) {
236                 Xpp3Dom dom = (Xpp3Dom) server.getConfiguration();
237                 for (int i = dom.getChildCount() - 1; i >= 0; i--) {
238                     Xpp3Dom child = dom.getChild(i);
239                     if ("wagonProvider".equals(child.getName())) {
240                         dom.removeChild(i);
241                     } else if ("httpHeaders".equals(child.getName())) {
242                         configProps.put(
243                                 ConfigurationProperties.HTTP_HEADERS + "." + server.getId(), getHttpHeaders(child));
244                     }
245                 }
246 
247                 configProps.put("aether.connector.wagon.config." + server.getId(), dom);
248             }
249 
250             configProps.put("aether.connector.perms.fileMode." + server.getId(), server.getFilePermissions());
251             configProps.put("aether.connector.perms.dirMode." + server.getId(), server.getDirectoryPermissions());
252         }
253     }
254 
255     private Map<String, String> getHttpHeaders(Xpp3Dom dom) {
256         final Map<String, String> headers = new HashMap<>();
257         for (int i = 0; i < dom.getChildCount(); i++) {
258             Xpp3Dom child = dom.getChild(i);
259             Xpp3Dom name = child.getChild("name");
260             Xpp3Dom value = child.getChild("value");
261             if (name != null && name.getValue() != null) {
262                 headers.put(name.getValue(), (value != null) ? value.getValue() : null);
263             }
264         }
265         return Collections.unmodifiableMap(headers);
266     }
267 
268     private File getDefaultLocalRepoDir() {
269         String dir = project.getProperty("maven.repo.local");
270         if (dir != null) {
271             return project.resolveFile(dir);
272         }
273 
274         Settings settings = getSettings();
275         if (settings.getLocalRepository() != null) {
276             return new File(settings.getLocalRepository());
277         }
278 
279         return new File(new File(project.getProperty("user.home"), ".m2"), "repository");
280     }
281 
282     private LocalRepositoryManager getLocalRepoMan(RepositorySystemSession session, LocalRepository localRepo) {
283         if (localRepo == null) {
284             localRepo = localRepository;
285         }
286 
287         File repoDir;
288         if (localRepo != null && localRepo.getDir() != null) {
289             repoDir = localRepo.getDir();
290         } else {
291             repoDir = getDefaultLocalRepoDir();
292         }
293 
294         org.eclipse.aether.repository.LocalRepository repo = new org.eclipse.aether.repository.LocalRepository(repoDir);
295 
296         return getSystem().newLocalRepositoryManager(session, repo);
297     }
298 
299     private synchronized Settings getSettings() {
300         if (settings == null) {
301             DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
302             request.setUserSettingsFile(getUserSettings());
303             request.setGlobalSettingsFile(getGlobalSettings());
304             request.setSystemProperties(getSystemProperties());
305             request.setUserProperties(getUserProperties());
306 
307             try {
308                 settings = SETTINGS_BUILDER.build(request).getEffectiveSettings();
309             } catch (SettingsBuildingException e) {
310                 project.log("Could not process settings.xml: " + e.getMessage(), e, Project.MSG_WARN);
311             }
312 
313             SettingsDecryptionResult result =
314                     SETTINGS_DECRYPTER.decrypt(new DefaultSettingsDecryptionRequest(settings));
315             settings.setServers(result.getServers());
316             settings.setProxies(result.getProxies());
317         }
318         return settings;
319     }
320 
321     private ProxySelector getProxySelector() {
322         DefaultProxySelector selector = new DefaultProxySelector();
323 
324         for (Proxy proxy : proxies) {
325             selector.add(ConverterUtils.toProxy(proxy), proxy.getNonProxyHosts());
326         }
327 
328         Settings settings = getSettings();
329         for (org.apache.maven.settings.Proxy proxy : settings.getProxies()) {
330             AuthenticationBuilder auth = new AuthenticationBuilder();
331             auth.addUsername(proxy.getUsername()).addPassword(proxy.getPassword());
332             selector.add(
333                     new org.eclipse.aether.repository.Proxy(
334                             proxy.getProtocol(), proxy.getHost(),
335                             proxy.getPort(), auth.build()),
336                     proxy.getNonProxyHosts());
337         }
338 
339         return selector;
340     }
341 
342     private MirrorSelector getMirrorSelector() {
343         DefaultMirrorSelector selector = new DefaultMirrorSelector();
344 
345         for (Mirror mirror : mirrors) {
346             selector.add(mirror.getId(), mirror.getUrl(), mirror.getType(), false, false, mirror.getMirrorOf(), null);
347         }
348 
349         Settings settings = getSettings();
350         for (org.apache.maven.settings.Mirror mirror : settings.getMirrors()) {
351             selector.add(
352                     String.valueOf(mirror.getId()),
353                     mirror.getUrl(),
354                     mirror.getLayout(),
355                     false,
356                     false,
357                     mirror.getMirrorOf(),
358                     mirror.getMirrorOfLayouts());
359         }
360 
361         return selector;
362     }
363 
364     private AuthenticationSelector getAuthSelector() {
365         DefaultAuthenticationSelector selector = new DefaultAuthenticationSelector();
366 
367         final Collection<String> ids = new HashSet<>();
368         for (Authentication auth : authentications) {
369             List<String> servers = auth.getServers();
370             if (!servers.isEmpty()) {
371                 org.eclipse.aether.repository.Authentication a = ConverterUtils.toAuthentication(auth);
372                 for (String server : servers) {
373                     if (ids.add(server)) {
374                         selector.add(server, a);
375                     }
376                 }
377             }
378         }
379 
380         Settings settings = getSettings();
381         for (Server server : settings.getServers()) {
382             AuthenticationBuilder auth = new AuthenticationBuilder();
383             auth.addUsername(server.getUsername()).addPassword(server.getPassword());
384             auth.addPrivateKey(server.getPrivateKey(), server.getPassphrase());
385             selector.add(server.getId(), auth.build());
386         }
387 
388         return new ConservativeAuthenticationSelector(selector);
389     }
390 
391     private RemoteRepositories getRemoteRepositories() {
392         RemoteRepositories remoteRepositories = new RemoteRepositories();
393         remoteRepositories.setProject(project);
394 
395         Settings settings = getSettings();
396         List<String> activeProfiles = settings.getActiveProfiles();
397         for (String profileId : activeProfiles) {
398             Profile profile = settings.getProfilesAsMap().get(profileId);
399             for (Repository repository : profile.getRepositories()) {
400                 String id = repository.getId();
401                 RemoteRepository repo = new RemoteRepository();
402                 repo.setProject(project);
403                 repo.setId(id);
404                 repo.setUrl(repository.getUrl());
405                 if (repository.getReleases() != null) {
406                     RepositoryPolicy repositoryPolicy = repository.getReleases();
407                     Policy policy = new Policy();
408                     policy.setEnabled(repositoryPolicy.isEnabled());
409                     if (repositoryPolicy.getChecksumPolicy() != null) {
410                         policy.setChecksums(repositoryPolicy.getChecksumPolicy());
411                     }
412                     if (repositoryPolicy.getUpdatePolicy() != null) {
413                         policy.setUpdates(repositoryPolicy.getUpdatePolicy());
414                     }
415                     repo.addReleases(policy);
416                 }
417                 if (repository.getSnapshots() != null) {
418                     RepositoryPolicy repositoryPolicy = repository.getSnapshots();
419                     Policy policy = new Policy();
420                     policy.setEnabled(repositoryPolicy.isEnabled());
421                     if (repositoryPolicy.getChecksumPolicy() != null) {
422                         policy.setChecksums(repositoryPolicy.getChecksumPolicy());
423                     }
424                     if (repositoryPolicy.getUpdatePolicy() != null) {
425                         policy.setUpdates(repositoryPolicy.getUpdatePolicy());
426                     }
427                     repo.addSnapshots(policy);
428                 }
429                 project.addReference(id, repo);
430 
431                 repo = new RemoteRepository();
432                 repo.setProject(project);
433                 repo.setRefid(new Reference(project, id));
434                 remoteRepositories.addRemoterepo(repo);
435             }
436         }
437 
438         return remoteRepositories;
439     }
440 
441     private RemoteRepositories getMergedRepositories() {
442         RemoteRepositories defaultRepositories = AetherUtils.getDefaultRepositories(project);
443         RemoteRepositories settingsRepositories = getRemoteRepositories();
444 
445         RemoteRepositories mergedRepositories = new RemoteRepositories();
446         mergedRepositories.setProject(project);
447         mergedRepositories.addRemoterepos(defaultRepositories);
448         mergedRepositories.addRemoterepos(settingsRepositories);
449 
450         return mergedRepositories;
451     }
452 
453     public synchronized void setUserSettings(File file) {
454         if (!eq(this.userSettings, file)) {
455             settings = null;
456         }
457         this.userSettings = file;
458     }
459 
460     /* UT */ File getUserSettings() {
461         if (userSettings == null) {
462             userSettings = AetherUtils.findUserSettings(project);
463         }
464         return userSettings;
465     }
466 
467     public void setGlobalSettings(File file) {
468         if (!eq(this.globalSettings, file)) {
469             settings = null;
470         }
471         this.globalSettings = file;
472     }
473 
474     /* UT */ File getGlobalSettings() {
475         if (globalSettings == null) {
476             globalSettings = AetherUtils.findGlobalSettings(project);
477         }
478         return globalSettings;
479     }
480 
481     public void addProxy(Proxy proxy) {
482         proxies.add(proxy);
483     }
484 
485     public void addMirror(Mirror mirror) {
486         mirrors.add(mirror);
487     }
488 
489     public void addAuthentication(Authentication authentication) {
490         authentications.add(authentication);
491     }
492 
493     public void setLocalRepository(LocalRepository localRepository) {
494         this.localRepository = localRepository;
495     }
496 
497     public Model loadModel(Task task, File pomFile, boolean local, RemoteRepositories remoteRepositories) {
498         RepositorySystemSession session = getSession(task, null);
499 
500         remoteRepositories = remoteRepositories == null ? getMergedRepositories() : remoteRepositories;
501 
502         List<org.eclipse.aether.repository.RemoteRepository> repositories =
503                 ConverterUtils.toRepositories(task.getProject(), getSystem(), session, remoteRepositories);
504 
505         ModelResolver modelResolver =
506                 new AntModelResolver(session, "project", getSystem(), getRemoteRepoMan(), repositories);
507 
508         Settings settings = getSettings();
509 
510         try {
511             DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
512             request.setLocationTracking(true);
513             request.setProcessPlugins(false);
514             if (local) {
515                 request.setPomFile(pomFile);
516                 request.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
517             } else {
518                 request.setModelSource(new FileModelSource(pomFile));
519                 request.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
520             }
521             request.setSystemProperties(getSystemProperties());
522             request.setUserProperties(getUserProperties());
523             request.setProfiles(SettingsUtils.convert(settings.getProfiles()));
524             request.setActiveProfileIds(settings.getActiveProfiles());
525             request.setModelResolver(modelResolver);
526             return antRepositorySystemSupplier.modelBuilder.build(request).getEffectiveModel();
527         } catch (ModelBuildingException e) {
528             throw new BuildException("Could not load POM " + pomFile + ": " + e.getMessage(), e);
529         }
530     }
531 
532     private Properties getSystemProperties() {
533         Properties props = new Properties();
534         getEnvProperties(props);
535         props.putAll(System.getProperties());
536         ConverterUtils.addProperties(props, project.getProperties());
537         return props;
538     }
539 
540     private void getEnvProperties(Properties props) {
541         if (props == null) {
542             props = new Properties();
543         }
544         for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
545             String key = entry.getKey();
546             if (OS_WINDOWS) {
547                 key = key.toUpperCase(Locale.ENGLISH);
548             }
549             key = "env." + key;
550             props.put(key, entry.getValue());
551         }
552     }
553 
554     private Properties getUserProperties() {
555         return ConverterUtils.addProperties(null, project.getUserProperties());
556     }
557 
558     /**
559      * Sets the default POM.
560      */
561     public void setDefaultPom(Pom pom) {
562         this.defaultPom = pom;
563     }
564 
565     /**
566      * Returns the current default POM.
567      */
568     public Pom getDefaultPom() {
569         return defaultPom;
570     }
571 
572     public CollectResult collectDependencies(
573             Task task,
574             Dependencies dependencies,
575             LocalRepository localRepository,
576             RemoteRepositories remoteRepositories) {
577         RepositorySystemSession session = getSession(task, localRepository);
578 
579         remoteRepositories = remoteRepositories == null ? getMergedRepositories() : remoteRepositories;
580 
581         List<org.eclipse.aether.repository.RemoteRepository> repos =
582                 ConverterUtils.toRepositories(project, getSystem(), session, remoteRepositories);
583 
584         CollectRequest collectRequest = new CollectRequest();
585         collectRequest.setRequestContext("project");
586 
587         for (org.eclipse.aether.repository.RemoteRepository repo : repos) {
588             task.getProject().log("Using remote repository " + repo, Project.MSG_VERBOSE);
589             collectRequest.addRepository(repo);
590         }
591 
592         if (dependencies != null) {
593             populateCollectRequest(collectRequest, task, session, dependencies, Collections.emptyList());
594         }
595 
596         task.getProject().log("Collecting dependencies", Project.MSG_VERBOSE);
597 
598         CollectResult result;
599         try {
600             result = getSystem().collectDependencies(session, collectRequest);
601         } catch (DependencyCollectionException e) {
602             throw new BuildException("Could not collect dependencies: " + e.getMessage(), e);
603         }
604 
605         return result;
606     }
607 
608     private void populateCollectRequest(
609             CollectRequest collectRequest,
610             Task task,
611             RepositorySystemSession session,
612             Dependencies dependencies,
613             List<Exclusion> exclusions) {
614         List<Exclusion> globalExclusions = exclusions;
615         if (!dependencies.getExclusions().isEmpty()) {
616             globalExclusions = new ArrayList<>(exclusions);
617             globalExclusions.addAll(dependencies.getExclusions());
618         }
619 
620         final Collection<String> ids = new HashSet<>();
621 
622         for (DependencyContainer container : dependencies.getDependencyContainers()) {
623             if (container instanceof Dependency) {
624                 Dependency dep = (Dependency) container;
625                 ids.add(dep.getVersionlessKey());
626                 collectRequest.addDependency(ConverterUtils.toDependency(dep, globalExclusions, session));
627             } else {
628                 populateCollectRequest(collectRequest, task, session, (Dependencies) container, globalExclusions);
629             }
630         }
631 
632         if (dependencies.getPom() != null) {
633             Model model = dependencies.getPom().getModel(task);
634             if (model.getDependencyManagement() != null) {
635                 for (org.apache.maven.model.Dependency manDep :
636                         model.getDependencyManagement().getDependencies()) {
637                     Dependency dependency = new Dependency();
638                     dependency.setArtifactId(manDep.getArtifactId());
639                     dependency.setClassifier(manDep.getClassifier());
640                     dependency.setGroupId(manDep.getGroupId());
641                     dependency.setScope(manDep.getScope());
642                     dependency.setType(manDep.getType());
643                     dependency.setVersion(manDep.getVersion());
644                     if (manDep.getSystemPath() != null
645                             && !manDep.getSystemPath().isEmpty()) {
646                         dependency.setSystemPath(task.getProject().resolveFile(manDep.getSystemPath()));
647                     }
648                     for (org.apache.maven.model.Exclusion exc : manDep.getExclusions()) {
649                         Exclusion exclusion = new Exclusion();
650                         exclusion.setGroupId(exc.getGroupId());
651                         exclusion.setArtifactId(exc.getArtifactId());
652                         exclusion.setClassifier("*");
653                         exclusion.setExtension("*");
654                         dependency.addExclusion(exclusion);
655                     }
656                     collectRequest.addManagedDependency(
657                             ConverterUtils.toDependency(dependency, globalExclusions, session));
658                 }
659             }
660 
661             for (org.apache.maven.model.Dependency dep : model.getDependencies()) {
662                 Dependency dependency = new Dependency();
663                 dependency.setArtifactId(dep.getArtifactId());
664                 dependency.setClassifier(dep.getClassifier());
665                 dependency.setGroupId(dep.getGroupId());
666                 dependency.setScope(dep.getScope());
667                 dependency.setType(dep.getType());
668                 dependency.setVersion(dep.getVersion());
669                 if (ids.contains(dependency.getVersionlessKey())) {
670                     project.log(
671                             "Ignoring dependency " + dependency.getVersionlessKey() + " from " + model.getId()
672                                     + ", already declared locally",
673                             Project.MSG_VERBOSE);
674                     continue;
675                 }
676                 if (dep.getSystemPath() != null && !dep.getSystemPath().isEmpty()) {
677                     dependency.setSystemPath(task.getProject().resolveFile(dep.getSystemPath()));
678                 }
679                 for (org.apache.maven.model.Exclusion exc : dep.getExclusions()) {
680                     Exclusion exclusion = new Exclusion();
681                     exclusion.setGroupId(exc.getGroupId());
682                     exclusion.setArtifactId(exc.getArtifactId());
683                     exclusion.setClassifier("*");
684                     exclusion.setExtension("*");
685                     dependency.addExclusion(exclusion);
686                 }
687                 collectRequest.addDependency(ConverterUtils.toDependency(dependency, globalExclusions, session));
688             }
689         }
690 
691         if (dependencies.getFile() != null) {
692             List<Dependency> deps = readDependencies(dependencies.getFile());
693             for (Dependency dependency : deps) {
694                 if (ids.contains(dependency.getVersionlessKey())) {
695                     project.log(
696                             "Ignoring dependency " + dependency.getVersionlessKey() + " from " + dependencies.getFile()
697                                     + ", already declared locally",
698                             Project.MSG_VERBOSE);
699                     continue;
700                 }
701                 collectRequest.addDependency(ConverterUtils.toDependency(dependency, globalExclusions, session));
702             }
703         }
704     }
705 
706     private List<Dependency> readDependencies(File file) {
707         final List<Dependency> dependencies = new ArrayList<>();
708         try {
709             try (BufferedReader reader = new BufferedReader(
710                     new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) {
711                 for (String line = reader.readLine(); line != null; line = reader.readLine()) {
712                     int comment = line.indexOf('#');
713                     if (comment >= 0) {
714                         line = line.substring(0, comment);
715                     }
716                     line = line.trim();
717                     if (line.length() <= 0) {
718                         continue;
719                     }
720                     Dependency dependency = new Dependency();
721                     dependency.setCoords(line);
722                     dependencies.add(dependency);
723                 }
724             }
725         } catch (IOException e) {
726             throw new BuildException("Cannot read " + file, e);
727         }
728         return dependencies;
729     }
730 
731     public void install(Task task, Pom pom, Artifacts artifacts) {
732         RepositorySystemSession session = getSession(task, null);
733 
734         InstallRequest request = new InstallRequest();
735         request.setArtifacts(toArtifacts(task, session, pom, artifacts));
736 
737         try {
738             getSystem().install(session, request);
739         } catch (InstallationException e) {
740             throw new BuildException("Could not install artifacts: " + e.getMessage(), e);
741         }
742     }
743 
744     public void deploy(
745             Task task,
746             Pom pom,
747             Artifacts artifacts,
748             RemoteRepository releaseRepository,
749             RemoteRepository snapshotRepository) {
750         RepositorySystemSession session = getSession(task, null);
751 
752         DeployRequest request = new DeployRequest();
753         request.setArtifacts(toArtifacts(task, session, pom, artifacts));
754         boolean snapshot = request.getArtifacts().iterator().next().isSnapshot();
755         RemoteRepository distRepo = (snapshot && snapshotRepository != null) ? snapshotRepository : releaseRepository;
756         request.setRepository(ConverterUtils.toDistRepository(distRepo, session));
757 
758         try {
759             getSystem().deploy(session, request);
760         } catch (DeploymentException e) {
761             throw new BuildException("Could not deploy artifacts: " + e.getMessage(), e);
762         }
763     }
764 
765     private List<org.eclipse.aether.artifact.Artifact> toArtifacts(
766             Task task, RepositorySystemSession session, Pom pom, Artifacts artifacts) {
767         Model model = pom.getModel(task);
768         File pomFile = pom.getFile();
769 
770         final List<org.eclipse.aether.artifact.Artifact> results = new ArrayList<>();
771 
772         org.eclipse.aether.artifact.Artifact pomArtifact = new DefaultArtifact(
773                         model.getGroupId(), model.getArtifactId(), "pom", model.getVersion())
774                 .setFile(pomFile);
775         results.add(pomArtifact);
776 
777         for (Artifact artifact : artifacts.getArtifacts()) {
778             org.eclipse.aether.artifact.Artifact buildArtifact = new DefaultArtifact(
779                             model.getGroupId(),
780                             model.getArtifactId(),
781                             artifact.getClassifier(),
782                             artifact.getType(),
783                             model.getVersion())
784                     .setFile(artifact.getFile());
785             results.add(buildArtifact);
786         }
787 
788         return results;
789     }
790 }