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