1 package org.apache.maven.plugin.testing;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.InputStream;
26 import java.io.Reader;
27 import java.lang.reflect.AccessibleObject;
28 import java.lang.reflect.Field;
29 import java.util.Arrays;
30 import java.util.HashMap;
31 import java.util.Map;
32
33 import org.apache.maven.artifact.Artifact;
34 import org.apache.maven.execution.DefaultMavenExecutionRequest;
35 import org.apache.maven.execution.DefaultMavenExecutionResult;
36 import org.apache.maven.execution.MavenExecutionRequest;
37 import org.apache.maven.execution.MavenExecutionResult;
38 import org.apache.maven.execution.MavenSession;
39 import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
40 import org.apache.maven.model.Plugin;
41 import org.apache.maven.monitor.logging.DefaultLog;
42 import org.apache.maven.plugin.Mojo;
43 import org.apache.maven.plugin.MojoExecution;
44 import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
45 import org.apache.maven.plugin.descriptor.MojoDescriptor;
46 import org.apache.maven.plugin.descriptor.Parameter;
47 import org.apache.maven.plugin.descriptor.PluginDescriptor;
48 import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
49 import org.apache.maven.plugin.logging.Log;
50 import org.apache.maven.project.MavenProject;
51 import org.apache.maven.repository.RepositorySystem;
52 import org.apache.maven.repository.internal.MavenRepositorySystemSession;
53 import org.codehaus.plexus.ContainerConfiguration;
54 import org.codehaus.plexus.DefaultContainerConfiguration;
55 import org.codehaus.plexus.DefaultPlexusContainer;
56 import org.codehaus.plexus.PlexusContainer;
57 import org.codehaus.plexus.PlexusContainerException;
58 import org.codehaus.plexus.PlexusTestCase;
59 import org.codehaus.plexus.classworlds.ClassWorld;
60 import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
61 import org.codehaus.plexus.component.configurator.ComponentConfigurator;
62 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
63 import org.codehaus.plexus.component.repository.ComponentDescriptor;
64 import org.codehaus.plexus.configuration.PlexusConfiguration;
65 import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
66 import org.codehaus.plexus.logging.LoggerManager;
67 import org.codehaus.plexus.util.InterpolationFilterReader;
68 import org.codehaus.plexus.util.ReaderFactory;
69 import org.codehaus.plexus.util.ReflectionUtils;
70 import org.codehaus.plexus.util.StringUtils;
71 import org.codehaus.plexus.util.xml.XmlStreamReader;
72 import org.codehaus.plexus.util.xml.Xpp3Dom;
73 import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public abstract class AbstractMojoTestCase
89 extends PlexusTestCase
90 {
91 private ComponentConfigurator configurator;
92
93 private PlexusContainer container;
94
95 private Map<String, MojoDescriptor> mojoDescriptors;
96
97
98
99
100
101
102
103
104 protected void setUp()
105 throws Exception
106 {
107 configurator = getContainer().lookup( ComponentConfigurator.class, "basic" );
108
109 InputStream is = getClass().getResourceAsStream( "/" + getPluginDescriptorLocation() );
110
111 XmlStreamReader reader = ReaderFactory.newXmlReader( is );
112
113 InterpolationFilterReader interpolationFilterReader =
114 new InterpolationFilterReader( new BufferedReader( reader ), container.getContext().getContextData() );
115
116 PluginDescriptor pluginDescriptor = new PluginDescriptorBuilder().build( interpolationFilterReader );
117
118 Artifact artifact =
119 lookup( RepositorySystem.class ).createArtifact( pluginDescriptor.getGroupId(),
120 pluginDescriptor.getArtifactId(),
121 pluginDescriptor.getVersion(), ".jar" );
122 artifact.setFile( new File( getBasedir() ).getCanonicalFile() );
123 pluginDescriptor.setPluginArtifact( artifact );
124 pluginDescriptor.setArtifacts( Arrays.asList( artifact ) );
125
126 for ( ComponentDescriptor<?> desc : pluginDescriptor.getComponents() )
127 {
128 getContainer().addComponentDescriptor( desc );
129 }
130
131 mojoDescriptors = new HashMap<String, MojoDescriptor>();
132 for ( MojoDescriptor mojoDescriptor : pluginDescriptor.getMojos() )
133 {
134 mojoDescriptors.put( mojoDescriptor.getGoal(), mojoDescriptor );
135 }
136 }
137
138 protected InputStream getPublicDescriptorStream()
139 throws Exception
140 {
141 return new FileInputStream( new File( getPluginDescriptorPath() ) );
142 }
143
144 protected String getPluginDescriptorPath()
145 {
146 return getBasedir() + "/target/classes/META-INF/maven/plugin.xml";
147 }
148
149 protected String getPluginDescriptorLocation()
150 {
151 return "META-INF/maven/plugin.xml";
152 }
153
154 protected void setupContainer()
155 {
156 ContainerConfiguration cc = setupContainerConfiguration();
157 try
158 {
159 container = new DefaultPlexusContainer( cc );
160 }
161 catch ( PlexusContainerException e )
162 {
163 e.printStackTrace();
164 fail( "Failed to create plexus container." );
165 }
166 }
167
168 protected ContainerConfiguration setupContainerConfiguration()
169 {
170 ClassWorld classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
171
172 return new DefaultContainerConfiguration().setClassWorld( classWorld ).setName( "embedder" );
173 }
174
175 protected PlexusContainer getContainer()
176 {
177 if ( container == null )
178 {
179 setupContainer();
180 }
181
182 return container;
183 }
184
185
186
187
188
189
190
191
192
193 protected Mojo lookupMojo( String goal, String pluginPom )
194 throws Exception
195 {
196 return lookupMojo( goal, new File( pluginPom ) );
197 }
198
199
200
201
202
203
204
205
206
207 protected Mojo lookupEmptyMojo( String goal, String pluginPom )
208 throws Exception
209 {
210 return lookupEmptyMojo( goal, new File( pluginPom ) );
211 }
212
213
214
215
216
217
218
219
220
221 protected Mojo lookupMojo( String goal, File pom )
222 throws Exception
223 {
224 File pluginPom = new File( getBasedir(), "pom.xml" );
225
226 Xpp3Dom pluginPomDom = Xpp3DomBuilder.build( ReaderFactory.newXmlReader( pluginPom ) );
227
228 String artifactId = pluginPomDom.getChild( "artifactId" ).getValue();
229
230 String groupId = resolveFromRootThenParent( pluginPomDom, "groupId" );
231
232 String version = resolveFromRootThenParent( pluginPomDom, "version" );
233
234 PlexusConfiguration pluginConfiguration = extractPluginConfiguration( artifactId, pom );
235
236 return lookupMojo( groupId, artifactId, version, goal, pluginConfiguration );
237 }
238
239
240
241
242
243
244
245
246
247 protected Mojo lookupEmptyMojo( String goal, File pom )
248 throws Exception
249 {
250 File pluginPom = new File( getBasedir(), "pom.xml" );
251
252 Xpp3Dom pluginPomDom = Xpp3DomBuilder.build( ReaderFactory.newXmlReader( pluginPom ) );
253
254 String artifactId = pluginPomDom.getChild( "artifactId" ).getValue();
255
256 String groupId = resolveFromRootThenParent( pluginPomDom, "groupId" );
257
258 String version = resolveFromRootThenParent( pluginPomDom, "version" );
259
260 return lookupMojo( groupId, artifactId, version, goal, null );
261 }
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283 protected Mojo lookupMojo( String groupId, String artifactId, String version, String goal,
284 PlexusConfiguration pluginConfiguration )
285 throws Exception
286 {
287 validateContainerStatus();
288
289
290
291 Mojo mojo = (Mojo) lookup( Mojo.ROLE, groupId + ":" + artifactId + ":" + version + ":" + goal );
292
293 LoggerManager loggerManager = (LoggerManager) getContainer().lookup( LoggerManager.class );
294
295 Log mojoLogger = new DefaultLog( loggerManager.getLoggerForComponent( Mojo.ROLE ) );
296
297 mojo.setLog( mojoLogger );
298
299 if ( pluginConfiguration != null )
300 {
301
302
303
304
305 ExpressionEvaluator evaluator = new ResolverExpressionEvaluatorStub();
306
307 configurator.configureComponent( mojo, pluginConfiguration, evaluator, getContainer().getContainerRealm() );
308 }
309
310 return mojo;
311 }
312
313 protected Mojo lookupConfiguredMojo( MavenProject project, String goal )
314 throws Exception
315 {
316 return lookupConfiguredMojo( newMavenSession( project ), newMojoExecution( goal ) );
317 }
318
319 protected Mojo lookupConfiguredMojo( MavenSession session, MojoExecution execution )
320 throws Exception, ComponentConfigurationException
321 {
322 MavenProject project = session.getCurrentProject();
323 MojoDescriptor mojoDescriptor = execution.getMojoDescriptor();
324
325 Mojo mojo = (Mojo) lookup( mojoDescriptor.getRole(), mojoDescriptor.getRoleHint() );
326
327 ExpressionEvaluator evaluator = new PluginParameterExpressionEvaluator( session, execution );
328
329 Xpp3Dom configuration = null;
330 Plugin plugin = project.getPlugin( mojoDescriptor.getPluginDescriptor().getPluginLookupKey() );
331 if ( plugin != null )
332 {
333 configuration = (Xpp3Dom) plugin.getConfiguration();
334 }
335 if ( configuration == null )
336 {
337 configuration = new Xpp3Dom( "configuration" );
338 }
339 configuration = Xpp3Dom.mergeXpp3Dom( execution.getConfiguration(), configuration );
340
341 PlexusConfiguration pluginConfiguration = new XmlPlexusConfiguration( configuration );
342
343 configurator.configureComponent( mojo, pluginConfiguration, evaluator, getContainer().getContainerRealm() );
344
345 return mojo;
346 }
347
348 protected MavenSession newMavenSession( MavenProject project )
349 {
350 MavenExecutionRequest request = new DefaultMavenExecutionRequest();
351 MavenExecutionResult result = new DefaultMavenExecutionResult();
352
353 MavenSession session = new MavenSession( container, new MavenRepositorySystemSession(), request, result );
354 session.setCurrentProject( project );
355 session.setProjects( Arrays.asList( project ) );
356 return session;
357 }
358
359 protected MojoExecution newMojoExecution( String goal )
360 {
361 MojoDescriptor mojoDescriptor = mojoDescriptors.get( goal );
362 assertNotNull( mojoDescriptor );
363 MojoExecution execution = new MojoExecution( mojoDescriptor );
364 finalizeMojoConfiguration( execution );
365 return execution;
366 }
367
368
369 private void finalizeMojoConfiguration( MojoExecution mojoExecution )
370 {
371 MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
372
373 Xpp3Dom executionConfiguration = mojoExecution.getConfiguration();
374 if ( executionConfiguration == null )
375 {
376 executionConfiguration = new Xpp3Dom( "configuration" );
377 }
378
379 Xpp3Dom defaultConfiguration = MojoDescriptorCreator.convert( mojoDescriptor );;
380
381 Xpp3Dom finalConfiguration = new Xpp3Dom( "configuration" );
382
383 if ( mojoDescriptor.getParameters() != null )
384 {
385 for ( Parameter parameter : mojoDescriptor.getParameters() )
386 {
387 Xpp3Dom parameterConfiguration = executionConfiguration.getChild( parameter.getName() );
388
389 if ( parameterConfiguration == null )
390 {
391 parameterConfiguration = executionConfiguration.getChild( parameter.getAlias() );
392 }
393
394 Xpp3Dom parameterDefaults = defaultConfiguration.getChild( parameter.getName() );
395
396 parameterConfiguration = Xpp3Dom.mergeXpp3Dom( parameterConfiguration, parameterDefaults, Boolean.TRUE );
397
398 if ( parameterConfiguration != null )
399 {
400 parameterConfiguration = new Xpp3Dom( parameterConfiguration, parameter.getName() );
401
402 if ( StringUtils.isEmpty( parameterConfiguration.getAttribute( "implementation" ) )
403 && StringUtils.isNotEmpty( parameter.getImplementation() ) )
404 {
405 parameterConfiguration.setAttribute( "implementation", parameter.getImplementation() );
406 }
407
408 finalConfiguration.addChild( parameterConfiguration );
409 }
410 }
411 }
412
413 mojoExecution.setConfiguration( finalConfiguration );
414 }
415
416
417
418
419
420
421
422 protected PlexusConfiguration extractPluginConfiguration( String artifactId, File pom )
423 throws Exception
424 {
425 Reader reader = ReaderFactory.newXmlReader( pom );
426
427 Xpp3Dom pomDom = Xpp3DomBuilder.build( reader );
428
429 return extractPluginConfiguration( artifactId, pomDom );
430 }
431
432
433
434
435
436
437
438 protected PlexusConfiguration extractPluginConfiguration( String artifactId, Xpp3Dom pomDom )
439 throws Exception
440 {
441 Xpp3Dom pluginConfigurationElement = null;
442
443 Xpp3Dom buildElement = pomDom.getChild( "build" );
444 if ( buildElement != null )
445 {
446 Xpp3Dom pluginsRootElement = buildElement.getChild( "plugins" );
447
448 if ( pluginsRootElement != null )
449 {
450 Xpp3Dom[] pluginElements = pluginsRootElement.getChildren();
451
452 for ( Xpp3Dom pluginElement : pluginElements )
453 {
454 String pluginElementArtifactId = pluginElement.getChild( "artifactId" ).getValue();
455
456 if ( pluginElementArtifactId.equals( artifactId ) )
457 {
458 pluginConfigurationElement = pluginElement.getChild( "configuration" );
459
460 break;
461 }
462 }
463
464 if ( pluginConfigurationElement == null )
465 {
466 throw new ConfigurationException( "Cannot find a configuration element for a plugin with an "
467 + "artifactId of " + artifactId + "." );
468 }
469 }
470 }
471
472 if ( pluginConfigurationElement == null )
473 {
474 throw new ConfigurationException( "Cannot find a configuration element for a plugin with an artifactId of "
475 + artifactId + "." );
476 }
477
478 return new XmlPlexusConfiguration( pluginConfigurationElement );
479 }
480
481
482
483
484
485
486
487
488
489
490 protected Mojo configureMojo( Mojo mojo, String artifactId, File pom )
491 throws Exception
492 {
493 validateContainerStatus();
494
495 PlexusConfiguration pluginConfiguration = extractPluginConfiguration( artifactId, pom );
496
497 ExpressionEvaluator evaluator = new ResolverExpressionEvaluatorStub();
498
499 configurator.configureComponent( mojo, pluginConfiguration, evaluator, getContainer().getContainerRealm() );
500
501 return mojo;
502 }
503
504
505
506
507
508
509
510
511
512 protected Mojo configureMojo( Mojo mojo, PlexusConfiguration pluginConfiguration )
513 throws Exception
514 {
515 validateContainerStatus();
516
517 ExpressionEvaluator evaluator = new ResolverExpressionEvaluatorStub();
518
519 configurator.configureComponent( mojo, pluginConfiguration, evaluator, getContainer().getContainerRealm() );
520
521 return mojo;
522 }
523
524
525
526
527
528
529
530
531
532
533
534 protected Object getVariableValueFromObject( Object object, String variable )
535 throws IllegalAccessException
536 {
537 Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses( variable, object.getClass() );
538
539 field.setAccessible( true );
540
541 return field.get( object );
542 }
543
544
545
546
547
548
549
550
551
552 protected Map<String, Object> getVariablesAndValuesFromObject( Object object )
553 throws IllegalAccessException
554 {
555 return getVariablesAndValuesFromObject( object.getClass(), object );
556 }
557
558
559
560
561
562
563
564
565
566
567 protected Map<String, Object> getVariablesAndValuesFromObject( Class<?> clazz, Object object )
568 throws IllegalAccessException
569 {
570 Map<String, Object> map = new HashMap<String, Object>();
571
572 Field[] fields = clazz.getDeclaredFields();
573
574 AccessibleObject.setAccessible( fields, true );
575
576 for ( Field field : fields )
577 {
578 map.put( field.getName(), field.get( object ) );
579 }
580
581 Class<?> superclass = clazz.getSuperclass();
582
583 if ( !Object.class.equals( superclass ) )
584 {
585 map.putAll( getVariablesAndValuesFromObject( superclass, object ) );
586 }
587
588 return map;
589 }
590
591
592
593
594
595
596
597
598
599 protected void setVariableValueToObject( Object object, String variable, Object value )
600 throws IllegalAccessException
601 {
602 Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses( variable, object.getClass() );
603
604 field.setAccessible( true );
605
606 field.set( object, value );
607 }
608
609
610
611
612
613
614
615
616
617
618
619 private String resolveFromRootThenParent( Xpp3Dom pluginPomDom, String element )
620 throws Exception
621 {
622 Xpp3Dom elementDom = pluginPomDom.getChild( element );
623
624
625 if ( elementDom == null )
626 {
627 Xpp3Dom pluginParentDom = pluginPomDom.getChild( "parent" );
628
629 if ( pluginParentDom != null )
630 {
631 elementDom = pluginParentDom.getChild( element );
632
633 if ( elementDom == null )
634 {
635 throw new Exception( "unable to determine " + element );
636 }
637
638 return elementDom.getValue();
639 }
640
641 throw new Exception( "unable to determine " + element );
642 }
643
644 return elementDom.getValue();
645 }
646
647
648
649
650
651
652
653
654
655 private void validateContainerStatus()
656 throws Exception
657 {
658 if ( getContainer() != null )
659 {
660 return;
661 }
662
663 throw new Exception( "container is null, make sure super.setUp() is called" );
664 }
665 }