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.internal.impl;
20  
21  import java.io.File;
22  import java.nio.file.Path;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.Collections;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.NoSuchElementException;
29  import java.util.Objects;
30  import java.util.Optional;
31  import java.util.WeakHashMap;
32  import java.util.concurrent.ConcurrentHashMap;
33  import java.util.concurrent.CopyOnWriteArrayList;
34  import java.util.function.Supplier;
35  import java.util.stream.Collectors;
36  
37  import org.apache.maven.api.Artifact;
38  import org.apache.maven.api.ArtifactCoordinate;
39  import org.apache.maven.api.Dependency;
40  import org.apache.maven.api.DependencyCoordinate;
41  import org.apache.maven.api.DependencyScope;
42  import org.apache.maven.api.Language;
43  import org.apache.maven.api.Listener;
44  import org.apache.maven.api.LocalRepository;
45  import org.apache.maven.api.Node;
46  import org.apache.maven.api.Packaging;
47  import org.apache.maven.api.PathScope;
48  import org.apache.maven.api.PathType;
49  import org.apache.maven.api.Project;
50  import org.apache.maven.api.ProjectScope;
51  import org.apache.maven.api.RemoteRepository;
52  import org.apache.maven.api.Service;
53  import org.apache.maven.api.Session;
54  import org.apache.maven.api.SessionData;
55  import org.apache.maven.api.Type;
56  import org.apache.maven.api.Version;
57  import org.apache.maven.api.VersionConstraint;
58  import org.apache.maven.api.VersionRange;
59  import org.apache.maven.api.annotations.Nonnull;
60  import org.apache.maven.api.annotations.Nullable;
61  import org.apache.maven.api.model.Repository;
62  import org.apache.maven.api.services.*;
63  import org.eclipse.aether.DefaultRepositorySystemSession;
64  import org.eclipse.aether.RepositorySystem;
65  import org.eclipse.aether.RepositorySystemSession;
66  
67  import static org.apache.maven.internal.impl.Utils.map;
68  import static org.apache.maven.internal.impl.Utils.nonNull;
69  
70  public abstract class AbstractSession implements InternalSession {
71  
72      protected final RepositorySystemSession session;
73      protected final RepositorySystem repositorySystem;
74      protected final List<RemoteRepository> repositories;
75      protected final Lookup lookup;
76      private final Map<Class<? extends Service>, Service> services = new ConcurrentHashMap<>();
77      private final List<Listener> listeners = new CopyOnWriteArrayList<>();
78      private final Map<org.eclipse.aether.graph.DependencyNode, Node> allNodes =
79              Collections.synchronizedMap(new WeakHashMap<>());
80      private final Map<org.eclipse.aether.artifact.Artifact, Artifact> allArtifacts =
81              Collections.synchronizedMap(new WeakHashMap<>());
82      private final Map<org.eclipse.aether.repository.RemoteRepository, RemoteRepository> allRepositories =
83              Collections.synchronizedMap(new WeakHashMap<>());
84      private final Map<org.eclipse.aether.graph.Dependency, Dependency> allDependencies =
85              Collections.synchronizedMap(new WeakHashMap<>());
86  
87      public AbstractSession(
88              RepositorySystemSession session,
89              RepositorySystem repositorySystem,
90              List<RemoteRepository> repositories,
91              List<org.eclipse.aether.repository.RemoteRepository> resolverRepositories,
92              Lookup lookup) {
93          this.session = nonNull(session, "session");
94          this.repositorySystem = repositorySystem;
95          this.repositories = getRepositories(repositories, resolverRepositories);
96          this.lookup = lookup;
97      }
98  
99      @Override
100     public RemoteRepository getRemoteRepository(org.eclipse.aether.repository.RemoteRepository repository) {
101         return allRepositories.computeIfAbsent(repository, DefaultRemoteRepository::new);
102     }
103 
104     @Override
105     public Node getNode(org.eclipse.aether.graph.DependencyNode node) {
106         return getNode(node, false);
107     }
108 
109     @Override
110     public Node getNode(org.eclipse.aether.graph.DependencyNode node, boolean verbose) {
111         return allNodes.computeIfAbsent(node, n -> new DefaultNode(this, n, verbose));
112     }
113 
114     @Nonnull
115     @Override
116     public Artifact getArtifact(@Nonnull org.eclipse.aether.artifact.Artifact artifact) {
117         return allArtifacts.computeIfAbsent(artifact, a -> new DefaultArtifact(this, a));
118     }
119 
120     @Nonnull
121     @Override
122     public Dependency getDependency(@Nonnull org.eclipse.aether.graph.Dependency dependency) {
123         return allDependencies.computeIfAbsent(dependency, d -> new DefaultDependency(this, d));
124     }
125 
126     @Override
127     public List<org.eclipse.aether.repository.RemoteRepository> toRepositories(List<RemoteRepository> repositories) {
128         return repositories == null ? null : map(repositories, this::toRepository);
129     }
130 
131     @Override
132     public org.eclipse.aether.repository.RemoteRepository toRepository(RemoteRepository repository) {
133         if (repository instanceof DefaultRemoteRepository) {
134             return ((DefaultRemoteRepository) repository).getRepository();
135         } else {
136             // TODO
137             throw new UnsupportedOperationException("Not implemented yet");
138         }
139     }
140 
141     @Override
142     public org.eclipse.aether.repository.LocalRepository toRepository(LocalRepository repository) {
143         if (repository instanceof DefaultLocalRepository) {
144             return ((DefaultLocalRepository) repository).getRepository();
145         } else {
146             // TODO
147             throw new UnsupportedOperationException("Not implemented yet");
148         }
149     }
150 
151     @Override
152     public List<org.eclipse.aether.graph.Dependency> toDependencies(
153             Collection<DependencyCoordinate> dependencies, boolean managed) {
154         return dependencies == null ? null : map(dependencies, d -> toDependency(d, managed));
155     }
156 
157     static List<RemoteRepository> getRepositories(
158             List<RemoteRepository> repositories,
159             List<org.eclipse.aether.repository.RemoteRepository> resolverRepositories) {
160         if (repositories != null) {
161             return repositories;
162         } else if (resolverRepositories != null) {
163             return map(resolverRepositories, DefaultRemoteRepository::new);
164         } else {
165             throw new IllegalArgumentException("no remote repositories provided");
166         }
167     }
168 
169     @Nonnull
170     @Override
171     public List<RemoteRepository> getRemoteRepositories() {
172         return Collections.unmodifiableList(repositories);
173     }
174 
175     @Nonnull
176     @Override
177     public SessionData getData() {
178         org.eclipse.aether.SessionData data = session.getData();
179         return new SessionData() {
180             @Override
181             public <T> void set(@Nonnull Key<T> key, @Nullable T value) {
182                 data.set(key, value);
183             }
184 
185             @Override
186             public <T> boolean replace(@Nonnull Key<T> key, @Nullable T oldValue, @Nullable T newValue) {
187                 return data.set(key, oldValue, newValue);
188             }
189 
190             @Nullable
191             @Override
192             @SuppressWarnings("unchecked")
193             public <T> T get(@Nonnull Key<T> key) {
194                 return (T) data.get(key);
195             }
196 
197             @Nullable
198             @Override
199             @SuppressWarnings("unchecked")
200             public <T> T computeIfAbsent(@Nonnull Key<T> key, @Nonnull Supplier<T> supplier) {
201                 return (T) data.computeIfAbsent(key, (Supplier<Object>) supplier);
202             }
203         };
204     }
205 
206     @Nonnull
207     @Override
208     public LocalRepository getLocalRepository() {
209         return new DefaultLocalRepository(session.getLocalRepository());
210     }
211 
212     @Nonnull
213     @Override
214     public Session withLocalRepository(@Nonnull LocalRepository localRepository) {
215         nonNull(localRepository, "localRepository");
216         if (session.getLocalRepository() != null
217                 && Objects.equals(session.getLocalRepository().getBasePath(), localRepository.getPath())) {
218             return this;
219         }
220         org.eclipse.aether.repository.LocalRepository repository = toRepository(localRepository);
221         org.eclipse.aether.repository.LocalRepositoryManager localRepositoryManager =
222                 repositorySystem.newLocalRepositoryManager(session, repository);
223 
224         RepositorySystemSession repoSession =
225                 new DefaultRepositorySystemSession(session).setLocalRepositoryManager(localRepositoryManager);
226         return newSession(repoSession, repositories);
227     }
228 
229     @Nonnull
230     @Override
231     public Session withRemoteRepositories(@Nonnull List<RemoteRepository> repositories) {
232         return newSession(session, repositories);
233     }
234 
235     protected abstract Session newSession(RepositorySystemSession session, List<RemoteRepository> repositories);
236 
237     @Nonnull
238     @Override
239     @SuppressWarnings("unchecked")
240     public <T extends Service> T getService(Class<T> clazz) throws NoSuchElementException {
241         T t = (T) services.computeIfAbsent(clazz, this::lookup);
242         if (t == null) {
243             throw new NoSuchElementException(clazz.getName());
244         }
245         return t;
246     }
247 
248     private Service lookup(Class<? extends Service> c) {
249         try {
250             return lookup.lookup(c);
251         } catch (LookupException e) {
252             NoSuchElementException nsee = new NoSuchElementException(c.getName());
253             e.initCause(e);
254             throw nsee;
255         }
256     }
257 
258     @Nonnull
259     public RepositorySystemSession getSession() {
260         return session;
261     }
262 
263     @Nonnull
264     public RepositorySystem getRepositorySystem() {
265         return repositorySystem;
266     }
267 
268     public org.eclipse.aether.graph.Dependency toDependency(DependencyCoordinate dependency, boolean managed) {
269         org.eclipse.aether.graph.Dependency dep;
270         if (dependency instanceof DefaultDependencyCoordinate) {
271             dep = ((DefaultDependencyCoordinate) dependency).getDependency();
272         } else {
273             dep = new org.eclipse.aether.graph.Dependency(
274                     new org.eclipse.aether.artifact.DefaultArtifact(
275                             dependency.getGroupId(),
276                             dependency.getArtifactId(),
277                             dependency.getClassifier(),
278                             dependency.getType().getExtension(),
279                             dependency.getVersion().toString(),
280                             null),
281                     dependency.getScope().id());
282         }
283         if (!managed && "".equals(dep.getScope())) {
284             dep = dep.setScope(DependencyScope.COMPILE.id());
285         }
286         return dep;
287     }
288 
289     @Override
290     public List<org.eclipse.aether.artifact.Artifact> toArtifacts(Collection<Artifact> artifacts) {
291         return artifacts == null ? null : map(artifacts, this::toArtifact);
292     }
293 
294     @Override
295     public org.eclipse.aether.artifact.Artifact toArtifact(Artifact artifact) {
296         Path path = getService(ArtifactManager.class).getPath(artifact).orElse(null);
297         if (artifact instanceof DefaultArtifact) {
298             org.eclipse.aether.artifact.Artifact a = ((DefaultArtifact) artifact).getArtifact();
299             if (Objects.equals(path, a.getPath())) {
300                 return a;
301             }
302         }
303         return new org.eclipse.aether.artifact.DefaultArtifact(
304                 artifact.getGroupId(),
305                 artifact.getArtifactId(),
306                 artifact.getClassifier(),
307                 artifact.getExtension(),
308                 artifact.getVersion().toString(),
309                 null,
310                 path);
311     }
312 
313     @Override
314     public org.eclipse.aether.artifact.Artifact toArtifact(ArtifactCoordinate coord) {
315         if (coord instanceof DefaultArtifactCoordinate) {
316             return ((DefaultArtifactCoordinate) coord).getCoordinate();
317         }
318         return new org.eclipse.aether.artifact.DefaultArtifact(
319                 coord.getGroupId(),
320                 coord.getArtifactId(),
321                 coord.getClassifier(),
322                 coord.getExtension(),
323                 coord.getVersion().toString(),
324                 null,
325                 (File) null);
326     }
327 
328     @Override
329     public void registerListener(@Nonnull Listener listener) {
330         listeners.add(nonNull(listener));
331     }
332 
333     @Override
334     public void unregisterListener(@Nonnull Listener listener) {
335         listeners.remove(nonNull(listener));
336     }
337 
338     @Nonnull
339     @Override
340     public Collection<Listener> getListeners() {
341         return Collections.unmodifiableCollection(listeners);
342     }
343 
344     //
345     // Shortcut implementations
346     //
347 
348     /**
349      * Shortcut for <code>getService(RepositoryFactory.class).createLocal(...)</code>
350      *
351      * @see RepositoryFactory#createLocal(Path)
352      */
353     @Override
354     public LocalRepository createLocalRepository(Path path) {
355         return getService(RepositoryFactory.class).createLocal(path);
356     }
357 
358     /**
359      * Shortcut for <code>getService(RepositoryFactory.class).createRemote(...)</code>
360      *
361      * @see RepositoryFactory#createRemote(String, String)
362      */
363     @Nonnull
364     @Override
365     public RemoteRepository createRemoteRepository(@Nonnull String id, @Nonnull String url) {
366         return getService(RepositoryFactory.class).createRemote(id, url);
367     }
368 
369     /**
370      * Shortcut for <code>getService(RepositoryFactory.class).createRemote(...)</code>
371      *
372      * @see RepositoryFactory#createRemote(Repository)
373      */
374     @Nonnull
375     @Override
376     public RemoteRepository createRemoteRepository(@Nonnull Repository repository) {
377         return getService(RepositoryFactory.class).createRemote(repository);
378     }
379 
380     /**
381      * Shortcut for <code>getService(CoordinateFactory.class).create(...)</code>
382      *
383      * @see ArtifactFactory#create(Session, String, String, String, String)
384      */
385     @Override
386     public ArtifactCoordinate createArtifactCoordinate(
387             String groupId, String artifactId, String version, String extension) {
388         return getService(ArtifactCoordinateFactory.class).create(this, groupId, artifactId, version, extension);
389     }
390 
391     /**
392      * Shortcut for <code>getService(CoordinateFactory.class).create(...)</code>
393      *
394      * @see ArtifactCoordinateFactory#create(Session, String)
395      */
396     @Override
397     public ArtifactCoordinate createArtifactCoordinate(String coordString) {
398         return getService(ArtifactCoordinateFactory.class).create(this, coordString);
399     }
400 
401     /**
402      * Shortcut for <code>getService(CoordinateFactory.class).create(...)</code>
403      *
404      * @see ArtifactCoordinateFactory#create(Session, String, String, String, String, String, String)
405      */
406     @Override
407     public ArtifactCoordinate createArtifactCoordinate(
408             String groupId, String artifactId, String version, String classifier, String extension, String type) {
409         return getService(ArtifactCoordinateFactory.class)
410                 .create(this, groupId, artifactId, version, classifier, extension, type);
411     }
412 
413     /**
414      * Shortcut for <code>getService(CoordinateFactory.class).create(...)</code>
415      *
416      * @see ArtifactCoordinateFactory#create(Session, String, String, String, String, String, String)
417      */
418     @Override
419     public ArtifactCoordinate createArtifactCoordinate(Artifact artifact) {
420         return getService(ArtifactCoordinateFactory.class)
421                 .create(
422                         this,
423                         artifact.getGroupId(),
424                         artifact.getArtifactId(),
425                         artifact.getVersion().asString(),
426                         artifact.getClassifier(),
427                         artifact.getExtension(),
428                         null);
429     }
430 
431     /**
432      * Shortcut for <code>getService(ArtifactFactory.class).create(...)</code>
433      *
434      * @see ArtifactFactory#create(Session, String, String, String, String)
435      */
436     @Override
437     public Artifact createArtifact(String groupId, String artifactId, String version, String extension) {
438         return getService(ArtifactFactory.class).create(this, groupId, artifactId, version, extension);
439     }
440 
441     /**
442      * Shortcut for <code>getService(ArtifactFactory.class).create(...)</code>
443      *
444      * @see ArtifactFactory#create(Session, String, String, String, String, String, String)
445      */
446     @Override
447     public Artifact createArtifact(
448             String groupId, String artifactId, String version, String classifier, String extension, String type) {
449         return getService(ArtifactFactory.class)
450                 .create(this, groupId, artifactId, version, classifier, extension, type);
451     }
452 
453     /**
454      * Shortcut for <code>getService(ArtifactResolver.class).resolve(...)</code>
455      *
456      * @throws ArtifactResolverException if the artifact resolution failed
457      * @see ArtifactResolver#resolve(Session, Collection)
458      */
459     @Override
460     public Map.Entry<Artifact, Path> resolveArtifact(ArtifactCoordinate coordinate) {
461         return getService(ArtifactResolver.class)
462                 .resolve(this, Collections.singletonList(coordinate))
463                 .getArtifacts()
464                 .entrySet()
465                 .iterator()
466                 .next();
467     }
468 
469     /**
470      * Shortcut for <code>getService(ArtifactResolver.class).resolve(...)</code>
471      *
472      * @throws ArtifactResolverException if the artifact resolution failed
473      * @see ArtifactResolver#resolve(Session, Collection)
474      */
475     @Override
476     public Map<Artifact, Path> resolveArtifacts(ArtifactCoordinate... coordinates) {
477         return resolveArtifacts(Arrays.asList(coordinates));
478     }
479 
480     /**
481      * Shortcut for <code>getService(ArtifactResolver.class).resolve(...)</code>
482      *
483      * @throws ArtifactResolverException if the artifact resolution failed
484      * @see ArtifactResolver#resolve(Session, Collection)
485      */
486     @Override
487     public Map<Artifact, Path> resolveArtifacts(Collection<? extends ArtifactCoordinate> coordinates) {
488         return getService(ArtifactResolver.class).resolve(this, coordinates).getArtifacts();
489     }
490 
491     /**
492      * Shortcut for <code>getService(ArtifactResolver.class).resolve(...)</code>
493      *
494      * @throws ArtifactResolverException if the artifact resolution failed
495      * @see ArtifactResolver#resolve(Session, Collection)
496      */
497     @Override
498     public Map.Entry<Artifact, Path> resolveArtifact(Artifact artifact) {
499         ArtifactCoordinate coordinate =
500                 getService(ArtifactCoordinateFactory.class).create(this, artifact);
501         return resolveArtifact(coordinate);
502     }
503 
504     @Override
505     public Map<Artifact, Path> resolveArtifacts(Artifact... artifacts) {
506         ArtifactCoordinateFactory acf = getService(ArtifactCoordinateFactory.class);
507         List<ArtifactCoordinate> coords =
508                 Arrays.stream(artifacts).map(a -> acf.create(this, a)).collect(Collectors.toList());
509         return resolveArtifacts(coords);
510     }
511 
512     /**
513      * Shortcut for {@code getService(ArtifactInstaller.class).install(...)}
514      *
515      * @throws ArtifactInstallerException if the artifacts installation failed
516      * @see ArtifactInstaller#install(Session, Collection)
517      */
518     @Override
519     public void installArtifacts(Artifact... artifacts) {
520         installArtifacts(Arrays.asList(artifacts));
521     }
522 
523     /**
524      * Shortcut for {@code getService(ArtifactInstaller.class).install(...)}
525      *
526      * @throws ArtifactInstallerException if the artifacts installation failed
527      * @see ArtifactInstaller#install(Session, Collection)
528      */
529     @Override
530     public void installArtifacts(Collection<Artifact> artifacts) {
531         getService(ArtifactInstaller.class).install(this, artifacts);
532     }
533 
534     /**
535      * Shortcut for <code>getService(ArtifactDeployer.class).deploy(...)</code>
536      *
537      * @throws ArtifactDeployerException if the artifacts deployment failed
538      * @see ArtifactDeployer#deploy(Session, RemoteRepository, Collection)
539      */
540     @Override
541     public void deployArtifact(RemoteRepository repository, Artifact... artifacts) {
542         getService(ArtifactDeployer.class).deploy(this, repository, Arrays.asList(artifacts));
543     }
544 
545     /**
546      * Shortcut for <code>getService(ArtifactManager.class).setPath(...)</code>
547      *
548      * @see ArtifactManager#setPath(Artifact, Path)
549      */
550     @Override
551     public void setArtifactPath(@Nonnull Artifact artifact, @Nonnull Path path) {
552         getService(ArtifactManager.class).setPath(artifact, path);
553     }
554 
555     /**
556      * Shortcut for <code>getService(ArtifactManager.class).getPath(...)</code>
557      *
558      * @see ArtifactManager#getPath(Artifact)
559      */
560     @Nonnull
561     @Override
562     public Optional<Path> getArtifactPath(@Nonnull Artifact artifact) {
563         return getService(ArtifactManager.class).getPath(artifact);
564     }
565 
566     /**
567      * Shortcut for <code>getService(VersionParser.class).isSnapshot(...)</code>
568      *
569      * @see VersionParser#isSnapshot(String)
570      */
571     @Override
572     public boolean isVersionSnapshot(@Nonnull String version) {
573         return getService(VersionParser.class).isSnapshot(version);
574     }
575 
576     /**
577      * Shortcut for <code>getService(DependencyFactory.class).create(...)</code>
578      *
579      * @see DependencyCoordinateFactory#create(Session, ArtifactCoordinate)
580      */
581     @Nonnull
582     @Override
583     public DependencyCoordinate createDependencyCoordinate(@Nonnull ArtifactCoordinate coordinate) {
584         return getService(DependencyCoordinateFactory.class).create(this, coordinate);
585     }
586 
587     /**
588      * Shortcut for <code>getService(DependencyFactory.class).create(...)</code>
589      *
590      * @see DependencyCoordinateFactory#create(Session, ArtifactCoordinate)
591      */
592     @Nonnull
593     @Override
594     public DependencyCoordinate createDependencyCoordinate(@Nonnull Dependency dependency) {
595         return getService(DependencyCoordinateFactory.class).create(this, dependency);
596     }
597 
598     /**
599      * Shortcut for <code>getService(DependencyCollector.class).collect(...)</code>
600      *
601      * @throws DependencyCollectorException if the dependency collection failed
602      * @see DependencyCollector#collect(Session, Artifact)
603      */
604     @Nonnull
605     @Override
606     public Node collectDependencies(@Nonnull Artifact artifact) {
607         return getService(DependencyCollector.class).collect(this, artifact).getRoot();
608     }
609 
610     /**
611      * Shortcut for <code>getService(DependencyCollector.class).collect(...)</code>
612      *
613      * @throws DependencyCollectorException if the dependency collection failed
614      * @see DependencyCollector#collect(Session, Project)
615      */
616     @Nonnull
617     @Override
618     public Node collectDependencies(@Nonnull Project project) {
619         return getService(DependencyCollector.class).collect(this, project).getRoot();
620     }
621 
622     /**
623      * Shortcut for <code>getService(DependencyCollector.class).collect(...)</code>
624      *
625      * @throws DependencyCollectorException if the dependency collection failed
626      * @see DependencyCollector#collect(Session, DependencyCoordinate)
627      */
628     @Nonnull
629     @Override
630     public Node collectDependencies(@Nonnull DependencyCoordinate dependency) {
631         return getService(DependencyCollector.class).collect(this, dependency).getRoot();
632     }
633 
634     @Nonnull
635     @Override
636     public List<Node> flattenDependencies(@Nonnull Node node, @Nonnull PathScope scope) {
637         return getService(DependencyResolver.class).flatten(this, node, scope);
638     }
639 
640     @Override
641     public List<Path> resolveDependencies(DependencyCoordinate dependency) {
642         return getService(DependencyResolver.class).resolve(this, dependency).getPaths();
643     }
644 
645     @Override
646     public List<Path> resolveDependencies(List<DependencyCoordinate> dependencies) {
647         return getService(DependencyResolver.class).resolve(this, dependencies).getPaths();
648     }
649 
650     @Override
651     public List<Path> resolveDependencies(Project project, PathScope scope) {
652         return getService(DependencyResolver.class)
653                 .resolve(this, project, scope)
654                 .getPaths();
655     }
656 
657     @Override
658     public Map<PathType, List<Path>> resolveDependencies(
659             @Nonnull DependencyCoordinate dependency,
660             @Nonnull PathScope scope,
661             @Nonnull Collection<PathType> desiredTypes) {
662         return getService(DependencyResolver.class)
663                 .resolve(DependencyResolverRequest.builder()
664                         .session(this)
665                         .dependency(dependency)
666                         .pathScope(scope)
667                         .pathTypeFilter(desiredTypes)
668                         .build())
669                 .getDispatchedPaths();
670     }
671 
672     @Override
673     public Map<PathType, List<Path>> resolveDependencies(
674             @Nonnull Project project, @Nonnull PathScope scope, @Nonnull Collection<PathType> desiredTypes) {
675         return getService(DependencyResolver.class)
676                 .resolve(DependencyResolverRequest.builder()
677                         .session(this)
678                         .project(project)
679                         .pathScope(scope)
680                         .pathTypeFilter(desiredTypes)
681                         .build())
682                 .getDispatchedPaths();
683     }
684 
685     @Override
686     public Path getPathForLocalArtifact(@Nonnull Artifact artifact) {
687         return getService(LocalRepositoryManager.class).getPathForLocalArtifact(this, getLocalRepository(), artifact);
688     }
689 
690     @Override
691     public Path getPathForRemoteArtifact(RemoteRepository remote, Artifact artifact) {
692         return getService(LocalRepositoryManager.class)
693                 .getPathForRemoteArtifact(this, getLocalRepository(), remote, artifact);
694     }
695 
696     @Override
697     public Version parseVersion(String version) {
698         return getService(VersionParser.class).parseVersion(version);
699     }
700 
701     @Override
702     public VersionRange parseVersionRange(String versionRange) {
703         return getService(VersionParser.class).parseVersionRange(versionRange);
704     }
705 
706     @Override
707     public VersionConstraint parseVersionConstraint(String versionConstraint) {
708         return getService(VersionParser.class).parseVersionConstraint(versionConstraint);
709     }
710 
711     @Override
712     public Version resolveVersion(ArtifactCoordinate artifact) {
713         return getService(VersionResolver.class).resolve(this, artifact).getVersion();
714     }
715 
716     @Override
717     public List<Version> resolveVersionRange(ArtifactCoordinate artifact) {
718         return getService(VersionRangeResolver.class).resolve(this, artifact).getVersions();
719     }
720 
721     @Override
722     public Type requireType(String id) {
723         return getService(TypeRegistry.class).require(id);
724     }
725 
726     @Override
727     public Language requireLanguage(String id) {
728         return getService(LanguageRegistry.class).require(id);
729     }
730 
731     @Override
732     public Packaging requirePackaging(String id) {
733         return getService(PackagingRegistry.class).require(id);
734     }
735 
736     @Override
737     public ProjectScope requireProjectScope(String id) {
738         return getService(ProjectScopeRegistry.class).require(id);
739     }
740 
741     @Override
742     public DependencyScope requireDependencyScope(String id) {
743         return DependencyScope.forId(nonNull(id, "id"));
744     }
745 
746     @Override
747     public PathScope requirePathScope(String id) {
748         return getService(PathScopeRegistry.class).require(id);
749     }
750 }