1 package org.apache.maven.plugins.dependency.resolvers;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.artifact.Artifact;
23
24 import org.apache.maven.plugin.MojoExecutionException;
25 import org.apache.maven.plugins.dependency.utils.DependencyStatusSets;
26 import org.apache.maven.plugins.dependency.utils.DependencyUtil;
27 import org.apache.maven.plugins.dependency.utils.filters.ResolveFileFilter;
28 import org.apache.maven.plugins.dependency.utils.markers.SourcesFileMarkerHandler;
29 import org.apache.maven.plugins.annotations.LifecyclePhase;
30 import org.apache.maven.plugins.annotations.Mojo;
31 import org.apache.maven.plugins.annotations.Parameter;
32 import org.apache.maven.plugins.annotations.ResolutionScope;
33 import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
34 import org.apache.maven.shared.utils.logging.MessageBuilder;
35 import org.apache.maven.shared.utils.logging.MessageUtils;
36
37 import java.io.File;
38 import java.io.IOException;
39 import java.lang.reflect.InvocationTargetException;
40 import java.lang.reflect.Method;
41 import java.util.ArrayList;
42 import java.util.Collections;
43 import java.util.LinkedHashSet;
44 import java.util.List;
45 import java.util.Set;
46 import java.util.jar.JarFile;
47 import java.util.jar.Manifest;
48
49
50
51
52
53
54
55
56
57 @Mojo( name = "resolve", requiresDependencyResolution = ResolutionScope.TEST, defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true )
58
59 public class ResolveDependenciesMojo
60 extends AbstractResolveMojo
61 {
62
63
64
65
66
67
68 @Parameter( property = "mdep.outputScope", defaultValue = "true" )
69 protected boolean outputScope;
70
71
72
73
74 DependencyStatusSets results;
75
76
77
78
79
80
81 @Parameter( property = "sort", defaultValue = "false" )
82 boolean sort;
83
84
85
86
87
88
89 @Parameter( property = "includeParents", defaultValue = "false" )
90 boolean includeParents;
91
92
93
94
95
96
97 @Override
98 protected void doExecute()
99 throws MojoExecutionException
100 {
101
102 results = this.getDependencySets( false, includeParents );
103
104 String output = getOutput( outputAbsoluteArtifactFilename, outputScope, sort );
105 try
106 {
107 if ( outputFile == null )
108 {
109 DependencyUtil.log( output, getLog() );
110 }
111 else
112 {
113 DependencyUtil.write( output, outputFile, appendOutput, getLog() );
114 }
115 }
116 catch ( IOException e )
117 {
118 throw new MojoExecutionException( e.getMessage(), e );
119 }
120 }
121
122
123
124
125 public DependencyStatusSets getResults()
126 {
127 return this.results;
128 }
129
130 @Override
131 protected ArtifactsFilter getMarkedArtifactFilter()
132 {
133 return new ResolveFileFilter( new SourcesFileMarkerHandler( this.markersDirectory ) );
134 }
135
136
137
138
139
140
141
142 public String getOutput( boolean outputAbsoluteArtifactFilename, boolean theOutputScope, boolean theSort )
143 {
144 StringBuilder sb = new StringBuilder();
145 sb.append( "\n" );
146 sb.append( "The following files have been resolved:\n" );
147 if ( results.getResolvedDependencies() == null || results.getResolvedDependencies().isEmpty() )
148 {
149 sb.append( " none\n" );
150 }
151 else
152 {
153 sb.append( buildArtifactListOutput( results.getResolvedDependencies(), outputAbsoluteArtifactFilename,
154 theOutputScope, theSort ) );
155 }
156
157 if ( results.getSkippedDependencies() != null && !results.getSkippedDependencies().isEmpty() )
158 {
159 sb.append( "\n" );
160 sb.append( "The following files were skipped:\n" );
161 Set<Artifact> skippedDependencies = new LinkedHashSet<Artifact>();
162 skippedDependencies.addAll( results.getSkippedDependencies() );
163 sb.append( buildArtifactListOutput( skippedDependencies, outputAbsoluteArtifactFilename, theOutputScope,
164 theSort ) );
165 }
166
167 if ( results.getUnResolvedDependencies() != null && !results.getUnResolvedDependencies().isEmpty() )
168 {
169 sb.append( "\n" );
170 sb.append( "The following files have NOT been resolved:\n" );
171 Set<Artifact> unResolvedDependencies = new LinkedHashSet<Artifact>();
172 unResolvedDependencies.addAll( results.getUnResolvedDependencies() );
173 sb.append( buildArtifactListOutput( unResolvedDependencies, outputAbsoluteArtifactFilename, theOutputScope,
174 theSort ) );
175 }
176 sb.append( "\n" );
177
178 return sb.toString();
179 }
180
181 private StringBuilder buildArtifactListOutput( Set<Artifact> artifacts, boolean outputAbsoluteArtifactFilename,
182 boolean theOutputScope, boolean theSort )
183 {
184 StringBuilder sb = new StringBuilder();
185 List<String> artifactStringList = new ArrayList<String>();
186 for ( Artifact artifact : artifacts )
187 {
188 MessageBuilder messageBuilder = MessageUtils.buffer();
189
190 messageBuilder.a( " " );
191
192 if ( theOutputScope )
193 {
194 messageBuilder.a( artifact.toString() );
195 }
196 else
197 {
198 messageBuilder.a( artifact.getId() );
199 }
200
201 if ( outputAbsoluteArtifactFilename )
202 {
203 try
204 {
205
206 String artifactFilename = artifact.getFile().getAbsoluteFile().getPath();
207
208 messageBuilder.a( ':' ).a( artifactFilename );
209 }
210 catch ( NullPointerException e )
211 {
212
213 }
214 }
215
216 if ( theOutputScope && artifact.isOptional() )
217 {
218 messageBuilder.a( " (optional) " );
219 }
220
221
222 if ( artifact.getFile() != null )
223 {
224 ModuleDescriptor moduleDescriptor = getModuleDescriptor( artifact.getFile() );
225 if ( moduleDescriptor != null )
226 {
227 messageBuilder.project( " -- module " + moduleDescriptor.name );
228
229 if ( moduleDescriptor.automatic )
230 {
231 if ( "MANIFEST".equals( moduleDescriptor.moduleNameSource ) )
232 {
233 messageBuilder.strong( " [auto]" );
234 }
235 else
236 {
237 messageBuilder.warning( " (auto)" );
238 }
239 }
240 }
241 }
242 artifactStringList.add( messageBuilder.toString() + "\n" );
243 }
244 if ( theSort )
245 {
246 Collections.sort( artifactStringList );
247 }
248 for ( String artifactString : artifactStringList )
249 {
250 sb.append( artifactString );
251 }
252 return sb;
253 }
254
255 private ModuleDescriptor getModuleDescriptor( File artifactFile )
256 {
257 ModuleDescriptor moduleDescriptor = null;
258 try
259 {
260
261 Class<?> moduleFinderClass = Class.forName( "java.lang.module.ModuleFinder" );
262
263 java.nio.file.Path path = artifactFile.toPath();
264
265 Method ofMethod = moduleFinderClass.getMethod( "of", java.nio.file.Path[].class );
266 Object moduleFinderInstance = ofMethod.invoke( null, new Object[] { new java.nio.file.Path[] { path } } );
267
268 Method findAllMethod = moduleFinderClass.getMethod( "findAll" );
269 @SuppressWarnings( "unchecked" )
270 Set<Object> moduleReferences = (Set<Object>) findAllMethod.invoke( moduleFinderInstance );
271
272
273 if ( !moduleReferences.isEmpty() )
274 {
275 Object moduleReference = moduleReferences.iterator().next();
276 Method descriptorMethod = moduleReference.getClass().getMethod( "descriptor" );
277 Object moduleDescriptorInstance = descriptorMethod.invoke( moduleReference );
278
279 Method nameMethod = moduleDescriptorInstance.getClass().getMethod( "name" );
280 String name = (String) nameMethod.invoke( moduleDescriptorInstance );
281
282 moduleDescriptor = new ModuleDescriptor();
283 moduleDescriptor.name = name;
284
285 Method isAutomaticMethod = moduleDescriptorInstance.getClass().getMethod( "isAutomatic" );
286 moduleDescriptor.automatic = (Boolean) isAutomaticMethod.invoke( moduleDescriptorInstance );
287
288 if ( moduleDescriptor.automatic )
289 {
290 if ( artifactFile.isFile() )
291 {
292 JarFile jarFile = null;
293 try
294 {
295 jarFile = new JarFile( artifactFile );
296
297 Manifest manifest = jarFile.getManifest();
298
299 if ( manifest != null
300 && manifest.getMainAttributes().getValue( "Automatic-Module-Name" ) != null )
301 {
302 moduleDescriptor.moduleNameSource = "MANIFEST";
303 }
304 else
305 {
306 moduleDescriptor.moduleNameSource = "FILENAME";
307 }
308 }
309 catch ( IOException e )
310 {
311
312 }
313 finally
314 {
315 if ( jarFile != null )
316 {
317 try
318 {
319 jarFile.close();
320 }
321 catch ( IOException e )
322 {
323
324 }
325 }
326 }
327 }
328 }
329 }
330 }
331 catch ( ClassNotFoundException e )
332 {
333
334 }
335 catch ( NoSuchMethodException e )
336 {
337 e.printStackTrace();
338 }
339 catch ( SecurityException e )
340 {
341
342 }
343 catch ( IllegalAccessException e )
344 {
345
346 }
347 catch ( IllegalArgumentException e )
348 {
349
350 }
351 catch ( InvocationTargetException e )
352 {
353 Throwable cause = e.getCause();
354 while ( cause.getCause() != null )
355 {
356 cause = cause.getCause();
357 }
358 getLog().info( "Can't extract module name from " + artifactFile.getName() + ": " + cause.getMessage() );
359 }
360 return moduleDescriptor;
361 }
362
363 private class ModuleDescriptor
364 {
365 String name;
366
367 boolean automatic = true;
368
369 String moduleNameSource;
370 }
371 }