View Javadoc
1   package org.codehaus.gmavenplus.mojo;
2   
3   import org.apache.maven.plugins.annotations.Component;
4   import org.apache.maven.plugins.annotations.Parameter;
5   import org.apache.maven.project.MavenProjectHelper;
6   import org.codehaus.gmavenplus.model.IncludeClasspath;
7   
8   import java.lang.reflect.InvocationTargetException;
9   import java.util.Properties;
10  
11  import static org.codehaus.gmavenplus.util.ReflectionUtils.findConstructor;
12  import static org.codehaus.gmavenplus.util.ReflectionUtils.invokeConstructor;
13  
14  
15  /**
16   * The base tools mojo, which all tool mojos extend.
17   * Note that it references the plugin classloader to pull in dependencies
18   * Groovy didn't include (for things like Ant for AntBuilder, Ivy for @grab, and Jansi for Groovysh).
19   * Note that using the <code>ant</code> property requires Java 8, as the included Ant version was compiled for Java 8.
20   *
21   * @author Keegan Witt
22   */
23  public abstract class AbstractToolsMojo extends AbstractGroovyMojo {
24  
25      /**
26       * Maven ProjectHelper to use in properties.
27       *
28       * @since 1.3
29       */
30      @Component
31      protected MavenProjectHelper projectHelper;
32  
33      /**
34       * Properties to make available in scripts as variables using the property name. By default will include
35       * <dl>
36       *   <dt>project</dt>
37       *     <dd>A org.apache.maven.project.Project object of the current Maven project.</dd>
38       *   <dt>session</dt>
39       *     <dd>A org.apache.maven.execution.MavenSession object of the current Maven session.</dd>
40       *   <dt>pluginArtifacts</dt>
41       *     <dd>A list of org.apache.maven.artifact.Artifact objects of this plugin's artifacts.</dd>
42       *   <dt>mojoExecution</dt>
43       *     <dd>A org.apache.maven.plugin.MojoExecution object of this plugin's mojo execution.</dd>
44       *   <dt>log</dt>
45       *     <dd>A org.apache.maven.plugin.logging.Log object of Maven's log.</dd>
46       *   <dt>ant</dt>
47       *     <dd>A groovy.util.AntBuilder object (if groovy.ant.AntBuilder or groovy.util.AntBuilder is available).</dd>
48       * </dl>
49       * These can be overridden.
50       *
51       * @since 1.0-beta-3
52       */
53      @Parameter
54      protected Properties properties = new Properties();
55  
56      /**
57       * Whether to allow System.exit() to be used. Should not be set to <code>false</code> when using parallel
58       * execution, as it isn't thread-safe.
59       *
60       * @since 1.2
61       */
62      @Parameter(defaultValue = "true")
63      protected boolean allowSystemExits;
64  
65      /**
66       * Whether to bind each property to a separate variable (otherwise binds properties to a single 'properties' variable).
67       *
68       * @since 1.2
69       */
70      @Parameter(defaultValue = "true")
71      protected boolean bindPropertiesToSeparateVariables;
72  
73      /**
74       * What classpath to include. One of
75       * <ul>
76       *   <li>PROJECT_ONLY</li>
77       *   <li>PROJECT_AND_PLUGIN</li>
78       *   <li>PLUGIN_ONLY</li>
79       * </ul>
80       * Uses the same scope as the required dependency resolution of this mojo. Use only if you know what you're doing.
81       *
82       * @since 1.8.0
83       */
84      @Parameter(defaultValue = "PROJECT_AND_PLUGIN")
85      protected IncludeClasspath includeClasspath;
86  
87      /**
88       * Whether to add all properties from <code>project.properties</code> into properties.
89       *
90       * @since 1.10.1
91       */
92      @Parameter(defaultValue = "false")
93      protected boolean bindAllProjectProperties;
94  
95      /**
96       * Whether to add user session properties from <code>session.userProperties</code> that override project properties
97       * into properties. <code>bindAllSessionUserProperties</code> takes priority over this property if present. Has no
98       * effect if <code>bindAllProjectProperties</code> is <code>false</code>.
99       *
100      * @since 1.10.1
101      */
102     @Parameter(defaultValue = "false")
103     protected boolean bindSessionUserOverrideProperties;
104 
105     /**
106      * Whether to add all properties from <code>session.userProperties</code> into properties. If both
107      * <code>bindAllProjectProperties</code> and <code>bindAllSessionUserProperties</code> are specified, the session
108      * properties will override the project properties, but it will also include properties not present in project
109      * properties. To only include user session properties that are also in project properties, use
110      * <code>bindSessionUserOverrideProperties</code>.
111      *
112      * @since 1.10.1
113      */
114     @Parameter(defaultValue = "false")
115     protected boolean bindAllSessionUserProperties;
116 
117     /**
118      * Initializes the properties field.
119      */
120     protected void initializeProperties() {
121         if (project != null && !properties.containsKey("project")) {
122             properties.put("project", project);
123         }
124         if (session != null && !properties.containsKey("session")) {
125             properties.put("session", session);
126         }
127         if (pluginArtifacts != null && !properties.containsKey("pluginArtifacts")) {
128             properties.put("pluginArtifacts", pluginArtifacts);
129         }
130         if (mojoExecution != null && !properties.containsKey("mojoExecution")) {
131             properties.put("mojoExecution", mojoExecution);
132         }
133         if (!properties.containsKey("log")) {
134             properties.put("log", getLog());
135         }
136         if (projectHelper != null && !properties.containsKey("projectHelper")) {
137             properties.put("projectHelper", projectHelper);
138         }
139         if (!properties.containsKey("ant")) {
140             Object antBuilder = null;
141             try {
142                 antBuilder = invokeConstructor(findConstructor(classWrangler.getClass("groovy.ant.AntBuilder")));
143             } catch (ClassNotFoundException e1) {
144                 getLog().debug("groovy.ant.AntBuilder not available, trying groovy.util.AntBuilder.");
145                 try {
146                     antBuilder = invokeConstructor(findConstructor(classWrangler.getClass("groovy.util.AntBuilder")));
147                 } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e2) {
148                     logUnableToInitializeAntBuilder(e2);
149                 }
150             } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
151                 logUnableToInitializeAntBuilder(e);
152             }
153             if (antBuilder != null) {
154                 properties.put("ant", antBuilder);
155             }
156         }
157         if (bindSessionUserOverrideProperties && !bindAllProjectProperties) {
158             getLog().warn("bindSessionUserOverrideProperties set without bindAllProjectProperties, ignoring.");
159         }
160         if (bindAllSessionUserProperties && bindSessionUserOverrideProperties) {
161             getLog().warn("bindAllSessionUserProperties and bindSessionUserOverrideProperties both set, bindAllSessionUserProperties will take precedence.");
162         }
163         if (bindAllProjectProperties && project != null) {
164             properties.putAll(project.getProperties());
165         }
166         if (session != null) {
167             if (bindAllSessionUserProperties) {
168                 properties.putAll(session.getUserProperties());
169             } else if (bindAllProjectProperties && bindSessionUserOverrideProperties && project != null) {
170                 for (Object key : project.getProperties().keySet()) {
171                     if (session.getUserProperties().get(key) != null) {
172                         properties.put(key, session.getUserProperties().get(key));
173                     }
174                 }
175             }
176         }
177     }
178 
179     /**
180      * Logs errors that caused the 'ant' object to not be populated.
181      *
182      * @param e the exception causing the failure
183      */
184     protected void logUnableToInitializeAntBuilder(final Throwable e) {
185         getLog().warn("Unable to initialize 'ant' with a new AntBuilder object. Is Groovy a dependency?  If you are using Groovy >= 2.3.0-rc-1, remember to include groovy-ant as a dependency.");
186     }
187 
188 }