View Javadoc

1   /*
2    * #%L
3    * License Maven Plugin
4    *
5    * $Id: AbstractLicenseMojo.java 14409 2011-08-10 15:30:41Z tchemit $
6    * $HeadURL: http://svn.codehaus.org/mojo/tags/license-maven-plugin-1.0/src/main/java/org/codehaus/mojo/license/AbstractLicenseMojo.java $
7    * %%
8    * Copyright (C) 2008 - 2011 CodeLutin, Codehaus, Tony Chemit
9    * %%
10   * This program is free software: you can redistribute it and/or modify
11   * it under the terms of the GNU Lesser General Public License as
12   * published by the Free Software Foundation, either version 3 of the
13   * License, or (at your option) any later version.
14   *
15   * This program is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   * GNU General Lesser Public License for more details.
19   *
20   * You should have received a copy of the GNU General Lesser Public
21   * License along with this program.  If not, see
22   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
23   * #L%
24   */
25  
26  package org.codehaus.mojo.license;
27  
28  import java.io.File;
29  import java.util.Arrays;
30  
31  import org.apache.commons.lang.StringUtils;
32  import org.apache.maven.execution.MavenSession;
33  import org.apache.maven.plugin.AbstractMojo;
34  import org.apache.maven.plugin.MojoExecutionException;
35  import org.apache.maven.plugin.MojoFailureException;
36  import org.apache.maven.project.MavenProject;
37  import org.codehaus.plexus.util.ReaderFactory;
38  
39  /**
40   * Abstract license mojo.
41   *
42   * @author tchemit <chemit@codelutin.com>
43   * @since 1.0
44   */
45  public abstract class AbstractLicenseMojo extends AbstractMojo {
46  
47      /**
48       * Current maven session. (used to launch certain mojo once by build).
49       *
50       * @parameter expression="${session}"
51       * @required
52       * @readonly
53       * @since 1.0
54       */
55      private MavenSession session;
56  
57      /**
58       * The reacted project.
59       *
60       * @parameter default-value="${project}"
61       * @required
62       * @since 1.0
63       */
64      private MavenProject project;
65  
66      /**
67       * Flag to activate verbose mode.
68       * <p/>
69       * <b>Note:</b> Verbose mode is always on if you starts a debug maven instance (says via {@code -X}).
70       *
71       * @parameter expression="${license.verbose}" default-value="${maven.verbose}"
72       * @since 1.0
73       */
74      private boolean verbose;
75  
76      /**
77       * Encoding used to read and writes files.
78       * <p/>
79       * <b>Note:</b> If nothing is filled here, we will use the system property {@code file.encoding}.
80       *
81       * @parameter expression="${license.encoding}" default-value="${project.build.sourceEncoding}"
82       * @since 1.0
83       */
84      private String encoding;
85  
86      public final String getEncoding() {
87          return encoding;
88      }
89  
90      public final void setEncoding(String encoding) {
91          this.encoding = encoding;
92      }
93  
94      /**
95       * Method to initialize the mojo before doing any concrete actions.
96       * <p/>
97       * <b>Note:</b> The method is invoked before the {@link #doAction()} method.
98       *
99       * @throws Exception
100      *             if any
101      */
102     protected abstract void init() throws Exception;
103 
104     /**
105      * Do plugin action.
106      * <p/>
107      * The method {@link #execute()} invoke this method only and only if :
108      * <ul>
109      * <li>{@link #checkPackaging()} returns {@code true}.</li>
110      * <li>method {@link #init()} returns {@code true}.</li>
111      * </ul>
112      *
113      * @throws Exception
114      *             if any
115      */
116     protected abstract void doAction() throws Exception;
117 
118     @Override
119     public final void execute() throws MojoExecutionException, MojoFailureException {
120         try {
121             if (getLog().isDebugEnabled()) {
122 
123                 // always be verbose in debug mode
124                 setVerbose(true);
125             }
126 
127             // check if project packaging is compatible with the mojo
128 
129             boolean canContinue = checkPackaging();
130             if (!canContinue) {
131                 getLog().debug("Skip for packaging '" + getProject().getPackaging() + "'");
132                 return;
133             }
134 
135             // init the mojo
136 
137             try {
138 
139                 checkEncoding();
140 
141                 init();
142 
143             } catch (MojoFailureException e) {
144                 throw e;
145             } catch (MojoExecutionException e) {
146                 throw e;
147             } catch (Exception e) {
148                 throw new MojoExecutionException("could not init goal " + getClass().getSimpleName() + " for reason : "
149                         + e.getMessage(), e);
150             }
151 
152             // check if mojo can be skipped
153 
154             canContinue = checkSkip();
155             if (!canContinue) {
156                 if (isVerbose()) {
157                     getLog().info("Goal will not be executed.");
158                 }
159                 return;
160             }
161 
162             // can really execute the mojo
163 
164             try {
165 
166                 doAction();
167 
168             } catch (MojoFailureException e) {
169                 throw e;
170             } catch (MojoExecutionException e) {
171                 throw e;
172             } catch (Exception e) {
173                 throw new MojoExecutionException("could not execute goal " + getClass().getSimpleName()
174                         + " for reason : " + e.getMessage(), e);
175             }
176         } finally {
177             afterExecute();
178         }
179     }
180 
181     /**
182      * A call back to execute after the {@link #execute()} is done
183      */
184     protected void afterExecute() {
185         // by default do nothing
186     }
187 
188     /**
189      * Check if the project packaging is acceptable for the mojo.
190      * <p/>
191      * By default, accept all packaging types.
192      * <p/>
193      * <b>Note:</b> This method is the first instruction to be executed in the {@link #execute()}.
194      * <p/>
195      * <b>Tip:</b> There is two method to simplify the packaging check :
196      * <p/>
197      * {@link #acceptPackaging(String...)}
198      * <p/>
199      * and
200      * <p/>
201      * {@link #rejectPackaging(String...)}
202      *
203      * @return {@code true} if can execute the goal for the packaging of the project, {@code false} otherwise.
204      */
205     protected boolean checkPackaging() {
206         // by default, accept every type of packaging
207         return true;
208     }
209 
210     /**
211      * Checks if the mojo execution should be skipped.
212      *
213      * @return {@code false} if the mojo should not be executed.
214      */
215     protected boolean checkSkip() {
216         // by default, never skip goal
217         return true;
218     }
219 
220     /**
221      * Accept the project's packaging between some given.
222      *
223      * @param packages
224      *            the accepted packaging
225      * @return {@code true} if the project's packaging is one of the given ones.
226      */
227     protected boolean acceptPackaging(String... packages) {
228         String projectPackaging = getProject().getPackaging();
229 
230         for (String p : packages) {
231             if (p.equals(projectPackaging)) {
232                 // accept packaging
233                 return true;
234             }
235         }
236         // reject packaging
237         return false;
238     }
239 
240     /**
241      * Accept the project's packaging if not in given one.
242      *
243      * @param packages
244      *            the rejecting packagings
245      * @return {@code true} if the project's packaging is not in the given ones.
246      */
247     protected boolean rejectPackaging(String... packages) {
248         String projectPackaging = getProject().getPackaging();
249 
250         for (String p : packages) {
251             if (p.equals(projectPackaging)) {
252                 // reject this packaging
253                 return false;
254             }
255         }
256         // accept packaging
257         return true;
258     }
259 
260     /**
261      * Method to be invoked in init phase to check sanity of {@link #getEncoding()}.
262      * <p/>
263      * If no encoding was filled, then use the default for system (via {@code file.encoding} environement property).
264      */
265     protected void checkEncoding() {
266 
267         if (isVerbose()) {
268             getLog().info("Will check encoding : " + getEncoding());
269         }
270         if (StringUtils.isEmpty(getEncoding())) {
271             getLog().warn(
272                     "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
273                             + ", i.e. build is platform dependent!");
274             setEncoding(ReaderFactory.FILE_ENCODING);
275         }
276     }
277 
278     public final MavenProject getProject() {
279         return project;
280     }
281 
282     public final void setProject(MavenProject project) {
283         this.project = project;
284     }
285 
286     public final boolean isVerbose() {
287         return verbose;
288     }
289 
290     public final void setVerbose(boolean verbose) {
291         this.verbose = verbose;
292     }
293 
294     public final MavenSession getSession() {
295         return session;
296     }
297 
298     public final void setSession(MavenSession session) {
299         this.session = session;
300     }
301 
302     public final long getBuildTimestamp() {
303         return session.getStartTime().getTime();
304     }
305 
306     /**
307      * Add a new resource location to the maven project (in not already present).
308      *
309      * @param dir
310      *            the new resource location to add
311      * @param includes
312      *            files to include
313      */
314     protected void addResourceDir(File dir, String... includes) {
315         boolean added = MojoHelper.addResourceDir(dir, getProject(), includes);
316         if (added && isVerbose()) {
317             getLog().info("add resource " + dir + " with includes " + Arrays.toString(includes));
318         }
319     }
320 
321     /**
322      * @return {@code true} if project is not a pom, {@code false} otherwise.
323      */
324     protected boolean hasClassPath() {
325         return rejectPackaging("pom");
326     }
327 
328 }