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