001 /* 002 * #%L 003 * License Maven Plugin 004 * 005 * $Id: AbstractLicenseMojo.java 14409 2011-08-10 15:30:41Z tchemit $ 006 * $HeadURL: http://svn.codehaus.org/mojo/tags/license-maven-plugin-1.0/src/main/java/org/codehaus/mojo/license/AbstractLicenseMojo.java $ 007 * %% 008 * Copyright (C) 2008 - 2011 CodeLutin, Codehaus, Tony Chemit 009 * %% 010 * This program is free software: you can redistribute it and/or modify 011 * it under the terms of the GNU Lesser General Public License as 012 * published by the Free Software Foundation, either version 3 of the 013 * License, or (at your option) any later version. 014 * 015 * This program is distributed in the hope that it will be useful, 016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 018 * GNU General Lesser Public License for more details. 019 * 020 * You should have received a copy of the GNU General Lesser Public 021 * License along with this program. If not, see 022 * <http://www.gnu.org/licenses/lgpl-3.0.html>. 023 * #L% 024 */ 025 026 package org.codehaus.mojo.license; 027 028 import java.io.File; 029 import java.util.Arrays; 030 031 import org.apache.commons.lang.StringUtils; 032 import org.apache.maven.execution.MavenSession; 033 import org.apache.maven.plugin.AbstractMojo; 034 import org.apache.maven.plugin.MojoExecutionException; 035 import org.apache.maven.plugin.MojoFailureException; 036 import org.apache.maven.project.MavenProject; 037 import org.codehaus.plexus.util.ReaderFactory; 038 039 /** 040 * Abstract license mojo. 041 * 042 * @author tchemit <chemit@codelutin.com> 043 * @since 1.0 044 */ 045 public abstract class AbstractLicenseMojo extends AbstractMojo { 046 047 /** 048 * Current maven session. (used to launch certain mojo once by build). 049 * 050 * @parameter expression="${session}" 051 * @required 052 * @readonly 053 * @since 1.0 054 */ 055 private MavenSession session; 056 057 /** 058 * The reacted project. 059 * 060 * @parameter default-value="${project}" 061 * @required 062 * @since 1.0 063 */ 064 private MavenProject project; 065 066 /** 067 * Flag to activate verbose mode. 068 * <p/> 069 * <b>Note:</b> Verbose mode is always on if you starts a debug maven instance (says via {@code -X}). 070 * 071 * @parameter expression="${license.verbose}" default-value="${maven.verbose}" 072 * @since 1.0 073 */ 074 private boolean verbose; 075 076 /** 077 * Encoding used to read and writes files. 078 * <p/> 079 * <b>Note:</b> If nothing is filled here, we will use the system property {@code file.encoding}. 080 * 081 * @parameter expression="${license.encoding}" default-value="${project.build.sourceEncoding}" 082 * @since 1.0 083 */ 084 private String encoding; 085 086 public final String getEncoding() { 087 return encoding; 088 } 089 090 public final void setEncoding(String encoding) { 091 this.encoding = encoding; 092 } 093 094 /** 095 * Method to initialize the mojo before doing any concrete actions. 096 * <p/> 097 * <b>Note:</b> The method is invoked before the {@link #doAction()} method. 098 * 099 * @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 }