View Javadoc

1   package org.codehaus.mojo.exec;
2   
3   import java.io.File;
4   import java.io.FileOutputStream;
5   import java.io.IOException;
6   import java.io.InputStream;
7   import java.io.OutputStream;
8   import java.util.ArrayList;
9   import java.util.List;
10  
11  import org.apache.commons.io.IOUtils;
12  import org.apache.maven.plugin.MojoExecutionException;
13  import org.apache.tools.ant.DirectoryScanner;
14  import org.codehaus.plexus.util.StringUtils;
15  import org.springframework.core.io.DefaultResourceLoader;
16  import org.springframework.core.io.Resource;
17  import org.springframework.core.io.ResourceLoader;
18  
19  /**
20   * A plugin for executing the Eclipse java source code formatter
21   * 
22   * @author Jeff Caddel
23   * @goal format
24   * @aggregator
25   */
26  public class EclipseFormatterMojo extends ExecMojo {
27      private static final String FS = System.getProperty("file.separator");
28  
29      /**
30       * Binaries representing a Java VM. Default values are "javaw.exe", "java.exe", and "java". This list is searched in
31       * order, stopping as soon as one is found.
32       * 
33       * @parameter
34       */
35      private String[] javaBinaries = new String[] { "javaw.exe", "java.exe", "java" };
36  
37      /**
38       * Full path to the Eclipse executable binary
39       * 
40       * @parameter expression="${eclipse.binary}"
41       * @required
42       */
43      private String eclipseBinary;
44  
45      /**
46       * Full path to a Java VM. This gets filled in using the system property "java.home" unless a value is supplied
47       * here.
48       * 
49       * @parameter expression="${eclipse.vm}"
50       */
51      private String vm;
52  
53      /**
54       * This is the name of the Eclipse application that performs the formatting
55       * 
56       * @parameter expression="${eclipse.application}" default-value="org.eclipse.jdt.core.JavaCodeFormatter"
57       * @required
58       */
59      private String application;
60  
61      /**
62       * Pointer to an Eclipse "org.eclipse.jdt.core.prefs" file. Supports "classpath:" style notation
63       * 
64       * @parameter expression="${eclipse.formatterPreferences}" default-value="classpath:eclipse.prefs"
65       * @required
66       */
67      private String formatterPreferences;
68  
69      /**
70       * Any arguments specified here are passed to the Eclipse binary as additional command line arguments. Default
71       * values are "-nosplash -verbose"
72       * 
73       * @parameter
74       */
75      private String[] eclipseArgs = new String[] { "-nosplash", "-verbose" };
76  
77      /**
78       * Regular expressions for directories that contain Java source code to format. Default values are
79       * **/src/main/java and **/src/test/java. The Eclipse formatter will recursively inspect any
80       * directories matching these patterns for *.java files
81       * 
82       * @parameter
83       */
84      private String[] includes = new String[] { "**/src/main/java", "**/src/test/java" };
85  
86      /**
87       * Regular expressions for directories to exclude from the formatting process.
88       * 
89       * @parameter
90       */
91      private String[] excludes = new String[] { "**/.settings", "**/.svn" };
92  
93      protected List<File> getSourceDirectories() {
94          DirectoryScanner scanner = new DirectoryScanner();
95          scanner.setBasedir(project.getBasedir());
96          scanner.setIncludes(includes);
97          scanner.setExcludes(excludes);
98          scanner.scan();
99          String[] includedDirs = scanner.getIncludedDirectories();
100         List<File> dirs = new ArrayList<File>();
101         for (String includedDir : includedDirs) {
102             File file = new File(project.getBasedir().getAbsolutePath() + FS + includedDir);
103             dirs.add(file);
104         }
105         return dirs;
106     }
107 
108     @Override
109     public void execute() throws MojoExecutionException {
110         File file = new File(eclipseBinary);
111         if (!file.exists()) {
112             throw new MojoExecutionException(eclipseBinary + " does not exist");
113         }
114         getLog().info("Eclipse Location: " + file.getAbsolutePath());
115         getLog().info("Java VM: " + getJavaBinary());
116         getLog().info("Scanning directory: " + project.getBasedir());
117         StringBuilder sb = new StringBuilder();
118         for (String include : includes) {
119             sb.append(include + " ");
120         }
121         getLog().info("Includes: " + sb.toString());
122         sb = new StringBuilder();
123         for (String exclude : excludes) {
124             sb.append(exclude + " ");
125         }
126         getLog().info("Excludes: " + sb.toString());
127         List<File> dirs = getSourceDirectories();
128 
129         if (dirs.size() == 0) {
130             getLog().info("No directories containing source code were located");
131             return;
132         } else {
133             getLog().info("Located " + dirs.size() + " source directories:");
134             for (File dir : dirs) {
135                 getLog().info(dir.getAbsolutePath());
136             }
137         }
138 
139         super.setExecutable(quote(eclipseBinary));
140         super.setArguments(getEclipseArguments(dirs));
141 
142         super.execute();
143     }
144 
145     protected String getJavaBinary() throws MojoExecutionException {
146         if (!StringUtils.isEmpty(vm)) {
147             return vm;
148         }
149         String javaHome = System.getProperty("java.home");
150         String binaryHome = javaHome + FS + "bin";
151         for (String binary : javaBinaries) {
152             File file = new File(binaryHome + FS + binary);
153             if (file.exists()) {
154                 return file.getAbsolutePath();
155             }
156         }
157         throw new MojoExecutionException(
158                 "No Java VM location was supplied, and we could not locate one using the System property 'java.home'");
159     }
160 
161     protected List<String> getEclipseArguments(List<File> dirs) throws MojoExecutionException {
162         List<String> args = new ArrayList<String>();
163         args.add("-application");
164         args.add(quote(application));
165         args.add("-vm");
166         args.add(quote(getJavaBinary()));
167         args.add("-config");
168         args.add(quote(getConfigAbsolutePath()));
169         for (String arg : eclipseArgs) {
170             addIfNotEmpty(args, arg);
171         }
172         for (File dir : dirs) {
173             args.add(quote(dir.getAbsolutePath()));
174         }
175         return args;
176     }
177 
178     protected String quote(String s) {
179         return '"' + s + '"';
180     }
181 
182     protected String getConfigAbsolutePath() throws MojoExecutionException {
183         File file = new File(formatterPreferences);
184         if (file.exists()) {
185             return file.getAbsolutePath();
186         }
187         ResourceLoader loader = new DefaultResourceLoader();
188         Resource resource = loader.getResource(formatterPreferences);
189         if (!resource.exists()) {
190             throw new MojoExecutionException("Unable to locate " + formatterPreferences);
191         }
192         OutputStream out = null;
193         InputStream in = null;
194         try {
195             File temp = File.createTempFile("eclipse.prefs.", null);
196             out = new FileOutputStream(temp);
197             in = resource.getInputStream();
198             IOUtils.copy(in, out);
199             return temp.getAbsolutePath();
200         } catch (IOException e) {
201             throw new MojoExecutionException("Error copying resource " + formatterPreferences, e);
202         } finally {
203             IOUtils.closeQuietly(out);
204             IOUtils.closeQuietly(in);
205         }
206 
207     }
208 
209     protected void addIfNotEmpty(List<String> list, String s) {
210         if (StringUtils.isEmpty(s)) {
211             return;
212         }
213         list.add(s);
214     }
215 
216     public String getEclipseBinary() {
217         return eclipseBinary;
218     }
219 
220     public void setEclipseBinary(String eclipseExecutable) {
221         this.eclipseBinary = eclipseExecutable;
222     }
223 
224     public String getVm() {
225         return vm;
226     }
227 
228     public void setVm(String vm) {
229         this.vm = vm;
230     }
231 
232     public String getApplication() {
233         return application;
234     }
235 
236     public void setApplication(String application) {
237         this.application = application;
238     }
239 
240     public String[] getIncludes() {
241         return includes;
242     }
243 
244     public void setIncludes(String[] includes) {
245         this.includes = includes;
246     }
247 
248     public String[] getExcludes() {
249         return excludes;
250     }
251 
252     public void setExcludes(String[] excludes) {
253         this.excludes = excludes;
254     }
255 
256     public String[] getJavaBinaries() {
257         return javaBinaries;
258     }
259 
260     public void setJavaBinaries(String[] binaries) {
261         this.javaBinaries = binaries;
262     }
263 
264     public String getFormatterPreferences() {
265         return formatterPreferences;
266     }
267 
268     public void setFormatterPreferences(String formatterPreferences) {
269         this.formatterPreferences = formatterPreferences;
270     }
271 
272     public String[] getEclipseArgs() {
273         return eclipseArgs;
274     }
275 
276     public void setEclipseArgs(String[] args) {
277         this.eclipseArgs = args;
278     }
279 
280 }