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