1 package org.apache.maven.cli.internal;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Set;
27
28 import javax.inject.Inject;
29 import javax.inject.Named;
30
31 import org.apache.maven.RepositoryUtils;
32 import org.apache.maven.cli.internal.extension.model.CoreExtension;
33 import org.apache.maven.execution.MavenExecutionRequest;
34 import org.apache.maven.extension.internal.CoreExtensionEntry;
35 import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
36 import org.apache.maven.model.Plugin;
37 import org.apache.maven.plugin.PluginResolutionException;
38 import org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver;
39 import org.codehaus.plexus.DefaultPlexusContainer;
40 import org.codehaus.plexus.PlexusContainer;
41 import org.codehaus.plexus.classworlds.ClassWorld;
42 import org.codehaus.plexus.classworlds.realm.ClassRealm;
43 import org.codehaus.plexus.logging.Logger;
44 import org.eclipse.aether.RepositorySystemSession;
45 import org.eclipse.aether.artifact.Artifact;
46 import org.eclipse.aether.graph.DependencyFilter;
47 import org.eclipse.aether.graph.DependencyNode;
48 import org.eclipse.aether.repository.RemoteRepository;
49 import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
50 import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
51
52
53
54
55 @Named
56 public class BootstrapCoreExtensionManager
57 {
58 private final Logger log;
59
60 private final DefaultPluginDependenciesResolver pluginDependenciesResolver;
61
62 private final DefaultRepositorySystemSessionFactory repositorySystemSessionFactory;
63
64 private final ClassWorld classWorld;
65
66 private final ClassRealm parentRealm;
67
68 @Inject
69 public BootstrapCoreExtensionManager( Logger log, DefaultPluginDependenciesResolver pluginDependenciesResolver,
70 DefaultRepositorySystemSessionFactory repositorySystemSessionFactory,
71 PlexusContainer container )
72 {
73 this.log = log;
74 this.pluginDependenciesResolver = pluginDependenciesResolver;
75 this.repositorySystemSessionFactory = repositorySystemSessionFactory;
76 this.classWorld = ( (DefaultPlexusContainer) container ).getClassWorld();
77 this.parentRealm = container.getContainerRealm();
78 }
79
80 public List<CoreExtensionEntry> loadCoreExtensions( MavenExecutionRequest request, Set<String> providedArtifacts,
81 List<CoreExtension> extensions )
82 throws Exception
83 {
84 RepositorySystemSession repoSession = repositorySystemSessionFactory.newRepositorySession( request );
85 List<RemoteRepository> repositories = RepositoryUtils.toRepos( request.getPluginArtifactRepositories() );
86
87 return resolveCoreExtensions( repoSession, repositories, providedArtifacts, extensions );
88 }
89
90 private List<CoreExtensionEntry> resolveCoreExtensions( RepositorySystemSession repoSession,
91 List<RemoteRepository> repositories,
92 Set<String> providedArtifacts,
93 List<CoreExtension> configuration )
94 throws Exception
95 {
96 List<CoreExtensionEntry> extensions = new ArrayList<>();
97
98 DependencyFilter dependencyFilter = new ExclusionsDependencyFilter( providedArtifacts );
99
100 for ( CoreExtension extension : configuration )
101 {
102 List<Artifact> artifacts = resolveExtension( extension, repoSession, repositories, dependencyFilter );
103 if ( !artifacts.isEmpty() )
104 {
105 extensions.add( createExtension( extension, artifacts ) );
106 }
107 }
108
109 return Collections.unmodifiableList( extensions );
110 }
111
112 private CoreExtensionEntry createExtension( CoreExtension extension, List<Artifact> artifacts )
113 throws Exception
114 {
115 String realmId =
116 "coreExtension>" + extension.getGroupId() + ":" + extension.getArtifactId() + ":" + extension.getVersion();
117 ClassRealm realm = classWorld.newRealm( realmId, null );
118 log.debug( "Populating class realm " + realm.getId() );
119 realm.setParentRealm( parentRealm );
120 for ( Artifact artifact : artifacts )
121 {
122 File file = artifact.getFile();
123 log.debug( " Included " + file );
124 realm.addURL( file.toURI().toURL() );
125 }
126 return CoreExtensionEntry.discoverFrom( realm, Collections.singleton( artifacts.get( 0 ).getFile() ) );
127 }
128
129 private List<Artifact> resolveExtension( CoreExtension extension, RepositorySystemSession repoSession,
130 List<RemoteRepository> repositories, DependencyFilter dependencyFilter )
131 throws PluginResolutionException
132 {
133 Plugin plugin = new Plugin();
134 plugin.setGroupId( extension.getGroupId() );
135 plugin.setArtifactId( extension.getArtifactId() );
136 plugin.setVersion( extension.getVersion() );
137
138 DependencyNode root =
139 pluginDependenciesResolver.resolveCoreExtension( plugin, dependencyFilter, repositories, repoSession );
140 PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
141 root.accept( nlg );
142 List<Artifact> artifacts = nlg.getArtifacts( false );
143
144 return artifacts;
145 }
146 }