001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2013 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.scan.filesystem.PathResolver;
025import org.sonar.api.utils.WildcardPattern;
026
027import java.util.List;
028
029/**
030 * This class is an implementation of a resource of type FILE
031 *
032 * @since 1.10
033 */
034public class File extends Resource {
035
036  public static final String SCOPE = Scopes.FILE;
037
038  private String directoryKey;
039  private String filename;
040  private Language language;
041  private Directory parent;
042  private String qualifier = Qualifiers.FILE;
043
044  /**
045   * File in project. Key is the path relative to project source directories. It is not the absolute path and it does not include the path
046   * to source directories. Example : <code>new File("org/sonar/foo.sql")</code>. The absolute path may be
047   * c:/myproject/src/main/sql/org/sonar/foo.sql. Project root is c:/myproject and source dir is src/main/sql.
048   */
049  public File(String key) {
050    if (key == null) {
051      throw new IllegalArgumentException("File key is null");
052    }
053    String realKey = parseKey(key);
054    if (realKey.indexOf(Directory.SEPARATOR) >= 0) {
055      this.directoryKey = Directory.parseKey(StringUtils.substringBeforeLast(key, Directory.SEPARATOR));
056      this.filename = StringUtils.substringAfterLast(realKey, Directory.SEPARATOR);
057      realKey = new StringBuilder().append(this.directoryKey).append(Directory.SEPARATOR).append(filename).toString();
058
059    } else {
060      this.filename = key;
061    }
062    setKey(realKey);
063  }
064
065  /**
066   * Creates a file from its containing directory and name
067   */
068  public File(String directory, String filename) {
069    this.filename = StringUtils.trim(filename);
070    if (StringUtils.isBlank(directory)) {
071      setKey(filename);
072
073    } else {
074      this.directoryKey = Directory.parseKey(directory);
075      setKey(new StringBuilder().append(directoryKey).append(Directory.SEPARATOR).append(this.filename).toString());
076    }
077  }
078
079  /**
080   * Creates a File from its language and its key
081   */
082  public File(Language language, String key) {
083    this(key);
084    this.language = language;
085  }
086
087  /**
088   * Creates a File from language, directory and filename
089   */
090  public File(Language language, String directory, String filename) {
091    this(directory, filename);
092    this.language = language;
093  }
094
095  /**
096   * {@inheritDoc}
097   *
098   * @see Resource#getParent()
099   */
100  @Override
101  public Directory getParent() {
102    if (parent == null) {
103      parent = new Directory(directoryKey);
104    }
105    return parent;
106  }
107
108  private static String parseKey(String key) {
109    if (StringUtils.isBlank(key)) {
110      return null;
111    }
112
113    key = key.replace('\\', '/');
114    key = StringUtils.trim(key);
115    return key;
116  }
117
118  /**
119   * {@inheritDoc}
120   *
121   * @see Resource#matchFilePattern(String)
122   */
123  @Override
124  public boolean matchFilePattern(String antPattern) {
125    WildcardPattern matcher = WildcardPattern.create(antPattern, "/");
126    return matcher.match(getKey());
127  }
128
129  /**
130   * Creates a File from an io.file and a list of sources directories
131   */
132  public static File fromIOFile(java.io.File file, List<java.io.File> sourceDirs) {
133    PathResolver.RelativePath relativePath = new PathResolver().relativePath(sourceDirs, file);
134    if (relativePath != null) {
135      return new File(relativePath.path());
136    }
137    return null;
138  }
139
140  /**
141   * Creates a File from its name and a project
142   */
143  public static File fromIOFile(java.io.File file, Project project) {
144    return fromIOFile(file, project.getFileSystem().getSourceDirs());
145  }
146
147  /**
148   * {@inheritDoc}
149   *
150   * @see Resource#getName()
151   */
152  @Override
153  public String getName() {
154    return filename;
155  }
156
157  /**
158   * {@inheritDoc}
159   *
160   * @see Resource#getLongName()
161   */
162  @Override
163  public String getLongName() {
164    return getKey();
165  }
166
167  /**
168   * {@inheritDoc}
169   *
170   * @see Resource#getDescription()
171   */
172  @Override
173  public String getDescription() {
174    return null;
175  }
176
177  /**
178   * {@inheritDoc}
179   *
180   * @see Resource#getLanguage()
181   */
182  @Override
183  public Language getLanguage() {
184    return language;
185  }
186
187  /**
188   * Sets the language of the file
189   */
190  public void setLanguage(Language language) {
191    this.language = language;
192  }
193
194  /**
195   * @return SCOPE_ENTITY
196   */
197  @Override
198  public final String getScope() {
199    return SCOPE;
200  }
201
202  /**
203   * Returns the qualifier associated to this File. Should be QUALIFIER_FILE or
204   *
205   * @return QUALIFIER_UNIT_TEST_CLASS
206   */
207  @Override
208  public String getQualifier() {
209    return qualifier;
210  }
211
212  public void setQualifier(String qualifier) {
213    this.qualifier = qualifier;
214  }
215
216  @Override
217  public String toString() {
218    return new ToStringBuilder(this)
219      .append("key", getKey())
220      .append("dir", directoryKey)
221      .append("filename", filename)
222      .append("language", language)
223      .toString();
224  }
225}