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.configuration.Configuration;
023 import org.apache.commons.configuration.MapConfiguration;
024 import org.apache.commons.lang.StringUtils;
025 import org.apache.commons.lang.time.DateUtils;
026 import org.apache.maven.project.MavenProject;
027 import org.sonar.api.CoreProperties;
028 import org.sonar.api.database.model.Snapshot;
029 import org.sonar.api.utils.SonarException;
030
031 import java.text.DateFormat;
032 import java.text.ParseException;
033 import java.text.SimpleDateFormat;
034 import java.util.ArrayList;
035 import java.util.Date;
036 import java.util.List;
037
038 /**
039 * @since 1.10
040 */
041 public class Project implements Resource {
042
043 /**
044 * @deprecated since version 1.11. Constant moved to CoreProperties
045 */
046 @Deprecated
047 public static final String PARAM_DEPRECATED_BRANCH = "branch";
048
049 /**
050 * @deprecated since version 1.11. Constant moved to CoreProperties
051 */
052 @Deprecated
053 public static final String PARAM_BRANCH = "sonar.branch";
054
055 /**
056 * @deprecated since version 1.11. Constant moved to CoreProperties
057 */
058 @Deprecated
059 public static final String PARAM_VERSION = "sonar.projectVersion";
060
061 /**
062 * @deprecated since version 1.11. Constant moved to CoreProperties
063 */
064 @Deprecated
065 public static final String PARAM_DATE = "sonar.projectDate";
066
067 /**
068 * @deprecated since version 1.11. Constant moved to CoreProperties
069 */
070 @Deprecated
071 public static final String PARAM_LANGUAGE = "sonar.language";
072
073 /**
074 * @deprecated since version 1.11. Constant moved to CoreProperties
075 */
076 @Deprecated
077 public static final String PARAM_DYNAMIC_ANALYSIS = "sonar.dynamicAnalysis";
078
079 /**
080 * @deprecated since version 1.11. Constant moved to CoreProperties
081 */
082 @Deprecated
083 public static final String PARAM_EXCLUSIONS = "sonar.exclusions";
084
085 /**
086 * @deprecated since version 1.11. Constant moved to CoreProperties
087 */
088 @Deprecated
089 public static final String PARAM_REUSE_RULES_CONFIG = "sonar.reuseExistingRulesConfiguration";
090
091 public enum AnalysisType {
092 STATIC, DYNAMIC, REUSE_REPORTS;
093
094 public boolean isDynamic(boolean includeReuseReportMode) {
095 return equals(Project.AnalysisType.DYNAMIC) ||
096 (equals(Project.AnalysisType.REUSE_REPORTS) && includeReuseReportMode);
097 }
098 }
099
100 private final MavenProject mavenProject;
101 private final DefaultProjectFileSystem fileSystem;
102 private Configuration configuration;
103
104 // modules tree
105 private Project root;
106 private Project parent;
107 private List<Project> modules = new ArrayList<Project>();
108
109 // internal use
110 private Snapshot snapshot;
111 private Integer id;
112 private Languages languages;
113
114 public Project(MavenProject mavenProject) {
115 this(mavenProject, new MapConfiguration(mavenProject.getProperties()));
116
117 }
118
119 public Project(MavenProject pom, Configuration configuration) {
120 this.mavenProject = pom;
121 this.fileSystem = new DefaultProjectFileSystem(this);
122 this.configuration = configuration;
123 }
124
125 public Snapshot getSnapshot() {
126 return snapshot;
127 }
128
129
130 public Integer getId() {
131 return id;
132 }
133
134 public Project setDatabaseSettings(Integer projectId, Snapshot snapshot) {
135 this.snapshot = snapshot;
136 this.id = projectId;
137 return this;
138 }
139
140 public Project setLanguages(Languages languages) {
141 this.languages = languages;
142 return this;
143 }
144
145
146 public Project getRoot() {
147 return root;
148 }
149
150 public String getPackaging() {
151 return mavenProject.getPackaging();
152 }
153
154 public boolean isRoot() {
155 return mavenProject.isExecutionRoot();
156 }
157
158 public boolean isModule() {
159 return !isRoot();
160 }
161
162 public AnalysisType getAnalysisType() {
163 String value = getConfiguration().getString(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY);
164 if (value == null) {
165 return (isSonarLightMode() ? AnalysisType.STATIC : AnalysisType.DYNAMIC);
166 }
167 if ("true".equals(value)) {
168 return AnalysisType.DYNAMIC;
169 }
170 if ("reuseReports".equals(value)) {
171 return AnalysisType.REUSE_REPORTS;
172 }
173 return AnalysisType.STATIC;
174 }
175
176 public String getGroupId() {
177 return mavenProject.getGroupId();
178 }
179
180 public String getArtifactId() {
181 return mavenProject.getArtifactId();
182 }
183
184 public String getBranch() {
185 return configuration.getString(CoreProperties.PROJECT_BRANCH_PROPERTY, configuration.getString(PARAM_DEPRECATED_BRANCH));
186 }
187
188 public String getName() {
189 return mavenProject.getName();
190 }
191
192 public String getDescription() {
193 return mavenProject.getDescription();
194 }
195
196 public Language getLanguage() {
197 String key = getLanguageKey();
198 if (languages != null) {
199 return languages.get(key);
200 }
201 if (Java.KEY.equals(key)) {
202 return Java.INSTANCE;
203 }
204 return null;
205 }
206
207 public String getLanguageKey() {
208 String key = configuration.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY);
209 return StringUtils.isBlank(key) ? Java.KEY : key;
210 }
211
212 public String getScope() {
213 return SCOPE_SET;
214 }
215
216 public String getQualifier() {
217 return isRoot() ? QUALIFIER_PROJECT : QUALIFIER_MODULE;
218 }
219
220 public boolean matchFilePattern(String antPattern) {
221 return false;
222 }
223
224 public Project getParent() {
225 return parent;
226 }
227
228 public void setParent(Project parent) {
229 this.parent = parent;
230 if (parent != null) {
231 parent.modules.add(this);
232 if (parent.isRoot()) {
233 this.root = parent;
234 } else {
235 this.root = parent.getRoot();
236 }
237 }
238 }
239
240 public List<Project> getModules() {
241 return modules;
242 }
243
244 public boolean getReuseExistingRulesConfig() {
245 return configuration.getBoolean(CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY, false);
246 }
247
248 public String getAnalysisVersion() {
249 String version = configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY);
250 if (version == null) {
251 version = mavenProject.getVersion();
252 }
253 return version;
254 }
255
256 public Date getAnalysisDate() {
257 String formattedDate = configuration.getString(CoreProperties.PROJECT_DATE_PROPERTY);
258 if (formattedDate == null) {
259 return new Date();
260 }
261
262 DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
263 try {
264 // see SONAR-908 make sure that a time is defined for the date.
265 Date date = DateUtils.setHours(format.parse(formattedDate), 0);
266 return DateUtils.setMinutes(date, 1);
267
268 } catch (ParseException e) {
269 throw new SonarException("The property " + PARAM_DATE + " does not respect the format yyyy-MM-dd (for example 2008-05-23) : " + formattedDate, e);
270 }
271 }
272
273 /**
274 * Project key is "groupId:artifactId[:branch]". Examples : org.struts:struts-core and org.codehaus.sonar:sonar:1.10
275 */
276 public String getKey() {
277 StringBuilder sb = new StringBuilder().append(getGroupId()).append(":").append(getArtifactId());
278 String branch = getBranch();
279 if (branch != null) {
280 sb.append(":").append(branch);
281 }
282 return sb.toString();
283 }
284
285 /**
286 * Patterns of resource exclusion as defined in project settings page.
287 */
288 public String[] getExclusionPatterns() {
289 String[] exclusions = getConfiguration().getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY);
290 if (exclusions == null) {
291 return new String[0];
292 }
293 return exclusions;
294 }
295
296 /**
297 * Set exclusion patterns. Configuration is not saved, so this method must be used ONLY IN UNIT TESTS.
298 */
299 public void setExclusionPatterns(String[] patterns) {
300 getConfiguration().setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, patterns);
301 }
302
303 public ProjectFileSystem getFileSystem() {
304 return fileSystem;
305 }
306
307 public MavenProject getPom() {
308 return mavenProject;
309 }
310
311 @Deprecated
312 public boolean isSonarLightMode() {
313 return configuration.getBoolean("sonar.light", false);
314 }
315
316 public Configuration getConfiguration() {
317 return configuration;
318 }
319
320 public Project setConfiguration(Configuration configuration) {
321 this.configuration = configuration;
322 return this;
323 }
324
325 public Object getProperty(String key) {
326 return configuration.getProperty(key);
327 }
328
329 @Override
330 public boolean equals(Object o) {
331 if (this == o) {
332 return true;
333 }
334 if (o == null || getClass() != o.getClass()) {
335 return false;
336 }
337 return ((Project) o).getKey().equals(getKey());
338 }
339
340 @Override
341 public int hashCode() {
342 return getKey().hashCode();
343 }
344
345 @Override
346 public String toString() {
347 return getKey();
348 }
349 }