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 */ 020package org.sonar.api.resources; 021 022import org.apache.commons.configuration.Configuration; 023import org.apache.commons.lang.StringUtils; 024import org.apache.commons.lang.builder.ToStringBuilder; 025import org.apache.maven.project.MavenProject; 026import org.sonar.api.CoreProperties; 027 028import java.util.ArrayList; 029import java.util.Date; 030import java.util.List; 031 032/** 033 * A class that manipulates Projects in the Sonar way. 034 * 035 * @since 1.10 036 */ 037public 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 @Override 158 public String getName() { 159 return name; 160 } 161 162 @Override 163 public String getLongName() { 164 return name; 165 } 166 167 @Override 168 public String getDescription() { 169 return description; 170 } 171 172 /** 173 * For internal use only. 174 */ 175 public Project setName(String name) { 176 this.name = name; 177 return this; 178 } 179 180 /** 181 * For internal use only. 182 */ 183 public Project setDescription(String description) { 184 this.description = description; 185 return this; 186 } 187 188 /** 189 * For internal use only. 190 * 191 * @deprecated in 2.8. See http://jira.codehaus.org/browse/SONAR-2341 192 */ 193 @Deprecated 194 public Project setPackaging(String packaging) { 195 this.packaging = packaging; 196 return this; 197 } 198 199 /** 200 * @return whether the current project is root project 201 */ 202 public boolean isRoot() { 203 return getParent() == null; 204 } 205 206 public Project getRoot() { 207 return (parent == null ? this : parent.getRoot()); 208 } 209 210 /** 211 * @return whether the current project is a module 212 */ 213 public boolean isModule() { 214 return !isRoot(); 215 } 216 217 /** 218 * @return the type of analysis of the project 219 */ 220 public AnalysisType getAnalysisType() { 221 return analysisType; 222 } 223 224 public Project setAnalysisType(AnalysisType at) { 225 this.analysisType = at; 226 return this; 227 } 228 229 /** 230 * whether it's the latest analysis done on this project (displayed in sonar dashboard) or an analysis on a past revision. 231 * 232 * @since 2.0 233 */ 234 public boolean isLatestAnalysis() { 235 return latestAnalysis; 236 } 237 238 /** 239 * For internal use only. 240 */ 241 public Project setLatestAnalysis(boolean b) { 242 this.latestAnalysis = b; 243 return this; 244 } 245 246 /** 247 * @return the project language 248 */ 249 @Override 250 public Language getLanguage() { 251 return language; 252 } 253 254 public Project setLanguage(Language language) { 255 this.language = language; 256 return this; 257 } 258 259 /** 260 * @return the language key 261 */ 262 public String getLanguageKey() { 263 return languageKey; 264 } 265 266 /** 267 * For internal use only. 268 */ 269 public Project setLanguageKey(String languageKey) { 270 this.languageKey = languageKey; 271 return this; 272 } 273 274 /** 275 * For internal use only. 276 */ 277 public Project setAnalysisDate(Date analysisDate) { 278 this.analysisDate = analysisDate; 279 return this; 280 } 281 282 /** 283 * For internal use only. 284 */ 285 public Project setAnalysisVersion(String analysisVersion) { 286 this.analysisVersion = analysisVersion; 287 return this; 288 } 289 290 /** 291 * @return the scope of the current object 292 */ 293 @Override 294 public String getScope() { 295 return Scopes.PROJECT; 296 } 297 298 /** 299 * @return the qualifier of the current object 300 */ 301 @Override 302 public String getQualifier() { 303 return isRoot() ? Qualifiers.PROJECT : Qualifiers.MODULE; 304 } 305 306 @Override 307 public boolean matchFilePattern(String antPattern) { 308 return false; 309 } 310 311 @Override 312 public Project getParent() { 313 return parent; 314 } 315 316 317 318 /** 319 * For internal use only. 320 */ 321 public Project setParent(Project parent) { 322 this.parent = parent; 323 if (parent != null) { 324 parent.modules.add(this); 325 } 326 return this; 327 } 328 329 /** 330 * For internal use only. 331 */ 332 public void removeFromParent() { 333 if (parent != null) { 334 parent.modules.remove(this); 335 } 336 } 337 338 /** 339 * @return the list of modules 340 */ 341 public List<Project> getModules() { 342 return modules; 343 } 344 345 /** 346 * @return whether to use external source for rules configuration 347 * @deprecated since 2.5. See discussion from http://jira.codehaus.org/browse/SONAR-1873 348 */ 349 @Deprecated 350 public boolean getReuseExistingRulesConfig() { 351 return (configuration != null && configuration.getBoolean(CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY, false)); 352 } 353 354 /** 355 * @return the current version of the project 356 */ 357 public String getAnalysisVersion() { 358 return analysisVersion; 359 } 360 361 /** 362 * @return the analysis date, i.e. the date that will be used to store the snapshot 363 */ 364 public Date getAnalysisDate() { 365 return analysisDate; 366 } 367 368 /** 369 * Patterns of resource exclusion as defined in project settings page. 370 */ 371 public String[] getExclusionPatterns() { 372 String[] exclusions = configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY); 373 for (int index=0 ; index<exclusions.length ; index++) { 374 // http://jira.codehaus.org/browse/SONAR-2261 - exclusion must be trimmed 375 exclusions[index]=StringUtils.trim(exclusions[index]); 376 } 377 return exclusions; 378 } 379 380 /** 381 * Set exclusion patterns. Configuration is not saved, so this method must be used ONLY IN UNIT TESTS. 382 */ 383 public Project setExclusionPatterns(String[] s) { 384 configuration.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, StringUtils.join(s, ",")); 385 return this; 386 } 387 388 /** 389 * Note: it's better to get a reference on ProjectFileSystem as an IoC dependency (constructor parameter) 390 */ 391 public ProjectFileSystem getFileSystem() { 392 return fileSystem; 393 } 394 395 /** 396 * For internal use only. 397 * 398 * @deprecated since 2.6. See http://jira.codehaus.org/browse/SONAR-2126 399 */ 400 @Deprecated 401 public Project setFileSystem(ProjectFileSystem fs) { 402 this.fileSystem = fs; 403 return this; 404 } 405 406 /** 407 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011 408 */ 409 @Deprecated 410 public String getGroupId() { 411 return pom.getGroupId(); 412 } 413 414 /** 415 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011 416 */ 417 @Deprecated 418 public String getArtifactId() { 419 return pom.getArtifactId(); 420 } 421 422 /** 423 * @return the underlying Maven project 424 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011 , 425 * MavenProject can be retrieved as an IoC dependency 426 */ 427 @Deprecated 428 public MavenProject getPom() { 429 return pom; 430 } 431 432 /** 433 * @return the project configuration 434 * @deprecated since 2.12. The component org.sonar.api.config.Settings must be used. 435 */ 436 @Deprecated 437 public Configuration getConfiguration() { 438 return configuration; 439 } 440 441 /** 442 * For internal use only. 443 */ 444 public final Project setConfiguration(Configuration configuration) { 445 this.configuration = configuration; 446 return this; 447 } 448 449 public Object getProperty(String key) { 450 return configuration != null ? configuration.getProperty(key) : null; 451 } 452 453 public static Project createFromMavenIds(String groupId, String artifactId) { 454 return new Project(String.format("%s:%s", groupId, artifactId)); 455 } 456 457 @Override 458 public String toString() { 459 return new ToStringBuilder(this) 460 .append("id", getId()) 461 .append("key", getKey()) 462 .append("qualifier", getQualifier()) 463 .toString(); 464 } 465}