001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 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     */
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.utils.WildcardPattern;
025    
026    import java.util.List;
027    
028    /**
029     * This class is an implementation of a resource of type FILE
030     * 
031     * @since 1.10
032     */
033    public 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      public Directory getParent() {
100        if (parent == null) {
101          parent = new Directory(directoryKey);
102        }
103        return parent;
104      }
105    
106      private static String parseKey(String key) {
107        if (StringUtils.isBlank(key)) {
108          return null;
109        }
110    
111        key = key.replace('\\', '/');
112        key = StringUtils.trim(key);
113        return key;
114      }
115    
116      /**
117       * {@inheritDoc}
118       * 
119       * @see Resource#matchFilePattern(String)
120       */
121      public boolean matchFilePattern(String antPattern) {
122        WildcardPattern matcher = WildcardPattern.create(antPattern, "/");
123        return matcher.match(getKey());
124      }
125    
126      /**
127       * Creates a File from an io.file and a list of sources directories
128       */
129      public static File fromIOFile(java.io.File file, List<java.io.File> sourceDirs) {
130        String relativePath = DefaultProjectFileSystem.getRelativePath(file, sourceDirs);
131        if (relativePath != null) {
132          return new File(relativePath);
133        }
134        return null;
135      }
136    
137      /**
138       * Creates a File from its name and a project
139       */
140      public static File fromIOFile(java.io.File file, Project project) {
141        return fromIOFile(file, project.getFileSystem().getSourceDirs());
142      }
143    
144      /**
145       * {@inheritDoc}
146       * 
147       * @see Resource#getName()
148       */
149      public String getName() {
150        return filename;
151      }
152    
153      /**
154       * {@inheritDoc}
155       * 
156       * @see Resource#getLongName()
157       */
158      public String getLongName() {
159        return getKey();
160      }
161    
162      /**
163       * {@inheritDoc}
164       * 
165       * @see Resource#getDescription()
166       */
167      public String getDescription() {
168        return null;
169      }
170    
171      /**
172       * {@inheritDoc}
173       * 
174       * @see Resource#getLanguage()
175       */
176      public Language getLanguage() {
177        return language;
178      }
179    
180      /**
181       * Sets the language of the file
182       */
183      public void setLanguage(Language language) {
184        this.language = language;
185      }
186    
187      /**
188       * @return SCOPE_ENTITY
189       */
190      public final String getScope() {
191        return SCOPE;
192      }
193    
194      /**
195       * Returns the qualifier associated to this File. Should be QUALIFIER_FILE or
196       * 
197       * @return QUALIFIER_UNIT_TEST_CLASS
198       */
199      public String getQualifier() {
200        return qualifier;
201      }
202    
203      public void setQualifier(String qualifier) {
204        this.qualifier = qualifier;
205      }
206    
207      @Override
208      public String toString() {
209        return new ToStringBuilder(this)
210            .append("key", getKey())
211            .append("dir", directoryKey)
212            .append("filename", filename)
213            .append("language", language)
214            .toString();
215      }
216    }