001 package org.codehaus.mojo.exec;
002
003 import java.io.File;
004 import java.io.FileOutputStream;
005 import java.io.IOException;
006 import java.io.InputStream;
007 import java.io.OutputStream;
008 import java.util.ArrayList;
009 import java.util.List;
010
011 import org.apache.commons.io.IOUtils;
012 import org.apache.maven.plugin.MojoExecutionException;
013 import org.apache.tools.ant.DirectoryScanner;
014 import org.codehaus.plexus.util.StringUtils;
015 import org.springframework.core.io.DefaultResourceLoader;
016 import org.springframework.core.io.Resource;
017 import org.springframework.core.io.ResourceLoader;
018
019 /**
020 * A plugin for executing the Eclipse java source code formatter
021 *
022 * @author Jeff Caddel
023 * @goal format
024 * @aggregator
025 */
026 public class EclipseFormatterMojo extends ExecMojo {
027 private static final String FS = System.getProperty("file.separator");
028
029 /**
030 * Binaries representing a Java VM. Default values are "javaw.exe", "java.exe", and "java". This list is searched in
031 * order, stopping as soon as one is found.
032 *
033 * @parameter
034 */
035 private String[] javaBinaries = new String[] { "javaw.exe", "java.exe", "java" };
036
037 /**
038 * Full path to the Eclipse executable binary
039 *
040 * @parameter expression="${eclipse.binary}"
041 * @required
042 */
043 private String eclipseBinary;
044
045 /**
046 * Full path to a Java VM. This gets filled in using the system property "java.home" unless a value is supplied
047 * here.
048 *
049 * @parameter expression="${eclipse.vm}"
050 */
051 private String vm;
052
053 /**
054 * This is the name of the Eclipse application that performs the formatting
055 *
056 * @parameter expression="${eclipse.application}" default-value="org.eclipse.jdt.core.JavaCodeFormatter"
057 * @required
058 */
059 private String application;
060
061 /**
062 * Pointer to an Eclipse "org.eclipse.jdt.core.prefs" file. Supports "classpath:" style notation
063 *
064 * @parameter expression="${eclipse.formatterPreferences}" default-value="classpath:eclipse.prefs"
065 * @required
066 */
067 private String formatterPreferences;
068
069 /**
070 * Any arguments specified here are passed to the Eclipse binary as additional command line arguments. Default
071 * values are "-nosplash -verbose"
072 *
073 * @parameter
074 */
075 private String[] eclipseArgs = new String[] { "-nosplash", "-verbose" };
076
077 /**
078 * Regular expressions for directories that contain Java source code to format. Default values are
079 * **/src/main/java and **/src/test/java. The Eclipse formatter will recursively inspect any
080 * directories matching these patterns for *.java files
081 *
082 * @parameter
083 */
084 private String[] includes = new String[] { "**/src/main/java", "**/src/test/java" };
085
086 /**
087 * Regular expressions for directories to exclude from the formatting process.
088 *
089 * @parameter
090 */
091 private String[] excludes = new String[] { "**/.settings", "**/.svn" };
092
093 protected List<File> getSourceDirectories() {
094 DirectoryScanner scanner = new DirectoryScanner();
095 scanner.setBasedir(project.getBasedir());
096 scanner.setIncludes(includes);
097 scanner.setExcludes(excludes);
098 scanner.scan();
099 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 }