001/* 002 * SonarQube 003 * Copyright (C) 2009-2016 SonarSource SA 004 * mailto:contact AT sonarsource DOT com 005 * 006 * This program 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 * This program 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 */ 020package org.sonar.api.resources; 021 022import java.util.ArrayList; 023import java.util.Date; 024import java.util.List; 025import javax.annotation.CheckForNull; 026import javax.annotation.Nullable; 027import org.apache.commons.lang.StringUtils; 028import org.apache.commons.lang.builder.ToStringBuilder; 029import org.sonar.api.CoreProperties; 030import org.sonar.api.batch.fs.InputModule; 031import org.sonar.api.component.Component; 032import org.sonar.api.config.Settings; 033 034/** 035 * @since 1.10 036 * @deprecated since 5.6 replaced by {@link InputModule}. 037 */ 038@Deprecated 039public class Project extends Resource implements Component { 040 041 /** 042 * Internal use 043 */ 044 public static final Language NONE_LANGUAGE = new AbstractLanguage("none", "None") { 045 @Override 046 public String[] getFileSuffixes() { 047 return new String[0]; 048 } 049 }; 050 051 static final String MAVEN_KEY_FORMAT = "%s:%s"; 052 private static final String BRANCH_KEY_FORMAT = "%s:%s"; 053 054 public static final String SCOPE = Scopes.PROJECT; 055 056 /** 057 * Enumerates the type of possible analysis 058 * @deprecated since 4.4 Since 4.3 SQ will no more run tests. So basically it's always reuse report. 059 */ 060 @Deprecated 061 public enum AnalysisType { 062 STATIC, DYNAMIC, REUSE_REPORTS; 063 064 /** 065 * @param includeReuseReportMode whether to count report reuse as dynamic or not 066 * @return whether this a dynamic analysis 067 */ 068 public boolean isDynamic(boolean includeReuseReportMode) { 069 return equals(Project.AnalysisType.DYNAMIC) || 070 (equals(Project.AnalysisType.REUSE_REPORTS) && includeReuseReportMode); 071 } 072 } 073 074 private String branch; 075 private String name; 076 private String description; 077 private Language language; 078 private Date analysisDate; 079 private AnalysisType analysisType; 080 private String analysisVersion; 081 private Settings settings; 082 083 // For internal use 084 private java.io.File baseDir; 085 086 // modules tree 087 private Project parent; 088 private List<Project> modules = new ArrayList<>(); 089 090 public Project(String key) { 091 setKey(key); 092 setEffectiveKey(key); 093 } 094 095 public Project(String key, String branch, String name) { 096 if (StringUtils.isNotBlank(branch)) { 097 setKey(String.format(BRANCH_KEY_FORMAT, key, branch)); 098 this.name = String.format("%s %s", name, branch); 099 } else { 100 setKey(key); 101 this.name = name; 102 } 103 setEffectiveKey(getKey()); 104 this.branch = branch; 105 } 106 107 public String getBranch() { 108 return branch; 109 } 110 111 /** 112 * For internal use only. 113 */ 114 public Project setBranch(String branch) { 115 this.branch = branch; 116 return this; 117 } 118 119 @Override 120 public String getName() { 121 return name; 122 } 123 124 @Override 125 public String getLongName() { 126 return name; 127 } 128 129 @Override 130 public String getDescription() { 131 return description; 132 } 133 134 /** 135 * For internal use only. 136 */ 137 public Project setName(String name) { 138 this.name = name; 139 return this; 140 } 141 142 /** 143 * For internal use only. 144 */ 145 public Project setDescription(String description) { 146 this.description = description; 147 return this; 148 } 149 150 /** 151 * @return whether the current project is root project 152 */ 153 public boolean isRoot() { 154 return getParent() == null; 155 } 156 157 public Project getRoot() { 158 return parent == null ? this : parent.getRoot(); 159 } 160 161 /** 162 * @return whether the current project is a module 163 */ 164 public boolean isModule() { 165 return !isRoot(); 166 } 167 168 /** 169 * @deprecated since 4.4 Since 4.3 SQ will no more run tests. So basically it's always reuse report. 170 */ 171 @Deprecated 172 public AnalysisType getAnalysisType() { 173 return analysisType; 174 } 175 176 /** 177 * @deprecated since 4.4 Since 4.3 SQ will no more run tests. So basically it's always reuse report. 178 */ 179 @Deprecated 180 public Project setAnalysisType(AnalysisType at) { 181 this.analysisType = at; 182 return this; 183 } 184 185 /** 186 * whether it's the latest analysis done on this project (displayed in sonar dashboard) or an analysis on a past revision. 187 * 188 * @since 2.0 189 * @deprecated in 3.6. The analysis is now always the latest one (past analysis must be done in a chronological order). See http://jira.sonarsource.com/browse/SONAR-4334 190 */ 191 @Deprecated 192 public boolean isLatestAnalysis() { 193 return true; 194 } 195 196 /** 197 * For internal use only. 198 * 199 * @deprecated in 3.6. It's not possible to analyze a project before the latest known quality snapshot. 200 * See http://jira.sonarsource.com/browse/SONAR-4334 201 */ 202 @Deprecated 203 public Project setLatestAnalysis(boolean b) { 204 if (!b) { 205 throw new UnsupportedOperationException("The analysis is always the latest one. " + 206 "Past analysis must be done in a chronological order."); 207 } 208 return this; 209 } 210 211 /** 212 * @return the project language when there is only one language 213 * @deprecated since 4.2 use {@link org.sonar.api.batch.fs.FileSystem#languages()} 214 */ 215 @Deprecated 216 @Override 217 public Language getLanguage() { 218 return language; 219 } 220 221 /** 222 * Internal use 223 */ 224 public Project setLanguage(Language language) { 225 this.language = language; 226 return this; 227 } 228 229 /** 230 * @return the language key or empty if no language is specified 231 * @deprecated since 4.2 use {@link org.sonar.api.batch.fs.FileSystem#languages()} 232 */ 233 @Deprecated 234 public String getLanguageKey() { 235 if (settings == null) { 236 throw new IllegalStateException("Project is not yet initialized"); 237 } 238 return StringUtils.defaultIfEmpty(settings.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY), ""); 239 } 240 241 /** 242 * Internal use 243 */ 244 public Project setSettings(Settings settings) { 245 this.settings = settings; 246 return this; 247 } 248 249 /** 250 * Internal use for backward compatibility. Settings should be retrieved as an IoC dependency. 251 * @deprecated since 5.0 252 */ 253 @Deprecated 254 public Settings getSettings() { 255 return settings; 256 } 257 258 /** 259 * For internal use only. 260 */ 261 public Project setAnalysisDate(Date analysisDate) { 262 this.analysisDate = analysisDate; 263 return this; 264 } 265 266 /** 267 * For internal use only. 268 */ 269 public Project setAnalysisVersion(String analysisVersion) { 270 this.analysisVersion = analysisVersion; 271 return this; 272 } 273 274 /** 275 * @return the scope of the current object 276 */ 277 @Override 278 public String getScope() { 279 return Scopes.PROJECT; 280 } 281 282 /** 283 * @return the qualifier of the current object 284 */ 285 @Override 286 public String getQualifier() { 287 return isRoot() ? Qualifiers.PROJECT : Qualifiers.MODULE; 288 } 289 290 @Override 291 public boolean matchFilePattern(String antPattern) { 292 return false; 293 } 294 295 @CheckForNull 296 @Override 297 public Project getParent() { 298 return parent; 299 } 300 301 /** 302 * For internal use only. 303 */ 304 public Project setParent(Project parent) { 305 this.parent = parent; 306 if (parent != null) { 307 parent.modules.add(this); 308 } 309 return this; 310 } 311 312 /** 313 * For internal use only. 314 */ 315 public void removeFromParent() { 316 if (parent != null) { 317 parent.modules.remove(this); 318 } 319 } 320 321 /** 322 * @return the list of modules 323 */ 324 public List<Project> getModules() { 325 return modules; 326 } 327 328 /** 329 * @return the current version of the project 330 */ 331 public String getAnalysisVersion() { 332 return analysisVersion; 333 } 334 335 /** 336 * @return the analysis date, i.e. the date that will be used to store the snapshot 337 */ 338 public Date getAnalysisDate() { 339 return analysisDate; 340 } 341 342 public static Project createFromMavenIds(String groupId, String artifactId) { 343 return createFromMavenIds(groupId, artifactId, null); 344 } 345 346 public static Project createFromMavenIds(String groupId, String artifactId, @Nullable String branch) { 347 return new Project(String.format(MAVEN_KEY_FORMAT, groupId, artifactId), branch, ""); 348 } 349 350 @Override 351 public String toString() { 352 return new ToStringBuilder(this) 353 .append("id", getId()) 354 .append("key", getKey()) 355 .append("qualifier", getQualifier()) 356 .toString(); 357 } 358 359 @Override 360 public String key() { 361 return getKey(); 362 } 363 364 @Override 365 public String name() { 366 return getName(); 367 } 368 369 @Override 370 public String path() { 371 return getPath(); 372 } 373 374 @Override 375 public String longName() { 376 return getLongName(); 377 } 378 379 @Override 380 public String qualifier() { 381 return getQualifier(); 382 } 383 384 // For internal use 385 public void setBaseDir(java.io.File baseDir) { 386 this.baseDir = baseDir; 387 } 388 389 java.io.File getBaseDir() { 390 return baseDir; 391 } 392}