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.Files; 027import java.nio.file.Path; 028import javax.annotation.CheckForNull; 029import org.sonar.api.batch.fs.internal.TestInputFileBuilder; 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 * Path relative to module base directory. Path is unique and identifies file 059 * within given <code>{@link FileSystem}</code>. 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 */ 068 @Override 069 String relativePath(); 070 071 /** 072 * Normalized absolute path. File separator is forward slash ('/'), even on Microsoft Windows. 073 * <br> 074 * This is not canonical path. Symbolic links are not resolved. For example if /project/src links 075 * to /tmp/src and basedir is /project, then this method returns /project/src/index.php. Use 076 * {@code file().getCanonicalPath()} to resolve symbolic link. 077 */ 078 @Override 079 String absolutePath(); 080 081 /** 082 * The underlying absolute {@link java.io.File}. It should not be used to read the file in the filesystem. 083 * @see #contents() 084 * @see #inputStream() 085 */ 086 @Override 087 File file(); 088 089 /** 090 * The underlying absolute {@link Path}. 091 * It should not be used to read the file in the filesystem. 092 * @see #contents() 093 * @see #inputStream() 094 * @since 5.1 095 */ 096 @Override 097 Path path(); 098 099 /** 100 * Language, for example "java" or "php". Can be null if indexation of all files is enabled and no language claims to support the file. 101 */ 102 @CheckForNull 103 @Override 104 String language(); 105 106 /** 107 * Does it contain main or test code ? 108 */ 109 @Override 110 Type type(); 111 112 /** 113 * 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. 114 * Typically, it won't be buffered. <b>The stream must be closed by the caller</b>. 115 * Note that there is a default implementation. 116 * @since 6.2 117 */ 118 @Override 119 default InputStream inputStream() throws IOException { 120 return Files.newInputStream(path()); 121 } 122 123 /** 124 * Fetches the entire contents of the file, decoding with the {@link #charset}. 125 * Note that there is a default implementation. 126 * @since 6.2 127 */ 128 default String contents() throws IOException { 129 return new String(Files.readAllBytes(path()), charset()); 130 } 131 132 /** 133 * Status regarding previous analysis 134 */ 135 Status status(); 136 137 /** 138 * Number of physical lines. This method supports all end-of-line characters. Formula is (number of line break + 1). 139 * <p> 140 * Returns 1 if the file is empty. 141 * <br> 142 * Returns 2 for <tt>foo\nbar</tt>. 143 * <br> 144 * Returns 3 for <tt>foo\nbar\n</tt>. 145 */ 146 int lines(); 147 148 /** 149 * Check if the file content is empty (ignore potential BOM). 150 * @since 5.2 151 */ 152 boolean isEmpty(); 153 154 /** 155 * Returns a {@link TextPointer} in the given file. 156 * @param line Line of the pointer. Start at 1. 157 * @param lineOffset Offset in the line. Start at 0. 158 * @throws IllegalArgumentException if line or offset is not valid for the given file. 159 * @since 5.2 160 */ 161 TextPointer newPointer(int line, int lineOffset); 162 163 /** 164 * Returns a {@link TextRange} in the given file. 165 * @param start start pointer 166 * @param end end pointer 167 * @throws IllegalArgumentException if start or stop pointers are not valid for the given file. 168 * @since 5.2 169 */ 170 TextRange newRange(TextPointer start, TextPointer end); 171 172 /** 173 * Returns a {@link TextRange} in the given file. 174 * <ul> 175 * <li><code>newRange(1, 0, 1, 1)</code> selects the first character at line 1</li> 176 * <li><code>newRange(1, 0, 1, 10)</code> selects the 10 first characters at line 1</li> 177 * </ul> 178 * @throws IllegalArgumentException if start or stop positions are not valid for the given file. 179 * @since 5.2 180 */ 181 TextRange newRange(int startLine, int startLineOffset, int endLine, int endLineOffset); 182 183 /** 184 * Returns a {@link TextRange} in the given file that select the full line. 185 * @param line Start at 1. 186 * @throws IllegalArgumentException if line is not valid for the given file. 187 * @since 5.2 188 */ 189 TextRange selectLine(int line); 190 191 /** 192 * Charset to be used to decode this specific file. 193 * @since 6.0 194 */ 195 Charset charset(); 196}