001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 SonarSource
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.plugins.squid;
021    
022    import java.nio.charset.Charset;
023    import java.util.List;
024    
025    import org.apache.commons.configuration.Configuration;
026    import org.apache.commons.io.FileUtils;
027    import org.sonar.api.CoreProperties;
028    import org.sonar.api.batch.DependedUpon;
029    import org.sonar.api.batch.Phase;
030    import org.sonar.api.batch.Sensor;
031    import org.sonar.api.batch.SensorContext;
032    import org.sonar.api.resources.InputFile;
033    import org.sonar.api.resources.Java;
034    import org.sonar.api.resources.JavaFile;
035    import org.sonar.api.resources.Project;
036    import org.sonar.api.resources.ProjectFileSystem;
037    import org.sonar.api.utils.SonarException;
038    import org.sonar.java.api.JavaUtils;
039    
040    @Phase(name = Phase.Name.PRE)
041    @DependedUpon(JavaUtils.BARRIER_BEFORE_SQUID)
042    public final class JavaSourceImporter implements Sensor {
043    
044      private boolean importSources = false;
045    
046      public JavaSourceImporter(Configuration conf) {
047        this.importSources = conf.getBoolean(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY,
048            CoreProperties.CORE_IMPORT_SOURCES_DEFAULT_VALUE);
049      }
050    
051      JavaSourceImporter(boolean importSources) {
052        this.importSources = importSources;
053      }
054    
055      /**
056       * {@inheritDoc}
057       */
058      public boolean shouldExecuteOnProject(Project project) {
059        return Java.KEY.equals(project.getLanguageKey());
060      }
061    
062      /**
063       * {@inheritDoc}
064       */
065      public void analyse(Project project, SensorContext context) {
066        analyse(project.getFileSystem(), context);
067      }
068    
069      void analyse(ProjectFileSystem fileSystem, SensorContext context) {
070        parseDirs(context, fileSystem.mainFiles(Java.KEY), false, fileSystem.getSourceCharset());
071        parseDirs(context, fileSystem.testFiles(Java.KEY), true, fileSystem.getSourceCharset());
072      }
073    
074      void parseDirs(SensorContext context, List<InputFile> inputFiles, boolean unitTest, Charset sourcesEncoding) {
075        for (InputFile inputFile : inputFiles) {
076          JavaFile javaFile = JavaFile.fromRelativePath(inputFile.getRelativePath(), unitTest);
077          importSource(context, javaFile, inputFile, sourcesEncoding);
078        }
079      }
080    
081      void importSource(SensorContext context, JavaFile javaFile, InputFile inputFile, Charset sourcesEncoding) {
082        String source = null;
083        if (importSources) {
084          source = loadSourceFromFile(inputFile, sourcesEncoding);
085        }
086    
087        try {
088          context.index(javaFile);
089          if (source != null) {
090            context.saveSource(javaFile, source);
091          }
092        } catch (SonarException e) {
093          throw new SonarException(e.getMessage() + ", on file: " + inputFile.getFile().getAbsolutePath(), e);
094        }
095      }
096    
097      protected String loadSourceFromFile(InputFile inputFile, Charset sourcesEncoding) {
098        try {
099          return FileUtils.readFileToString(inputFile.getFile(), sourcesEncoding.name());
100        } catch (Exception e) {
101          throw new SonarException("Unable to read and import the source file : '" + inputFile.getFile().getAbsolutePath() + "' with the charset : '"
102            + sourcesEncoding.name() + "'.", e);
103        }
104      }
105    
106      @Override
107      public String toString() {
108        return getClass().getSimpleName();
109      }
110    
111    }