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