001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube 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 * SonarQube 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.resources;
021
022import org.apache.commons.lang.StringUtils;
023import org.apache.commons.lang.builder.ToStringBuilder;
024import org.sonar.api.batch.SensorContext;
025import org.sonar.api.batch.fs.FileSystem;
026import org.sonar.api.scan.filesystem.PathResolver;
027import org.sonar.api.utils.WildcardPattern;
028
029import javax.annotation.CheckForNull;
030
031import java.util.List;
032
033/**
034 * This class is an implementation of a resource of type FILE
035 *
036 * @since 1.10
037 */
038public class File extends Resource {
039
040  public static final String SCOPE = Scopes.FILE;
041
042  private String filename;
043  private Language language;
044  private Directory parent;
045  private String qualifier = Qualifiers.FILE;
046
047  private final String relativePathFromSourceDir;
048
049  private File() {
050    // Used by factory method
051    this.relativePathFromSourceDir = null;
052  }
053
054  /**
055   * @deprecated since 4.2 use {@link FileSystem#inputFile(org.sonar.api.batch.fs.FilePredicate)}
056   */
057  @Deprecated
058  public File(String relativePathFromSourceDir) {
059    if (relativePathFromSourceDir == null) {
060      throw new IllegalArgumentException("File key is null");
061    }
062    this.relativePathFromSourceDir = parseKey(relativePathFromSourceDir);
063  }
064
065  /**
066   * @deprecated since 4.2 use {@link FileSystem#inputFile(org.sonar.api.batch.fs.FilePredicate)}
067   */
068  @Deprecated
069  public File(String relativeDirectoryPathFromSourceDir, String filename) {
070    this.filename = StringUtils.trim(filename);
071    if (StringUtils.isBlank(relativeDirectoryPathFromSourceDir)) {
072      this.relativePathFromSourceDir = filename;
073    } else {
074      this.relativePathFromSourceDir = new StringBuilder().append(Directory.parseKey(relativeDirectoryPathFromSourceDir)).append(Directory.SEPARATOR).append(this.filename)
075        .toString();
076    }
077  }
078
079  /**
080   * @deprecated since 4.2 use {@link FileSystem#inputFile(org.sonar.api.batch.fs.FilePredicate)}
081   */
082  @Deprecated
083  public File(Language language, String relativePathFromSourceDir) {
084    this(relativePathFromSourceDir);
085    this.language = language;
086  }
087
088  /**
089   * Creates a File from language, directory and filename
090   * @deprecated since 4.2 use {@link #fromIOFile(java.io.File, Project)}
091   */
092  @Deprecated
093  public File(Language language, String relativeDirectoryPathFromSourceDir, String filename) {
094    this(relativeDirectoryPathFromSourceDir, filename);
095    this.language = language;
096  }
097
098  /**
099   * Internal.
100   */
101  public String relativePathFromSourceDir() {
102    return relativePathFromSourceDir;
103  }
104
105  /**
106   * {@inheritDoc}
107   *
108   * @see Resource#getParent()
109   */
110  @Override
111  public Directory getParent() {
112    return parent;
113  }
114
115  private static String parseKey(String key) {
116    if (StringUtils.isBlank(key)) {
117      return null;
118    }
119    String normalizedKey = key;
120    normalizedKey = normalizedKey.replace('\\', '/');
121    normalizedKey = StringUtils.trim(normalizedKey);
122    return normalizedKey;
123  }
124
125  /**
126   * {@inheritDoc}
127   *
128   * @see Resource#matchFilePattern(String)
129   */
130  @Override
131  public boolean matchFilePattern(String antPattern) {
132    WildcardPattern matcher = WildcardPattern.create(antPattern, Directory.SEPARATOR);
133    return matcher.match(getKey());
134  }
135
136  /**
137  * Creates a File from an io.file and a list of sources directories
138  * @deprecated since 4.2 use {@link #fromIOFile(java.io.File, Project)}
139  */
140  @Deprecated
141  @CheckForNull
142  public static File fromIOFile(java.io.File file, List<java.io.File> sourceDirs) {
143    PathResolver.RelativePath relativePath = new PathResolver().relativePath(sourceDirs, file);
144    if (relativePath != null) {
145      return new File(relativePath.path());
146    }
147    return null;
148  }
149
150  /**
151   * Creates a {@link File} from an absolute {@link java.io.File} and a module.
152   * The returned {@link File} can be then passed for example to
153   * {@link SensorContext#saveMeasure(Resource, org.sonar.api.measures.Measure)}.
154   * @param file absolute path to a file
155   * @param module
156   * @return null if the file is not under module basedir.
157   * @deprecated since 4.5 use {@link FileSystem#inputFile(org.sonar.api.batch.fs.FilePredicate)}
158   */
159  @Deprecated
160  @CheckForNull
161  public static File fromIOFile(java.io.File file, Project module) {
162    String relativePathFromBasedir = new PathResolver().relativePath(module.getBaseDir(), file);
163    if (relativePathFromBasedir != null) {
164      return File.create(relativePathFromBasedir);
165    }
166    return null;
167  }
168
169  /**
170   * {@inheritDoc}
171   *
172   * @see Resource#getName()
173   */
174  @Override
175  public String getName() {
176    return filename;
177  }
178
179  /**
180   * {@inheritDoc}
181   *
182   * @see Resource#getLongName()
183   */
184  @Override
185  public String getLongName() {
186    return StringUtils.defaultIfBlank(getPath(), getKey());
187  }
188
189  /**
190   * {@inheritDoc}
191   *
192   * @see Resource#getDescription()
193   */
194  @Override
195  public String getDescription() {
196    return null;
197  }
198
199  /**
200   * {@inheritDoc}
201   *
202   * @see Resource#getLanguage()
203   */
204  @Override
205  public Language getLanguage() {
206    return language;
207  }
208
209  /**
210   * Sets the language of the file
211   */
212  public void setLanguage(Language language) {
213    this.language = language;
214  }
215
216  /**
217   * @return SCOPE_ENTITY
218   */
219  @Override
220  public final String getScope() {
221    return SCOPE;
222  }
223
224  /**
225   * Returns the qualifier associated to this File. Should be QUALIFIER_FILE or QUALIFIER_UNIT_TEST_CLASS
226   */
227  @Override
228  public String getQualifier() {
229    return qualifier;
230  }
231
232  public void setQualifier(String qualifier) {
233    this.qualifier = qualifier;
234  }
235
236  /**
237   * Internal use only.
238   * @deprecated since 5.1 use {@link FileSystem#inputFile(org.sonar.api.batch.fs.FilePredicate)}
239   */
240  @Deprecated
241  public static File create(String relativePathFromBasedir) {
242    File file = new File();
243    String normalizedPath = normalize(relativePathFromBasedir);
244    file.setKey(normalizedPath);
245    file.setPath(normalizedPath);
246    String directoryPath;
247    if (normalizedPath != null && normalizedPath.contains(Directory.SEPARATOR)) {
248      directoryPath = StringUtils.substringBeforeLast(normalizedPath, Directory.SEPARATOR);
249      file.filename = StringUtils.substringAfterLast(normalizedPath, Directory.SEPARATOR);
250    } else {
251      directoryPath = Directory.SEPARATOR;
252      file.filename = normalizedPath;
253    }
254    file.parent = Directory.create(directoryPath);
255    return file;
256  }
257
258  /**
259   * Internal use only.
260   * @deprecated since 5.1 use {@link FileSystem#inputFile(org.sonar.api.batch.fs.FilePredicate)}
261   */
262  @Deprecated
263  public static File create(String relativePathFromBasedir, Language language, boolean unitTest) {
264    File file = create(relativePathFromBasedir);
265    file.setLanguage(language);
266    if (unitTest) {
267      file.setQualifier(Qualifiers.UNIT_TEST_FILE);
268    }
269    return file;
270  }
271
272  @Override
273  public String toString() {
274    return new ToStringBuilder(this)
275      .append("key", getKey())
276      .append("path", getPath())
277      .append("filename", filename)
278      .append("language", language)
279      .toString();
280  }
281}