001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2009 SonarSource SA
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.dev;
021    
022    import org.apache.commons.io.FileUtils;
023    import org.apache.commons.io.IOUtils;
024    import org.apache.commons.io.LineIterator;
025    import org.apache.maven.plugin.AbstractMojo;
026    import org.apache.maven.plugin.MojoExecutionException;
027    import org.apache.maven.plugin.MojoFailureException;
028    import org.codehaus.plexus.util.DirectoryScanner;
029    import org.codehaus.plexus.util.StringUtils;
030    
031    import java.io.File;
032    import java.io.IOException;
033    
034    /**
035     * @goal trim
036     */
037    public class TrimMojo extends AbstractMojo {
038    
039      /**
040       * @parameter
041       * @required
042       */
043      private File directory;
044    
045      /**
046       * List of ant-style patterns. If
047       * this is not specified, allfiles in the project source directories are included.
048       *
049       * @parameter
050       */
051      private String[] includes;
052    
053      /**
054       * @parameter
055       */
056      private String[] excludes;
057    
058    
059      /**
060       * Specifies the encoding of the source files.
061       *
062       * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}"
063       */
064      private String sourceEncoding;
065    
066      public void execute() throws MojoExecutionException, MojoFailureException {
067        if (shouldExecute()) {
068          trimDirectory();
069        }
070      }
071    
072      private void trimDirectory() throws MojoExecutionException {
073        File[] files = scanFiles();
074        for (File file : files) {
075          StringBuilder sb = new StringBuilder();
076          try {
077            LineIterator lines = FileUtils.lineIterator(file, sourceEncoding);
078            while (lines.hasNext()) {
079              String line = lines.nextLine();
080              sb.append(StringUtils.trim(line));
081              sb.append(IOUtils.LINE_SEPARATOR);
082            }
083            FileUtils.writeStringToFile(file, sb.toString(), sourceEncoding);
084    
085          } catch (IOException e) {
086            throw new MojoExecutionException("Can not trim the file " + file, e);
087          }
088        }
089        getLog().info("Trimmed files: " + files.length);
090      }
091    
092      private boolean shouldExecute() {
093        return directory != null && directory.exists();
094      }
095    
096      /**
097       * gets a list of all files in the source directory.
098       *
099       * @return the list of all files in the source directory;
100       */
101      private File[] scanFiles() {
102        String[] defaultIncludes = {"**\\*"};
103        DirectoryScanner ds = new DirectoryScanner();
104        if (includes == null) {
105          ds.setIncludes(defaultIncludes);
106        } else {
107          ds.setIncludes(includes);
108        }
109        ds.addDefaultExcludes(); // .svn, ...
110        if (excludes != null) {
111          ds.setExcludes(excludes);
112        }
113        ds.setBasedir(directory);
114        getLog().info("Scanning directory " + directory);
115        ds.scan();
116        int maxFiles = ds.getIncludedFiles().length;
117        File[] result = new File[maxFiles];
118        for (int i = 0; i < maxFiles; i++) {
119          result[i] = new File(directory, ds.getIncludedFiles()[i]);
120        }
121        return result;
122      }
123    
124      public File getDirectory() {
125        return directory;
126      }
127    
128      public void setDirectory(File directory) {
129        this.directory = directory;
130      }
131    
132      public String[] getIncludes() {
133        return includes;
134      }
135    
136      public void setIncludes(String[] includes) {
137        this.includes = includes;
138      }
139    
140      public String[] getExcludes() {
141        return excludes;
142      }
143    
144      public void setExcludes(String[] excludes) {
145        this.excludes = excludes;
146      }
147    
148      public String getSourceEncoding() {
149        return sourceEncoding;
150      }
151    
152      public void setSourceEncoding(String sourceEncoding) {
153        this.sourceEncoding = sourceEncoding;
154      }
155    }