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.interpolation.InterpolationException;
44 import org.codehaus.plexus.interpolation.Interpolator;
45 import org.codehaus.plexus.interpolation.MapBasedValueSource;
46 import org.codehaus.plexus.interpolation.StringSearchInterpolator;
47 import org.codehaus.plexus.logging.Logger;
48 import org.eclipse.aether.RepositorySystemSession;
49 import org.eclipse.aether.artifact.Artifact;
50 import org.eclipse.aether.graph.DependencyFilter;
51 import org.eclipse.aether.graph.DependencyNode;
52 import org.eclipse.aether.repository.RemoteRepository;
53 import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
54 import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
55
56
57
58
59 @Named
60 public class BootstrapCoreExtensionManager
61 {
62 private final Logger log;
63
64 private final DefaultPluginDependenciesResolver pluginDependenciesResolver;
65
66 private final DefaultRepositorySystemSessionFactory repositorySystemSessionFactory;
67
68 private final ClassWorld classWorld;
69
70 private final ClassRealm parentRealm;
71
72 @Inject
73 public BootstrapCoreExtensionManager( Logger log, DefaultPluginDependenciesResolver pluginDependenciesResolver,
74 DefaultRepositorySystemSessionFactory repositorySystemSessionFactory,
75 PlexusContainer container )
76 {
77 this.log = log;
78 this.pluginDependenciesResolver = pluginDependenciesResolver;
79 this.repositorySystemSessionFactory = repositorySystemSessionFactory;
80 this.classWorld = ( (DefaultPlexusContainer) container ).getClassWorld();
81 this.parentRealm = container.getContainerRealm();
82 }
83
84 public List<CoreExtensionEntry> loadCoreExtensions( MavenExecutionRequest request, Set<String> providedArtifacts,
85 List<CoreExtension> extensions )
86 throws Exception
87 {
88 RepositorySystemSession repoSession = repositorySystemSessionFactory.newRepositorySession( request );
89 List<RemoteRepository> repositories = RepositoryUtils.toRepos( request.getPluginArtifactRepositories() );
90 Interpolator interpolator = createInterpolator( request );
91
92 return resolveCoreExtensions( repoSession, repositories, providedArtifacts, extensions, interpolator );
93 }
94
95 private List<CoreExtensionEntry> resolveCoreExtensions( RepositorySystemSession repoSession,
96 List<RemoteRepository> repositories,
97 Set<String> providedArtifacts,
98 List<CoreExtension> configuration,
99 Interpolator interpolator )
100 throws Exception
101 {
102 List<CoreExtensionEntry> extensions = new ArrayList<>();
103
104 DependencyFilter dependencyFilter = new ExclusionsDependencyFilter( providedArtifacts );
105
106 for ( CoreExtension extension : configuration )
107 {
108 List<Artifact> artifacts = resolveExtension( extension, repoSession, repositories,
109 dependencyFilter, interpolator );
110 if ( !artifacts.isEmpty() )
111 {
112 extensions.add( createExtension( extension, artifacts ) );
113 }
114 }
115
116 return Collections.unmodifiableList( extensions );
117 }
118
119 private CoreExtensionEntry createExtension( CoreExtension extension, List<Artifact> artifacts )
120 throws Exception
121 {
122 String realmId =
123 "coreExtension>" + extension.getGroupId() + ":" + extension.getArtifactId() + ":" + extension.getVersion();
124 ClassRealm realm = classWorld.newRealm( realmId, null );
125 log.debug( "Populating class realm " + realm.getId() );
126 realm.setParentRealm( parentRealm );
127 for ( Artifact artifact : artifacts )
128 {
129 File file = artifact.getFile();
130 log.debug( " Included " + file );
131 realm.addURL( file.toURI().toURL() );
132 }
133 return CoreExtensionEntry.discoverFrom( realm, Collections.singleton( artifacts.get( 0 ).getFile() ) );
134 }
135
136 private List<Artifact> resolveExtension( CoreExtension extension, RepositorySystemSession repoSession,
137 List<RemoteRepository> repositories, DependencyFilter dependencyFilter,
138 Interpolator interpolator )
139 throws ExtensionResolutionException
140 {
141 try
142 {
143
144
145
146
147 Plugin plugin = new Plugin();
148 plugin.setGroupId( interpolator.interpolate( extension.getGroupId() ) );
149 plugin.setArtifactId( interpolator.interpolate( extension.getArtifactId() ) );
150 plugin.setVersion( interpolator.interpolate( extension.getVersion() ) );
151
152 DependencyNode root = pluginDependenciesResolver
153 .resolveCoreExtension( plugin, dependencyFilter, repositories, repoSession );
154 PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
155 root.accept( nlg );
156 List<Artifact> artifacts = nlg.getArtifacts( false );
157
158 return artifacts;
159 }
160 catch ( PluginResolutionException e )
161 {
162 throw new ExtensionResolutionException( extension, e.getCause() );
163 }
164 catch ( InterpolationException e )
165 {
166 throw new ExtensionResolutionException( extension, e );
167 }
168 }
169
170 private static Interpolator createInterpolator( MavenExecutionRequest request )
171 {
172 StringSearchInterpolator interpolator = new StringSearchInterpolator();
173 interpolator.addValueSource( new MapBasedValueSource( request.getUserProperties() ) );
174 interpolator.addValueSource( new MapBasedValueSource( request.getSystemProperties() ) );
175 return interpolator;
176 }
177
178 }