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