001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
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.io.File;
027 import java.util.List;
028
029 /**
030 * A class that represents a Java class. This class can either be a Test class or source class
031 *
032 * @since 1.10
033 */
034 public class JavaFile implements Resource<JavaPackage> {
035
036 private String key;
037 private String filename;
038 private String longName;
039 private String packageKey;
040 private boolean unitTest;
041 private JavaPackage parent = null;
042
043 /**
044 * Creates a JavaFile that is not a class of test based on package and file names
045 */
046 public JavaFile(String packageName, String className) {
047 this(packageName, className, false);
048 }
049
050 /**
051 * Creates a JavaFile that can be of any type based on package and file names
052 *
053 * @param unitTest whether it is a unit test file or a source file
054 */
055 public JavaFile(String packageKey, String className, boolean unitTest) {
056 if (className != null && className.indexOf('$') >= 0) {
057 throw new IllegalArgumentException("Java inner classes are not supported : " + className);
058 }
059 this.filename = className.trim();
060 if (StringUtils.isBlank(packageKey)) {
061 this.packageKey = JavaPackage.DEFAULT_PACKAGE_NAME;
062 this.longName = this.filename;
063 this.key = new StringBuilder().append(this.packageKey).append(".").append(this.filename).toString();
064 } else {
065 this.packageKey = packageKey.trim();
066 this.key = new StringBuilder().append(this.packageKey).append(".").append(this.filename).toString();
067 this.longName = this.key;
068 }
069
070 this.unitTest = unitTest;
071 }
072
073 /**
074 * Creates a source file from its key
075 */
076 public JavaFile(String key) {
077 this(key, false);
078 }
079
080 /**
081 * Creates any JavaFile from its key
082 *
083 * @param unitTest whether it is a unit test file or a source file
084 */
085 public JavaFile(String key, boolean unitTest) {
086 if (key != null && key.indexOf('$') >= 0) {
087 throw new IllegalArgumentException("Java inner classes are not supported : " + key);
088 }
089 this.key = key.trim();
090 this.unitTest = unitTest;
091
092 if (this.key.contains(".")) {
093 this.filename = StringUtils.substringAfterLast(this.key, ".");
094 this.packageKey = StringUtils.substringBeforeLast(this.key, ".");
095 this.longName = this.key;
096
097 } else {
098 this.filename = this.key;
099 this.longName = this.key;
100 this.packageKey = JavaPackage.DEFAULT_PACKAGE_NAME;
101 this.key = new StringBuilder().append(JavaPackage.DEFAULT_PACKAGE_NAME).append(".").append(this.key).toString();
102 }
103 }
104
105 /**
106 * {@inheritDoc}
107 */
108 public JavaPackage getParent() {
109 if (parent == null) {
110 parent = new JavaPackage(packageKey);
111 }
112 return parent;
113 }
114
115 /**
116 * {@inheritDoc}
117 */
118 public String getKey() {
119 return key;
120 }
121
122 /**
123 * @return null
124 */
125 public String getDescription() {
126 return null;
127 }
128
129 /**
130 * @return Java
131 */
132 public Language getLanguage() {
133 return Java.INSTANCE;
134 }
135
136 /**
137 * {@inheritDoc}
138 */
139 public String getName() {
140 return filename;
141 }
142
143 /**
144 * {@inheritDoc}
145 */
146 public String getLongName() {
147 return longName;
148 }
149
150 /**
151 * @return SCOPE_ENTITY
152 */
153 public String getScope() {
154 return Resource.SCOPE_ENTITY;
155 }
156
157 /**
158 * @return QUALIFIER_UNIT_TEST_CLASS or QUALIFIER_CLASS depending whether it is a unit test class
159 */
160 public String getQualifier() {
161 return unitTest ? Resource.QUALIFIER_UNIT_TEST_CLASS : Resource.QUALIFIER_CLASS;
162 }
163
164 /**
165 * @return whether the JavaFile is a unit test class or not
166 */
167 public boolean isUnitTest() {
168 return unitTest;
169 }
170
171 /**
172 * {@inheritDoc}
173 */
174 public boolean matchFilePattern(String antPattern) {
175 String patternWithoutFileSuffix = StringUtils.substringBeforeLast(antPattern, ".");
176 WildcardPattern matcher = WildcardPattern.create(patternWithoutFileSuffix, ".");
177 return matcher.match(getKey());
178 }
179
180 /**
181 * Creates a JavaFile from a file in the source directories
182 *
183 * @return the JavaFile created if exists, null otherwise
184 */
185 public static JavaFile fromIOFile(File file, List<File> sourceDirs, boolean unitTest) {
186 if (file == null || !StringUtils.endsWithIgnoreCase(file.getName(), ".java")) {
187 return null;
188 }
189 String relativePath = DefaultProjectFileSystem.getRelativePath(file, sourceDirs);
190 if (relativePath != null) {
191 String pacname = null;
192 String classname = relativePath;
193
194 if (relativePath.indexOf('/') >= 0) {
195 pacname = StringUtils.substringBeforeLast(relativePath, "/");
196 pacname = StringUtils.replace(pacname, "/", ".");
197 classname = StringUtils.substringAfterLast(relativePath, "/");
198 }
199 classname = StringUtils.substringBeforeLast(classname, ".");
200 return new JavaFile(pacname, classname, unitTest);
201 }
202 return null;
203 }
204
205 /**
206 * Shortcut to fromIOFile with an abolute path
207 */
208 public static JavaFile fromAbsolutePath(String path, List<File> sourceDirs, boolean unitTest) {
209 if (path == null) {
210 return null;
211 }
212 return fromIOFile(new File(path), sourceDirs, unitTest);
213 }
214
215 @Override
216 public boolean equals(Object obj) {
217 if (!(obj instanceof JavaFile)) {
218 return false;
219 }
220 if (this == obj) {
221 return true;
222 }
223 JavaFile other = (JavaFile) obj;
224 return StringUtils.equals(key, other.getKey());
225 }
226
227 @Override
228 public int hashCode() {
229 return key.hashCode();
230 }
231
232 @Override
233 public String toString() {
234 return new ToStringBuilder(this)
235 .append("key", key)
236 .append("package", packageKey)
237 .append("longName", longName)
238 .append("unitTest", unitTest)
239 .toString();
240 }
241 }