1 | |
package org.apache.maven.tools.plugin.annotations.scanner; |
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 | |
import org.apache.maven.plugins.annotations.Component; |
24 | |
import org.apache.maven.plugins.annotations.Execute; |
25 | |
import org.apache.maven.plugins.annotations.Mojo; |
26 | |
import org.apache.maven.plugins.annotations.Parameter; |
27 | |
import org.apache.maven.tools.plugin.annotations.datamodel.ComponentAnnotationContent; |
28 | |
import org.apache.maven.tools.plugin.annotations.datamodel.ExecuteAnnotationContent; |
29 | |
import org.apache.maven.tools.plugin.annotations.datamodel.MojoAnnotationContent; |
30 | |
import org.apache.maven.tools.plugin.annotations.datamodel.ParameterAnnotationContent; |
31 | |
import org.apache.maven.tools.plugin.annotations.scanner.visitors.MojoAnnotationVisitor; |
32 | |
import org.apache.maven.tools.plugin.annotations.scanner.visitors.MojoClassVisitor; |
33 | |
import org.apache.maven.tools.plugin.annotations.scanner.visitors.MojoFieldVisitor; |
34 | |
import org.apache.maven.tools.plugin.extractor.ExtractionException; |
35 | |
import org.codehaus.plexus.logging.AbstractLogEnabled; |
36 | |
import org.codehaus.plexus.util.DirectoryScanner; |
37 | |
import org.codehaus.plexus.util.IOUtil; |
38 | |
import org.codehaus.plexus.util.StringUtils; |
39 | |
import org.codehaus.plexus.util.reflection.Reflector; |
40 | |
import org.objectweb.asm.ClassReader; |
41 | |
import org.objectweb.asm.Type; |
42 | |
|
43 | |
import java.io.BufferedInputStream; |
44 | |
import java.io.File; |
45 | |
import java.io.FileInputStream; |
46 | |
import java.io.IOException; |
47 | |
import java.io.InputStream; |
48 | |
import java.util.Collections; |
49 | |
import java.util.HashMap; |
50 | |
import java.util.List; |
51 | |
import java.util.Map; |
52 | |
import java.util.zip.ZipEntry; |
53 | |
import java.util.zip.ZipInputStream; |
54 | |
|
55 | |
|
56 | |
|
57 | |
|
58 | |
|
59 | |
@org.codehaus.plexus.component.annotations.Component( role = MojoAnnotationsScanner.class ) |
60 | 1 | public class DefaultMojoAnnotationsScanner |
61 | |
extends AbstractLogEnabled |
62 | |
implements MojoAnnotationsScanner |
63 | |
{ |
64 | 1 | private Reflector reflector = new Reflector(); |
65 | |
|
66 | |
public Map<String, MojoAnnotatedClass> scan( MojoAnnotationsScannerRequest request ) |
67 | |
throws ExtractionException |
68 | |
{ |
69 | 1 | Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = new HashMap<String, MojoAnnotatedClass>(); |
70 | |
try |
71 | |
{ |
72 | |
|
73 | 1 | for ( Artifact dependency : request.getDependencies() ) |
74 | |
{ |
75 | 0 | File dependencyFile = dependency.getFile(); |
76 | 0 | if ( dependencyFile != null && dependencyFile.exists() ) |
77 | |
{ |
78 | 0 | if ( dependencyFile.isDirectory() ) |
79 | |
{ |
80 | 0 | mojoAnnotatedClasses.putAll( |
81 | |
scanDirectory( dependencyFile, request.getIncludePatterns(), dependency, true ) ); |
82 | |
} |
83 | |
else |
84 | |
{ |
85 | 0 | mojoAnnotatedClasses.putAll( |
86 | |
scanFile( dependencyFile, request.getIncludePatterns(), dependency, true ) ); |
87 | |
} |
88 | |
} |
89 | 0 | } |
90 | |
|
91 | 1 | for ( File classDirectory : request.getClassesDirectories() ) |
92 | |
{ |
93 | 1 | if ( classDirectory.exists() && classDirectory.isDirectory() ) |
94 | |
{ |
95 | 1 | mojoAnnotatedClasses.putAll( |
96 | |
scanDirectory( classDirectory, request.getIncludePatterns(), request.getProject().getArtifact(), |
97 | |
false ) ); |
98 | |
} |
99 | |
} |
100 | |
|
101 | 1 | return mojoAnnotatedClasses; |
102 | |
} |
103 | 0 | catch ( IOException e ) |
104 | |
{ |
105 | 0 | throw new ExtractionException( e.getMessage(), e ); |
106 | |
} |
107 | |
} |
108 | |
|
109 | |
|
110 | |
|
111 | |
|
112 | |
|
113 | |
|
114 | |
|
115 | |
|
116 | |
|
117 | |
|
118 | |
protected Map<String, MojoAnnotatedClass> scanFile( File archiveFile, List<String> includePatterns, |
119 | |
Artifact artifact, boolean excludeMojo ) |
120 | |
throws IOException, ExtractionException |
121 | |
{ |
122 | 0 | if ( !archiveFile.exists() ) |
123 | |
{ |
124 | 0 | return Collections.emptyMap(); |
125 | |
} |
126 | 0 | Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = new HashMap<String, MojoAnnotatedClass>(); |
127 | 0 | ZipInputStream archiveStream = new ZipInputStream( new FileInputStream( archiveFile ) ); |
128 | |
|
129 | |
try |
130 | |
{ |
131 | 0 | for ( ZipEntry zipEntry = archiveStream.getNextEntry(); zipEntry != null; |
132 | 0 | zipEntry = archiveStream.getNextEntry() ) |
133 | |
{ |
134 | 0 | if ( zipEntry.getName().endsWith( ".class" ) ) |
135 | |
{ |
136 | 0 | MojoClassVisitor mojoClassVisitor = new MojoClassVisitor( getLogger() ); |
137 | |
|
138 | 0 | ClassReader rdr = new ClassReader( archiveStream ); |
139 | 0 | rdr.accept( mojoClassVisitor, |
140 | |
ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG ); |
141 | 0 | analyzeVisitors( mojoClassVisitor ); |
142 | 0 | if ( excludeMojo ) |
143 | |
{ |
144 | 0 | mojoClassVisitor.getMojoAnnotatedClass().setMojo( null ); |
145 | |
} |
146 | 0 | if ( isStoreClass( mojoClassVisitor.getMojoAnnotatedClass() ) != null ) |
147 | |
{ |
148 | 0 | getLogger().debug( |
149 | |
"found MojoAnnotatedClass:" + mojoClassVisitor.getMojoAnnotatedClass().getClassName() + ":" |
150 | |
+ mojoClassVisitor.getMojoAnnotatedClass() ); |
151 | 0 | mojoClassVisitor.getMojoAnnotatedClass().setArtifact( artifact ); |
152 | 0 | mojoAnnotatedClasses.put( mojoClassVisitor.getMojoAnnotatedClass().getClassName(), |
153 | |
mojoClassVisitor.getMojoAnnotatedClass() ); |
154 | |
} |
155 | |
} |
156 | |
} |
157 | |
} |
158 | |
finally |
159 | |
{ |
160 | 0 | IOUtil.close( archiveStream ); |
161 | 0 | } |
162 | 0 | return mojoAnnotatedClasses; |
163 | |
} |
164 | |
|
165 | |
|
166 | |
|
167 | |
|
168 | |
|
169 | |
|
170 | |
|
171 | |
|
172 | |
|
173 | |
|
174 | |
protected Map<String, MojoAnnotatedClass> scanDirectory( File classDirectory, List<String> includePatterns, |
175 | |
Artifact artifact, boolean excludeMojo ) |
176 | |
throws IOException, ExtractionException |
177 | |
{ |
178 | 1 | if ( !classDirectory.exists() ) |
179 | |
{ |
180 | 0 | return Collections.emptyMap(); |
181 | |
} |
182 | 1 | Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = new HashMap<String, MojoAnnotatedClass>(); |
183 | 1 | DirectoryScanner scanner = new DirectoryScanner(); |
184 | 1 | scanner.setBasedir( classDirectory ); |
185 | 1 | scanner.addDefaultExcludes(); |
186 | 1 | if ( includePatterns != null ) |
187 | |
{ |
188 | 1 | scanner.setIncludes( includePatterns.toArray( new String[includePatterns.size()] ) ); |
189 | |
} |
190 | 1 | scanner.scan(); |
191 | 1 | String[] classFiles = scanner.getIncludedFiles(); |
192 | |
|
193 | 2 | for ( String classFile : classFiles ) |
194 | |
{ |
195 | 1 | InputStream is = new BufferedInputStream( new FileInputStream( new File( classDirectory, classFile ) ) ); |
196 | |
try |
197 | |
{ |
198 | |
|
199 | 1 | if ( classFile.endsWith( ".class" ) ) |
200 | |
{ |
201 | 1 | MojoClassVisitor mojoClassVisitor = new MojoClassVisitor( getLogger() ); |
202 | 1 | ClassReader rdr = new ClassReader( is ); |
203 | 1 | rdr.accept( mojoClassVisitor, |
204 | |
ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG ); |
205 | 1 | analyzeVisitors( mojoClassVisitor ); |
206 | 1 | if ( excludeMojo ) |
207 | |
{ |
208 | 0 | mojoClassVisitor.getMojoAnnotatedClass().setMojo( null ); |
209 | |
} |
210 | 1 | if ( isStoreClass( mojoClassVisitor.getMojoAnnotatedClass() ) != null ) |
211 | |
{ |
212 | 1 | getLogger().debug( |
213 | |
"found MojoAnnotatedClass:" + mojoClassVisitor.getMojoAnnotatedClass().getClassName() + ":" |
214 | |
+ mojoClassVisitor.getMojoAnnotatedClass() ); |
215 | 1 | mojoClassVisitor.getMojoAnnotatedClass().setArtifact( artifact ); |
216 | 1 | mojoAnnotatedClasses.put( mojoClassVisitor.getMojoAnnotatedClass().getClassName(), |
217 | |
mojoClassVisitor.getMojoAnnotatedClass() ); |
218 | |
} |
219 | |
|
220 | |
} |
221 | |
} |
222 | |
finally |
223 | |
{ |
224 | 1 | IOUtil.close( is ); |
225 | 1 | } |
226 | |
|
227 | |
} |
228 | 1 | return mojoAnnotatedClasses; |
229 | |
} |
230 | |
|
231 | |
private MojoAnnotatedClass isStoreClass( MojoAnnotatedClass mojoAnnotatedClass ) |
232 | |
{ |
233 | |
|
234 | 1 | if ( mojoAnnotatedClass == null ) |
235 | |
{ |
236 | 0 | return null; |
237 | |
} |
238 | 1 | return mojoAnnotatedClass; |
239 | |
|
240 | |
|
241 | |
|
242 | |
|
243 | |
|
244 | |
|
245 | |
|
246 | |
|
247 | |
} |
248 | |
|
249 | |
|
250 | |
protected void analyzeVisitors( MojoClassVisitor mojoClassVisitor ) |
251 | |
throws ExtractionException |
252 | |
{ |
253 | |
|
254 | |
try |
255 | |
{ |
256 | 1 | MojoAnnotationVisitor mojoAnnotationVisitor = |
257 | |
mojoClassVisitor.getAnnotationVisitorMap().get( Mojo.class.getName() ); |
258 | 1 | if ( mojoAnnotationVisitor != null ) |
259 | |
{ |
260 | 1 | MojoAnnotationContent mojoAnnotationContent = new MojoAnnotationContent(); |
261 | 1 | for ( Map.Entry<String, Object> entry : mojoAnnotationVisitor.getAnnotationValues().entrySet() ) |
262 | |
{ |
263 | 3 | reflector.invoke( mojoAnnotationContent, entry.getKey(), new Object[]{ entry.getValue() } ); |
264 | |
} |
265 | 1 | mojoClassVisitor.getMojoAnnotatedClass().setMojo( mojoAnnotationContent ); |
266 | |
} |
267 | |
|
268 | 1 | mojoAnnotationVisitor = mojoClassVisitor.getAnnotationVisitorMap().get( Execute.class.getName() ); |
269 | 1 | if ( mojoAnnotationVisitor != null ) |
270 | |
{ |
271 | 1 | ExecuteAnnotationContent executeAnnotationContent = new ExecuteAnnotationContent(); |
272 | |
|
273 | 1 | for ( Map.Entry<String, Object> entry : mojoAnnotationVisitor.getAnnotationValues().entrySet() ) |
274 | |
{ |
275 | 3 | reflector.invoke( executeAnnotationContent, entry.getKey(), new Object[]{ entry.getValue() } ); |
276 | |
} |
277 | 1 | mojoClassVisitor.getMojoAnnotatedClass().setExecute( executeAnnotationContent ); |
278 | |
} |
279 | |
|
280 | 1 | List<MojoFieldVisitor> mojoFieldVisitors = |
281 | |
mojoClassVisitor.findFieldWithAnnotationClass( Parameter.class.getName() ); |
282 | |
|
283 | 1 | for ( MojoFieldVisitor mojoFieldVisitor : mojoFieldVisitors ) |
284 | |
{ |
285 | 2 | ParameterAnnotationContent parameterAnnotationContent = |
286 | |
new ParameterAnnotationContent( mojoFieldVisitor.getFieldName(), mojoFieldVisitor.getClassName() ); |
287 | 2 | if ( mojoFieldVisitor.getMojoAnnotationVisitor() != null ) |
288 | |
{ |
289 | 2 | for ( Map.Entry<String, Object> entry : mojoFieldVisitor.getMojoAnnotationVisitor().getAnnotationValues().entrySet() ) |
290 | |
{ |
291 | 5 | reflector.invoke( parameterAnnotationContent, entry.getKey(), |
292 | |
new Object[]{ entry.getValue() } ); |
293 | |
} |
294 | |
|
295 | |
} |
296 | 2 | mojoClassVisitor.getMojoAnnotatedClass().getParameters().put( parameterAnnotationContent.getFieldName(), |
297 | |
parameterAnnotationContent ); |
298 | 2 | } |
299 | |
|
300 | 1 | mojoFieldVisitors = mojoClassVisitor.findFieldWithAnnotationClass( Component.class.getName() ); |
301 | |
|
302 | 1 | for ( MojoFieldVisitor mojoFieldVisitor : mojoFieldVisitors ) |
303 | |
{ |
304 | 2 | ComponentAnnotationContent componentAnnotationContent = |
305 | |
new ComponentAnnotationContent( mojoFieldVisitor.getFieldName() ); |
306 | |
|
307 | 2 | if ( mojoFieldVisitor.getMojoAnnotationVisitor() != null ) |
308 | |
{ |
309 | 2 | for ( Map.Entry<String, Object> entry : mojoFieldVisitor.getMojoAnnotationVisitor().getAnnotationValues().entrySet() ) |
310 | |
{ |
311 | 2 | String methodName = entry.getKey(); |
312 | 2 | if ( StringUtils.equals( "role", methodName ) ) |
313 | |
{ |
314 | 1 | Type type = (Type) entry.getValue(); |
315 | 1 | componentAnnotationContent.setRoleClassName( type.getClassName() ); |
316 | 1 | } |
317 | |
else |
318 | |
{ |
319 | 1 | reflector.invoke( componentAnnotationContent, entry.getKey(), |
320 | |
new Object[]{ entry.getValue() } ); |
321 | |
} |
322 | 2 | } |
323 | 2 | if ( StringUtils.isEmpty( componentAnnotationContent.getRoleClassName() ) ) |
324 | |
{ |
325 | 1 | componentAnnotationContent.setRoleClassName( mojoFieldVisitor.getClassName() ); |
326 | |
} |
327 | |
} |
328 | 2 | mojoClassVisitor.getMojoAnnotatedClass().getComponents().put( componentAnnotationContent.getFieldName(), |
329 | |
componentAnnotationContent ); |
330 | 2 | } |
331 | |
|
332 | |
} |
333 | 0 | catch ( Exception e ) |
334 | |
{ |
335 | 0 | throw new ExtractionException( e.getMessage(), e ); |
336 | 1 | } |
337 | 1 | } |
338 | |
} |