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 }