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     */
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      @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    }