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   * @since 5.1
086   */
087  @Override
088  Path path();
089
090  /**
091   * Language, for example "java" or "php". Can be null if indexation of all files is enabled and no language claims to support the file.
092   */
093  @CheckForNull
094  String language();
095
096  /**
097   * Does it contain main or test code ?
098   */
099  Type type();
100
101  /**
102   * Status regarding previous analysis
103   */
104  Status status();
105
106  /**
107   * Number of physical lines. This method supports all end-of-line characters. Formula is (number of line break + 1). 
108   * <p>
109   * Returns 1 if the file is empty.
110   * <br> 
111   * Returns 2 for <tt>foo\nbar</tt>. 
112   * <br>
113   * Returns 3 for <tt>foo\nbar\n</tt>.
114   */
115  int lines();
116
117  /**
118   * Check if the file content is empty (ignore potential BOM).
119   * @since 5.2
120   */
121  boolean isEmpty();
122
123  /**
124   * Returns a {@link TextPointer} in the given file.
125   * @param line Line of the pointer. Start at 1.
126   * @param lineOffset Offset in the line. Start at 0.
127   * @throws IllegalArgumentException if line or offset is not valid for the given file.
128   * @since 5.2
129   */
130  TextPointer newPointer(int line, int lineOffset);
131
132  /**
133   * Returns a {@link TextRange} in the given file.
134   * @param start start pointer
135   * @param end end pointer
136   * @throws IllegalArgumentException if start or stop pointers are not valid for the given file.
137   * @since 5.2
138   */
139  TextRange newRange(TextPointer start, TextPointer end);
140
141  /**
142   * Returns a {@link TextRange} in the given file.
143   * <ul>
144   * <li><code>newRange(1, 0, 1, 1)</code> selects the first character at line 1</li>
145   * <li><code>newRange(1, 0, 1, 10)</code> selects the 10 first characters at line 1</li>
146   * </ul>
147   * @throws IllegalArgumentException if start or stop positions are not valid for the given file.
148   * @since 5.2
149   */
150  TextRange newRange(int startLine, int startLineOffset, int endLine, int endLineOffset);
151
152  /**
153   * Returns a {@link TextRange} in the given file that select the full line.
154   * @param line Start at 1.
155   * @throws IllegalArgumentException if line is not valid for the given file.
156   * @since 5.2
157   */
158  TextRange selectLine(int line);
159}