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.configuration.Configuration;
023 import org.apache.commons.lang.StringUtils;
024 import org.apache.commons.lang.builder.ToStringBuilder;
025 import org.apache.maven.project.MavenProject;
026 import org.sonar.api.CoreProperties;
027
028 import java.util.ArrayList;
029 import java.util.Date;
030 import java.util.List;
031
032 /**
033 * A class that manipulates Projects in the Sonar way.
034 *
035 * @since 1.10
036 */
037 public class Project extends Resource {
038
039 public static final String SCOPE = Scopes.PROJECT;
040
041 /**
042 * @deprecated since version 1.11. Constant moved to CoreProperties
043 */
044 @Deprecated
045 public static final String PARAM_VERSION = CoreProperties.PROJECT_VERSION_PROPERTY;
046
047 /**
048 * @deprecated since version 1.11. Constant moved to CoreProperties
049 */
050 @Deprecated
051 public static final String PARAM_DATE = CoreProperties.PROJECT_DATE_PROPERTY;
052
053 /**
054 * @deprecated since version 1.11. Constant moved to CoreProperties
055 */
056 @Deprecated
057 public static final String PARAM_LANGUAGE = CoreProperties.PROJECT_LANGUAGE_PROPERTY;
058
059 /**
060 * @deprecated since version 1.11. Constant moved to CoreProperties
061 */
062 @Deprecated
063 public static final String PARAM_DYNAMIC_ANALYSIS = CoreProperties.DYNAMIC_ANALYSIS_PROPERTY;
064
065 /**
066 * @deprecated since version 1.11. Constant moved to CoreProperties
067 */
068 @Deprecated
069 public static final String PARAM_EXCLUSIONS = CoreProperties.PROJECT_EXCLUSIONS_PROPERTY;
070
071 /**
072 * @deprecated since version 1.11. Constant moved to CoreProperties
073 */
074 @Deprecated
075 public static final String PARAM_REUSE_RULES_CONFIG = CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY;
076
077 /**
078 * Enumerates the type of possible analysis
079 */
080 public enum AnalysisType {
081 STATIC, DYNAMIC, REUSE_REPORTS;
082
083 /**
084 * @param includeReuseReportMode whether to count report reuse as dynamic or not
085 * @return whether this a dynamic analysis
086 */
087 public boolean isDynamic(boolean includeReuseReportMode) {
088 return equals(Project.AnalysisType.DYNAMIC) ||
089 (equals(Project.AnalysisType.REUSE_REPORTS) && includeReuseReportMode);
090 }
091 }
092
093 private MavenProject pom;
094 private String branch;
095 private ProjectFileSystem fileSystem;
096 private Configuration configuration;
097 private String name;
098 private String description;
099 private String packaging;
100 private Language language;
101 private String languageKey;
102 private Date analysisDate;
103 private AnalysisType analysisType;
104 private String analysisVersion;
105 private boolean latestAnalysis;
106
107 // modules tree
108 private Project parent;
109 private List<Project> modules = new ArrayList<Project>();
110
111 public Project(String key) {
112 setKey(key);
113 setEffectiveKey(key);
114 }
115
116 public Project(String key, String branch, String name) {
117 if (StringUtils.isNotBlank(branch)) {
118 setKey(String.format("%s:%s", key, branch));
119 this.name = String.format("%s %s", name, branch);
120 } else {
121 setKey(key);
122 this.name = name;
123 }
124 setEffectiveKey(getKey());
125 this.branch = branch;
126 }
127
128 public String getBranch() {
129 return branch;
130 }
131
132 /**
133 * For internal use only.
134 */
135 public Project setBranch(String branch) {
136 this.branch = branch;
137 return this;
138 }
139
140 /**
141 * For internal use only.
142 */
143 public final Project setPom(MavenProject pom) {
144 this.pom = pom;
145 return this;
146 }
147
148 /**
149 * @return the project's packaging
150 * @deprecated in 2.8. See http://jira.codehaus.org/browse/SONAR-2341
151 */
152 @Deprecated
153 public String getPackaging() {
154 return packaging;
155 }
156
157 public String getName() {
158 return name;
159 }
160
161 public String getLongName() {
162 return name;
163 }
164
165 public String getDescription() {
166 return description;
167 }
168
169 /**
170 * For internal use only.
171 */
172 public Project setName(String name) {
173 this.name = name;
174 return this;
175 }
176
177 /**
178 * For internal use only.
179 */
180 public Project setDescription(String description) {
181 this.description = description;
182 return this;
183 }
184
185 /**
186 * For internal use only.
187 *
188 * @deprecated in 2.8. See http://jira.codehaus.org/browse/SONAR-2341
189 */
190 @Deprecated
191 public Project setPackaging(String packaging) {
192 this.packaging = packaging;
193 return this;
194 }
195
196 /**
197 * @return whether the current project is root project
198 */
199 public boolean isRoot() {
200 return getParent() == null;
201 }
202
203 public Project getRoot() {
204 return (parent == null ? this : parent.getRoot());
205 }
206
207 /**
208 * @return whether the current project is a module
209 */
210 public boolean isModule() {
211 return !isRoot();
212 }
213
214 /**
215 * @return the type of analysis of the project
216 */
217 public AnalysisType getAnalysisType() {
218 return analysisType;
219 }
220
221 public Project setAnalysisType(AnalysisType at) {
222 this.analysisType = at;
223 return this;
224 }
225
226 /**
227 * whether it's the latest analysis done on this project (displayed in sonar dashboard) or an analysis on a past revision.
228 *
229 * @since 2.0
230 */
231 public boolean isLatestAnalysis() {
232 return latestAnalysis;
233 }
234
235 /**
236 * For internal use only.
237 */
238 public Project setLatestAnalysis(boolean b) {
239 this.latestAnalysis = b;
240 return this;
241 }
242
243 /**
244 * @return the project language
245 */
246 public Language getLanguage() {
247 return language;
248 }
249
250 public Project setLanguage(Language language) {
251 this.language = language;
252 return this;
253 }
254
255 /**
256 * @return the language key
257 */
258 public String getLanguageKey() {
259 return languageKey;
260 }
261
262 /**
263 * For internal use only.
264 */
265 public Project setLanguageKey(String languageKey) {
266 this.languageKey = languageKey;
267 return this;
268 }
269
270 /**
271 * For internal use only.
272 */
273 public Project setAnalysisDate(Date analysisDate) {
274 this.analysisDate = analysisDate;
275 return this;
276 }
277
278 /**
279 * For internal use only.
280 */
281 public Project setAnalysisVersion(String analysisVersion) {
282 this.analysisVersion = analysisVersion;
283 return this;
284 }
285
286 /**
287 * @return the scope of the current object
288 */
289 public String getScope() {
290 return Scopes.PROJECT;
291 }
292
293 /**
294 * @return the qualifier of the current object
295 */
296 public String getQualifier() {
297 return isRoot() ? Qualifiers.PROJECT : Qualifiers.MODULE;
298 }
299
300 @Override
301 public boolean matchFilePattern(String antPattern) {
302 return false;
303 }
304
305 public Project getParent() {
306 return parent;
307 }
308
309
310
311 /**
312 * For internal use only.
313 */
314 public Project setParent(Project parent) {
315 this.parent = parent;
316 if (parent != null) {
317 parent.modules.add(this);
318 }
319 return this;
320 }
321
322 /**
323 * For internal use only.
324 */
325 public void removeFromParent() {
326 if (parent != null) {
327 parent.modules.remove(this);
328 }
329 }
330
331 /**
332 * @return the list of modules
333 */
334 public List<Project> getModules() {
335 return modules;
336 }
337
338 /**
339 * @return whether to use external source for rules configuration
340 * @deprecated since 2.5. See discussion from http://jira.codehaus.org/browse/SONAR-1873
341 */
342 @Deprecated
343 public boolean getReuseExistingRulesConfig() {
344 return (configuration != null && configuration.getBoolean(CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY, false));
345 }
346
347 /**
348 * @return the current version of the project
349 */
350 public String getAnalysisVersion() {
351 return analysisVersion;
352 }
353
354 /**
355 * @return the analysis date, i.e. the date that will be used to store the snapshot
356 */
357 public Date getAnalysisDate() {
358 return analysisDate;
359 }
360
361 /**
362 * Patterns of resource exclusion as defined in project settings page.
363 */
364 public String[] getExclusionPatterns() {
365 String[] exclusions = configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY);
366 for (int index=0 ; index<exclusions.length ; index++) {
367 // http://jira.codehaus.org/browse/SONAR-2261 - exclusion must be trimmed
368 exclusions[index]=StringUtils.trim(exclusions[index]);
369 }
370 return exclusions;
371 }
372
373 /**
374 * Set exclusion patterns. Configuration is not saved, so this method must be used ONLY IN UNIT TESTS.
375 */
376 public Project setExclusionPatterns(String[] s) {
377 configuration.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, StringUtils.join(s, ","));
378 return this;
379 }
380
381 /**
382 * Note: it's better to get a reference on ProjectFileSystem as an IoC dependency (constructor parameter)
383 */
384 public ProjectFileSystem getFileSystem() {
385 return fileSystem;
386 }
387
388 /**
389 * For internal use only.
390 *
391 * @deprecated since 2.6. See http://jira.codehaus.org/browse/SONAR-2126
392 */
393 @Deprecated
394 public Project setFileSystem(ProjectFileSystem fs) {
395 this.fileSystem = fs;
396 return this;
397 }
398
399 /**
400 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011
401 */
402 @Deprecated
403 public String getGroupId() {
404 return pom.getGroupId();
405 }
406
407 /**
408 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011
409 */
410 @Deprecated
411 public String getArtifactId() {
412 return pom.getArtifactId();
413 }
414
415 /**
416 * @return the underlying Maven project
417 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011 ,
418 * MavenProject can be retrieved as an IoC dependency
419 */
420 @Deprecated
421 public MavenProject getPom() {
422 return pom;
423 }
424
425 /**
426 * @return the project configuration
427 * @deprecated since 2.12. The component org.sonar.api.config.Settings must be used.
428 */
429 @Deprecated
430 public Configuration getConfiguration() {
431 return configuration;
432 }
433
434 /**
435 * For internal use only.
436 */
437 public final Project setConfiguration(Configuration configuration) {
438 this.configuration = configuration;
439 return this;
440 }
441
442 public Object getProperty(String key) {
443 return configuration != null ? configuration.getProperty(key) : null;
444 }
445
446 public static Project createFromMavenIds(String groupId, String artifactId) {
447 return new Project(String.format("%s:%s", groupId, artifactId));
448 }
449
450 @Override
451 public String toString() {
452 return new ToStringBuilder(this)
453 .append("id", getId())
454 .append("key", getKey())
455 .append("qualifier", getQualifier())
456 .toString();
457 }
458 }