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  private String branch;
057  private String name;
058  private String description;
059  private Date analysisDate;
060  private String analysisVersion;
061  private Settings settings;
062  private String originalName;
063
064  // For internal use
065  private java.io.File baseDir;
066
067  // modules tree
068  private Project parent;
069  private List<Project> modules = new ArrayList<>();
070
071  public Project(String key) {
072    setKey(key);
073    setEffectiveKey(key);
074  }
075
076  public Project(String key, String branch, String name) {
077    if (StringUtils.isNotBlank(branch)) {
078      setKey(String.format(BRANCH_KEY_FORMAT, key, branch));
079      this.name = String.format("%s %s", name, branch);
080    } else {
081      setKey(key);
082      this.name = name;
083    }
084    this.originalName = this.name;
085    setEffectiveKey(getKey());
086    this.branch = branch;
087  }
088
089  public String getBranch() {
090    return branch;
091  }
092
093  /**
094   * For internal use only.
095   */
096  public Project setBranch(String branch) {
097    this.branch = branch;
098    return this;
099  }
100
101  @CheckForNull
102  public String getOriginalName() {
103    return originalName;
104  }
105
106  public void setOriginalName(String originalName) {
107    if (StringUtils.isNotBlank(branch)) {
108      this.originalName = String.format("%s %s", originalName, branch);
109    } else {
110      this.originalName = originalName;
111    }
112  }
113
114  @Override
115  public String getName() {
116    return name;
117  }
118
119  @Override
120  public String getLongName() {
121    return name;
122  }
123
124  @Override
125  public String getDescription() {
126    return description;
127  }
128
129  /**
130   * For internal use only.
131   */
132  public Project setName(String name) {
133    this.name = name;
134    return this;
135  }
136
137  @Override
138  public Language getLanguage() {
139    return null;
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   * For internal use only.
170   *
171   * @deprecated in 3.6. It's not possible to analyze a project before the latest known quality snapshot.
172   * See http://jira.sonarsource.com/browse/SONAR-4334
173   */
174  @Deprecated
175  public Project setLatestAnalysis(boolean b) {
176    if (!b) {
177      throw new UnsupportedOperationException("The analysis is always the latest one. " +
178        "Past analysis must be done in a chronological order.");
179    }
180    return this;
181  }
182
183  /**
184     * @return the language key or empty if no language is specified
185     * @deprecated since 4.2 use {@link org.sonar.api.batch.fs.FileSystem#languages()}
186     */
187  @Deprecated
188  public String getLanguageKey() {
189    if (settings == null) {
190      throw new IllegalStateException("Project is not yet initialized");
191    }
192    return StringUtils.defaultIfEmpty(settings.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY), "");
193  }
194
195  /**
196   * Internal use
197   */
198  public Project setSettings(Settings settings) {
199    this.settings = settings;
200    return this;
201  }
202
203  /**
204   * Internal use for backward compatibility. Settings should be retrieved as an IoC dependency.
205   * @deprecated since 5.0
206   */
207  @Deprecated
208  public Settings getSettings() {
209    return settings;
210  }
211
212  /**
213   * For internal use only.
214   */
215  public Project setAnalysisDate(Date analysisDate) {
216    this.analysisDate = analysisDate;
217    return this;
218  }
219
220  /**
221   * For internal use only.
222   */
223  public Project setAnalysisVersion(String analysisVersion) {
224    this.analysisVersion = analysisVersion;
225    return this;
226  }
227
228  /**
229   * @return the scope of the current object
230   */
231  @Override
232  public String getScope() {
233    return Scopes.PROJECT;
234  }
235
236  /**
237   * @return the qualifier of the current object
238   */
239  @Override
240  public String getQualifier() {
241    return isRoot() ? Qualifiers.PROJECT : Qualifiers.MODULE;
242  }
243
244  @Override
245  public boolean matchFilePattern(String antPattern) {
246    return false;
247  }
248
249  @CheckForNull
250  @Override
251  public Project getParent() {
252    return parent;
253  }
254
255  /**
256   * For internal use only.
257   */
258  public Project setParent(Project parent) {
259    this.parent = parent;
260    if (parent != null) {
261      parent.modules.add(this);
262    }
263    return this;
264  }
265
266  /**
267   * For internal use only.
268   */
269  public void removeFromParent() {
270    if (parent != null) {
271      parent.modules.remove(this);
272    }
273  }
274
275  /**
276   * @return the list of modules
277   */
278  public List<Project> getModules() {
279    return modules;
280  }
281
282  /**
283   * @return the current version of the project
284   */
285  public String getAnalysisVersion() {
286    return analysisVersion;
287  }
288
289  /**
290   * @return the analysis date, i.e. the date that will be used to store the snapshot
291   */
292  public Date getAnalysisDate() {
293    return analysisDate;
294  }
295
296  public static Project createFromMavenIds(String groupId, String artifactId) {
297    return createFromMavenIds(groupId, artifactId, null);
298  }
299
300  public static Project createFromMavenIds(String groupId, String artifactId, @Nullable String branch) {
301    return new Project(String.format(MAVEN_KEY_FORMAT, groupId, artifactId), branch, "");
302  }
303
304  @Override
305  public String toString() {
306    return new ToStringBuilder(this)
307      .append("id", getId())
308      .append("key", getKey())
309      .append("qualifier", getQualifier())
310      .toString();
311  }
312
313  @Override
314  public String key() {
315    return getKey();
316  }
317
318  @Override
319  public String name() {
320    return getName();
321  }
322
323  @Override
324  public String path() {
325    return getPath();
326  }
327
328  @Override
329  public String longName() {
330    return getLongName();
331  }
332
333  @Override
334  public String qualifier() {
335    return getQualifier();
336  }
337
338  // For internal use
339  public void setBaseDir(java.io.File baseDir) {
340    this.baseDir = baseDir;
341  }
342
343  java.io.File getBaseDir() {
344    return baseDir;
345  }
346}