View Javadoc
1   package net_alchim31_maven_yuicompressor;
2   
3   import java.io.File;
4   import java.util.List;
5   
6   import org.apache.maven.model.Resource;
7   import org.apache.maven.plugin.AbstractMojo;
8   import org.apache.maven.plugin.MojoExecutionException;
9   import org.apache.maven.plugin.MojoFailureException;
10  import org.apache.maven.project.MavenProject;
11  import org.codehaus.plexus.util.DirectoryScanner;
12  import org.codehaus.plexus.util.Scanner;
13  import org.sonatype.plexus.build.incremental.BuildContext;
14  
15  /**
16   * Common class for mojos.
17   *
18   * @author David Bernard
19   * @created 2007-08-29
20   */
21  // @SuppressWarnings("unchecked")
22  public abstract class MojoSupport extends AbstractMojo {
23      private static final String[] EMPTY_STRING_ARRAY = {};
24  
25      /**
26       * Javascript source directory. (result will be put to outputDirectory).
27       * This allow project with "src/main/js" structure.
28       *
29       * @parameter expression="${project.build.sourceDirectory}/../js"
30       */
31      private File sourceDirectory;
32  
33      /**
34       * Single directory for extra files to include in the WAR.
35       *
36       * @parameter expression="${basedir}/src/main/webapp"
37       */
38      private File warSourceDirectory;
39  
40      /**
41       * The directory where the webapp is built.
42       *
43       * @parameter expression="${project.build.directory}/${project.build.finalName}"
44       */
45      private File webappDirectory;
46  
47      /**
48       * The output directory into which to copy the resources.
49       *
50       * @parameter property="project.build.outputDirectory"
51       */
52      private File outputDirectory;
53  
54      /**
55       * The list of resources we want to transfer.
56       *
57       * @parameter property="project.resources"
58       */
59      private List<Resource> resources;
60  
61      /**
62       * list of additional excludes
63       *
64       * @parameter
65       */
66      private List<String> excludes;
67  
68      /**
69       * Use processed resources if available
70       *
71       * @parameter default-value="false"
72       */
73      private boolean useProcessedResources;
74  
75      /**
76       * list of additional includes
77       *
78       * @parameter
79       */
80      private List<String> includes;
81  
82      /**
83       * Excludes files from webapp directory
84       *
85       * @parameter
86       */
87      private boolean excludeWarSourceDirectory = false;
88  
89      /**
90       * Excludes files from resources directories.
91       *
92       * @parameter default-value="false"
93       */
94      private boolean excludeResources = false;
95  
96      /**
97       * @parameter property="project"
98       * @readonly
99       * @required
100      */
101     protected MavenProject project;
102 
103     /**
104      * [js only] Display possible errors in the code
105      *
106      * @parameter property="maven.yuicompressor.jswarn" default-value="true"
107      */
108     protected boolean jswarn;
109 
110     /**
111      * Whether to skip execution.
112      *
113      * @parameter property="maven.yuicompressor.skip" default-value="false"
114      */
115     private boolean skip;
116 
117     /**
118      * define if plugin must stop/fail on warnings.
119      *
120      * @parameter property="maven.yuicompressor.failOnWarning" default-value="false"
121      */
122     protected boolean failOnWarning;
123 
124     /** @component */
125    	protected BuildContext buildContext;
126 
127     protected ErrorReporter4Mojo jsErrorReporter_;
128 
129     public void execute() throws MojoExecutionException, MojoFailureException {
130         try {
131             if (skip) {
132                 getLog().debug("run of yuicompressor-maven-plugin skipped");
133                 return;
134             }
135             if (failOnWarning) {
136                 jswarn = true;
137             }
138             jsErrorReporter_ = new ErrorReporter4Mojo(getLog(), jswarn, buildContext);
139             beforeProcess();
140             processDir(sourceDirectory, outputDirectory, null, useProcessedResources);
141             if (!excludeResources) {
142               for (Resource resource : resources){
143                   File destRoot = outputDirectory;
144                   if (resource.getTargetPath() != null) {
145                       destRoot = new File(outputDirectory, resource.getTargetPath());
146                   }
147                   processDir(new File( resource.getDirectory() ), destRoot, resource.getExcludes(), useProcessedResources);
148               }
149             }
150             if (!excludeWarSourceDirectory) {
151             	processDir(warSourceDirectory, webappDirectory, null, useProcessedResources);
152             }
153             afterProcess();
154             getLog().info(String.format("nb warnings: %d, nb errors: %d", jsErrorReporter_.getWarningCnt(), jsErrorReporter_.getErrorCnt()));
155             if (failOnWarning && (jsErrorReporter_.getWarningCnt() > 0)) {
156                 throw new MojoFailureException("warnings on "+ this.getClass().getSimpleName() + "=> failure ! (see log)");
157             }
158         } catch (RuntimeException exc) {
159             throw exc;
160         } catch (MojoFailureException exc) {
161             throw exc;
162         } catch (MojoExecutionException exc) {
163             throw exc;
164         } catch (Exception exc) {
165             throw new MojoExecutionException("wrap: " + exc.getMessage(), exc);
166         }
167     }
168 
169     protected abstract String[] getDefaultIncludes() throws Exception;
170     protected abstract void beforeProcess() throws Exception;
171     protected abstract void afterProcess() throws Exception;
172 
173     /**
174      * Force to use defaultIncludes (ignore srcIncludes) to avoid processing resources/includes from other type than *.css or *.js
175      * @see https://github.com/davidB/yuicompressor-maven-plugin/issues/19
176      */
177     protected void processDir(File srcRoot, File destRoot, List<String> srcExcludes, boolean destAsSource) throws Exception {
178         if ((srcRoot == null) || ( !srcRoot.exists() )) {
179             return;
180         }
181         if (destRoot == null) {
182             throw new MojoFailureException("destination directory for " + srcRoot + " is null");
183         }
184         DirectoryScanner scanner = new DirectoryScanner();
185         scanner.setBasedir(srcRoot);
186         Scanner incrementalScanner = buildContext.newScanner(srcRoot);
187 
188         if (includes == null) {
189         	scanner.setIncludes(getDefaultIncludes());
190         	incrementalScanner.setIncludes(getDefaultIncludes());
191         } else {
192         	scanner.setIncludes(includes.toArray(new String[0]));
193         	incrementalScanner.setIncludes(includes.toArray(new String[0]));
194         }
195 
196         if ( (srcExcludes != null) && !srcExcludes.isEmpty() ) {
197             scanner.setExcludes( srcExcludes.toArray( EMPTY_STRING_ARRAY ) );
198         }
199         if ((excludes != null) && !excludes.isEmpty()) {
200             scanner.setExcludes( excludes.toArray( EMPTY_STRING_ARRAY ) );
201         }
202         scanner.addDefaultExcludes();
203         incrementalScanner.addDefaultExcludes();
204         if(buildContext.isIncremental()){
205         	incrementalScanner.scan();
206         	if(incrementalScanner.getIncludedFiles() == null ||incrementalScanner.getIncludedFiles().length ==0 ){
207         		getLog().info("No files have changed, so skipping the processing");
208         		return;
209         	}
210         }
211         scanner.scan();
212         for(String name :scanner.getIncludedFiles() ) {
213             SourceFile src = new SourceFile(srcRoot, destRoot, name, destAsSource);
214             jsErrorReporter_.setDefaultFileName("..." + src.toFile().getAbsolutePath().substring(src.toFile().getAbsolutePath().lastIndexOf('/')+1));
215             jsErrorReporter_.setFile(src.toFile());
216             processFile(src);
217         }
218     }
219 
220     protected abstract void processFile(SourceFile src) throws Exception;
221 }