001/*
002 * SonarQube
003 * Copyright (C) 2009-2017 SonarSource SA
004 * mailto:info AT sonarsource DOT com
005 *
006 * This program 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 * This program 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 */
020package org.sonar.api.batch.fs;
021
022import java.io.File;
023import java.io.IOException;
024import java.io.InputStream;
025import java.nio.charset.Charset;
026import java.nio.file.Path;
027import javax.annotation.CheckForNull;
028import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
029import org.sonar.api.batch.sensor.SensorDescriptor;
030
031/**
032 * This layer over {@link java.io.File} adds information for code analyzers.
033 * For unit testing purpose, use {@link TestInputFileBuilder} and initialize
034 * the needed fields:
035 * 
036 * <pre>
037 *   new TestInputFileBuilder("moduleKey", "relative/path/from/module/baseDir.java")
038 *     .setModuleBaseDir(path)
039 *     .build();
040 * </pre>
041 *
042 * @since 4.2
043 */
044public interface InputFile extends IndexedFile {
045
046  enum Type {
047    MAIN, TEST
048  }
049
050  /** 
051   * Status regarding previous analysis
052   */
053  enum Status {
054    SAME, CHANGED, ADDED
055  }
056
057  /**
058   * Relative path to module (for normal Sensors) or project (for {@link SensorDescriptor#global() global} Sensors) base directory.
059   * File separator is the forward
060   * slash ('/'), even on Microsoft Windows.
061   * <br>
062   * Returns <code>src/main/java/com/Foo.java</code> if module base dir is
063   * <code>/path/to/module</code> and if file is
064   * <code>/path/to/module/src/main/java/com/Foo.java</code>.
065   * <br>
066   * Relative path is not null and is normalized ('foo/../foo' is replaced by 'foo').
067   * @deprecated since 6.6 use {@link #inputStream()} for file content, {@link #filename()} for file name, {@link #uri()} for an unique identifier, and {@link #toString()} for logging
068   */
069  @Deprecated
070  @Override
071  String relativePath();
072
073  /**
074   * Normalized absolute path. File separator is forward slash ('/'), even on Microsoft Windows.
075   * <br>
076   * This is not canonical path. Symbolic links are not resolved. For example if /project/src links
077   * to /tmp/src and basedir is /project, then this method returns /project/src/index.php. Use
078   * {@code file().getCanonicalPath()} to resolve symbolic link.
079   * @deprecated since 6.6 use {@link #inputStream()} for file content, {@link #filename()} for file name, {@link #uri()} for an unique identifier, and {@link #toString()} for logging
080   */
081  @Deprecated
082  @Override
083  String absolutePath();
084
085  /**
086   * The underlying absolute {@link java.io.File}. It should not be used to read the file in the filesystem.
087   * @see #contents()
088   * @see #inputStream()
089   * @deprecated since 6.6 use {@link #inputStream()} for file content, {@link #filename()} for file name, {@link #uri()} for an unique identifier, and {@link #toString()} for logging
090   */
091  @Deprecated
092  @Override
093  File file();
094
095  /**
096   * The underlying absolute {@link Path}.
097   * It should not be used to read the file in the filesystem.
098   * @see #contents()
099   * @see #inputStream()
100   * @since 5.1
101   * @deprecated since 6.6 use {@link #inputStream()} for file content, {@link #filename()} for file name, {@link #uri()} for an unique identifier, and {@link #toString()} for logging
102   */
103  @Deprecated
104  @Override
105  Path path();
106
107  /**
108   * Language, for example "java" or "php". Can be null if indexation of all files is enabled and no language claims to support the file.
109   */
110  @CheckForNull
111  @Override
112  String language();
113
114  /**
115   * Does it contain main or test code ?
116   */
117  @Override
118  Type type();
119
120  /**
121   * Creates a stream of the file's contents. Depending on the runtime context, the source might be a file in a physical or virtual filesystem.
122   * Typically, it won't be buffered. <b>The stream must be closed by the caller</b>.
123   * Since 6.4 BOM is automatically filtered out.
124   * @since 6.2
125   */
126  @Override
127  InputStream inputStream() throws IOException;
128
129  /**
130   * Fetches the entire contents of the file, decoding with the {@link #charset}.
131   * Since 6.4 BOM is automatically filtered out.
132   * @since 6.2
133   */
134  String contents() throws IOException;
135
136  /**
137   * Status regarding previous analysis
138   */
139  Status status();
140
141  /**
142   * Number of physical lines. This method supports all end-of-line characters. Formula is (number of line break + 1). 
143   * <p>
144   * Returns 1 if the file is empty.
145   * <br> 
146   * Returns 2 for <tt>foo\nbar</tt>. 
147   * <br>
148   * Returns 3 for <tt>foo\nbar\n</tt>.
149   */
150  int lines();
151
152  /**
153   * Check if the file content is empty (ignore potential BOM).
154   * @since 5.2
155   */
156  boolean isEmpty();
157
158  /**
159   * Returns a {@link TextPointer} in the given file.
160   * @param line Line of the pointer. Start at 1.
161   * @param lineOffset Offset in the line. Start at 0.
162   * @throws IllegalArgumentException if line or offset is not valid for the given file.
163   * @since 5.2
164   */
165  TextPointer newPointer(int line, int lineOffset);
166
167  /**
168   * Returns a {@link TextRange} in the given file.
169   * @param start start pointer
170   * @param end end pointer
171   * @throws IllegalArgumentException if start or stop pointers are not valid for the given file.
172   * @since 5.2
173   */
174  TextRange newRange(TextPointer start, TextPointer end);
175
176  /**
177   * Returns a {@link TextRange} in the given file.
178   * <ul>
179   * <li><code>newRange(1, 0, 1, 1)</code> selects the first character at line 1</li>
180   * <li><code>newRange(1, 0, 1, 10)</code> selects the 10 first characters at line 1</li>
181   * </ul>
182   * @throws IllegalArgumentException if start or stop positions are not valid for the given file.
183   * @since 5.2
184   */
185  TextRange newRange(int startLine, int startLineOffset, int endLine, int endLineOffset);
186
187  /**
188   * Returns a {@link TextRange} in the given file that select the full line.
189   * @param line Start at 1.
190   * @throws IllegalArgumentException if line is not valid for the given file.
191   * @since 5.2
192   */
193  TextRange selectLine(int line);
194
195  /**
196   * Charset to be used to decode this specific file.
197   * @since 6.0
198   */
199  Charset charset();
200
201  /**
202   * Return a string to identify this file (suitable for logs).
203   */
204  @Override
205  String toString();
206}