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