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     */
020    package org.sonar.api.resources;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.apache.commons.lang.builder.ToStringBuilder;
024    import org.sonar.api.scan.filesystem.PathResolver;
025    import org.sonar.api.utils.WildcardPattern;
026    
027    import java.util.List;
028    
029    /**
030     * This class is an implementation of a resource of type FILE
031     *
032     * @since 1.10
033     */
034    public class File extends Resource<Directory> {
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    }