001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2014 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * SonarQube 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     * SonarQube 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 License
017     * along with this program; if not, write to the Free Software Foundation,
018     * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019     */
020    package org.sonar.api.batch.fs;
021    
022    import org.sonar.api.BatchComponent;
023    
024    import javax.annotation.CheckForNull;
025    import java.io.File;
026    import java.nio.charset.Charset;
027    import java.util.SortedSet;
028    
029    /**
030     * The {@link FileSystem} manages all the source files to be analyzed.
031     * <p/>
032     * This is not an extension point so it must not be implemented by plugins. It must be injected as a
033     * constructor parameter :
034     * <pre>
035     * public class MySensor implements Sensor {
036     *   private final FileSystem fs;
037     *
038     *   public MySensor(FileSystem fs) {
039     *     this.fs = fs;
040     *   }
041     * }
042     * </pre>
043     *
044     * <h2>How to use in unit tests</h2>
045     * The unit tests needing an instance of FileSystem can use the implementation
046     * {@link org.sonar.api.batch.fs.internal.DefaultFileSystem} and the related {@link org.sonar.api.batch.fs.internal.DefaultInputFile},
047     * for example :
048     * <pre>
049     * DefaultFileSystem fs = new DefaultFileSystem();
050     * fs.add(new DefaultInputFile("src/foo/bar.php"));
051     * </pre>
052     *
053     * @since 4.2
054     */
055    public interface FileSystem extends BatchComponent {
056    
057      /**
058       * Absolute base directory of module
059       */
060      File baseDir();
061    
062      /**
063       * Default encoding of input files. If it's not defined, then
064       * the platform default encoding is returned
065       */
066      Charset encoding();
067    
068      /**
069       * Absolute work directory. It can be used to
070       * store third-party analysis reports.
071       * <p/>
072       * The work directory can be located outside {@link #baseDir()}.
073       */
074      File workDir();
075    
076      /**
077       * Factory of {@link FilePredicate}
078       */
079      FilePredicates predicates();
080    
081      /**
082       * Returns the single element matching the predicate. If more than one elements match
083       * the predicate, then {@link IllegalArgumentException} is thrown. Returns {@code null}
084       * if no files match.
085       *
086       * <p/>
087       * How to use :
088       * <pre>
089       * InputFile file = fs.inputFile(fs.predicates().hasRelativePath("src/Foo.php"));
090       * </pre>
091       *
092       * @see #predicates()
093       */
094      @CheckForNull
095      InputFile inputFile(FilePredicate predicate);
096    
097      /**
098       * Input files matching the given attributes. Return all the files if the parameter
099       * <code>attributes</code> is empty.
100       * <p/>
101       * <b>Important</b> - result is an {@link java.lang.Iterable} to benefit from streaming and decreasing
102       * memory consumption. It should be iterated only once, else copy it into a list :
103       * {@code com.google.common.collect.Lists.newArrayList(inputFiles(predicate))}
104       * <p/>
105       * How to use :
106       * <pre>
107       * FilePredicates p = fs.predicates();
108       * Iterable<InputFile> files = fs.inputFiles(p.and(p.hasLanguage("java"), p.hasType(InputFile.Type.MAIN)));
109       * </pre>
110       *
111       * @see #predicates()
112       */
113      Iterable<InputFile> inputFiles(FilePredicate predicate);
114    
115      /**
116       * Returns true if at least one {@link org.sonar.api.batch.fs.InputFile} matches
117       * the given predicate. This method can be faster than checking if {@link #inputFiles(org.sonar.api.batch.fs.FilePredicate)}
118       * has elements.
119       * @see #predicates()
120       */
121      boolean hasFiles(FilePredicate predicate);
122    
123      /**
124       * Files matching the given predicate.
125       * @see #predicates()
126       */
127      Iterable<File> files(FilePredicate predicate);
128    
129      /**
130       * Languages detected in all files, whatever their type (main or test)
131       */
132      SortedSet<String> languages();
133    }