001/*
002 * SonarQube
003 * Copyright (C) 2009-2016 SonarSource SA
004 * mailto:contact 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.nio.charset.Charset;
024import java.nio.file.Path;
025import javax.annotation.CheckForNull;
026import org.sonar.api.batch.fs.internal.DefaultInputFile;
027
028/**
029 * This layer over {@link java.io.File} adds information for code analyzers.
030 * For unit testing purpose you can create some {@link DefaultInputFile} and initialize
031 * all fields using 
032 * 
033 * <pre>
034 *   new DefaultInputFile("moduleKey", "relative/path/from/module/baseDir.java")
035 *     .setModuleBaseDir(path)
036 *     .initMetadata(new FileMetadata().readMetadata(someReader));
037 * </pre>
038 *
039 * @since 4.2
040 */
041public interface InputFile extends InputPath {
042
043  enum Type {
044    MAIN, TEST
045  }
046
047  /** 
048   * Status regarding previous analysis
049   */
050  enum Status {
051    SAME, CHANGED, ADDED
052  }
053
054  /**
055   * Path relative to module base directory. Path is unique and identifies file
056   * within given <code>{@link FileSystem}</code>. File separator is the forward
057   * slash ('/'), even on Microsoft Windows.
058   * <br>
059   * Returns <code>src/main/java/com/Foo.java</code> if module base dir is
060   * <code>/path/to/module</code> and if file is
061   * <code>/path/to/module/src/main/java/com/Foo.java</code>.
062   * <br>
063   * Relative path is not null and is normalized ('foo/../foo' is replaced by 'foo').
064   */
065  @Override
066  String relativePath();
067
068  /**
069   * Normalized absolute path. File separator is forward slash ('/'), even on Microsoft Windows.
070   * <br>
071   * This is not canonical path. Symbolic links are not resolved. For example if /project/src links
072   * to /tmp/src and basedir is /project, then this method returns /project/src/index.php. Use
073   * {@code file().getCanonicalPath()} to resolve symbolic link.
074   */
075  @Override
076  String absolutePath();
077
078  /**
079   * The underlying absolute {@link java.io.File}
080   */
081  @Override
082  File file();
083
084  /**
085   * The underlying absolute {@link Path}
086   * @since 5.1
087   */
088  @Override
089  Path path();
090
091  /**
092   * Language, for example "java" or "php". Can be null if indexation of all files is enabled and no language claims to support the file.
093   */
094  @CheckForNull
095  String language();
096
097  /**
098   * Does it contain main or test code ?
099   */
100  Type type();
101
102  /**
103   * Status regarding previous analysis
104   */
105  Status status();
106
107  /**
108   * Number of physical lines. This method supports all end-of-line characters. Formula is (number of line break + 1). 
109   * <p>
110   * Returns 1 if the file is empty.
111   * <br> 
112   * Returns 2 for <tt>foo\nbar</tt>. 
113   * <br>
114   * Returns 3 for <tt>foo\nbar\n</tt>.
115   */
116  int lines();
117
118  /**
119   * Check if the file content is empty (ignore potential BOM).
120   * @since 5.2
121   */
122  boolean isEmpty();
123
124  /**
125   * Returns a {@link TextPointer} in the given file.
126   * @param line Line of the pointer. Start at 1.
127   * @param lineOffset Offset in the line. Start at 0.
128   * @throws IllegalArgumentException if line or offset is not valid for the given file.
129   * @since 5.2
130   */
131  TextPointer newPointer(int line, int lineOffset);
132
133  /**
134   * Returns a {@link TextRange} in the given file.
135   * @param start start pointer
136   * @param end end pointer
137   * @throws IllegalArgumentException if start or stop pointers are not valid for the given file.
138   * @since 5.2
139   */
140  TextRange newRange(TextPointer start, TextPointer end);
141
142  /**
143   * Returns a {@link TextRange} in the given file.
144   * <ul>
145   * <li><code>newRange(1, 0, 1, 1)</code> selects the first character at line 1</li>
146   * <li><code>newRange(1, 0, 1, 10)</code> selects the 10 first characters at line 1</li>
147   * </ul>
148   * @throws IllegalArgumentException if start or stop positions are not valid for the given file.
149   * @since 5.2
150   */
151  TextRange newRange(int startLine, int startLineOffset, int endLine, int endLineOffset);
152
153  /**
154   * Returns a {@link TextRange} in the given file that select the full line.
155   * @param line Start at 1.
156   * @throws IllegalArgumentException if line is not valid for the given file.
157   * @since 5.2
158   */
159  TextRange selectLine(int line);
160
161  /**
162   * Charset to be used to decode this specific file.
163   * @since 6.0
164   */
165  Charset charset();
166}