001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 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[] exclusionPatterns;
105      private String analysisVersion;
106      private boolean latestAnalysis;
107    
108      // modules tree
109      private Project parent;
110      private List<Project> modules = new ArrayList<Project>();
111    
112      public Project(String key) {
113        setKey(key);
114        setEffectiveKey(key);
115      }
116    
117      public Project(String key, String branch, String name) {
118        if (StringUtils.isNotBlank(branch)) {
119          setKey(String.format("%s:%s", key, branch));
120          this.name = String.format("%s %s", name, branch);
121        } else {
122          setKey(key);
123          this.name = name;
124        }
125        setEffectiveKey(getKey());
126        this.branch = branch;
127      }
128    
129      public String getBranch() {
130        return branch;
131      }
132    
133      /**
134       * For internal use only.
135       */
136      public Project setBranch(String branch) {
137        this.branch = branch;
138        return this;
139      }
140    
141      /**
142       * For internal use only.
143       */
144      public final Project setPom(MavenProject pom) {
145        this.pom = pom;
146        return this;
147      }
148    
149      /**
150       * @return the project's packaging
151       * @deprecated in 2.8. See http://jira.codehaus.org/browse/SONAR-2341
152       */
153      @Deprecated
154      public String getPackaging() {
155        return packaging;
156      }
157    
158      public String getName() {
159        return name;
160      }
161    
162      public String getLongName() {
163        return name;
164      }
165    
166      public String getDescription() {
167        return description;
168      }
169    
170      /**
171       * For internal use only.
172       */
173      public Project setName(String name) {
174        this.name = name;
175        return this;
176      }
177    
178      /**
179       * For internal use only.
180       */
181      public Project setDescription(String description) {
182        this.description = description;
183        return this;
184      }
185    
186      /**
187       * For internal use only.
188       * 
189       * @deprecated in 2.8. See http://jira.codehaus.org/browse/SONAR-2341
190       */
191      @Deprecated
192      public Project setPackaging(String packaging) {
193        this.packaging = packaging;
194        return this;
195      }
196    
197      /**
198       * @return whether the current project is root project
199       */
200      public boolean isRoot() {
201        return getParent() == null;
202      }
203    
204      public Project getRoot() {
205        return (parent == null ? this : parent.getRoot());
206      }
207    
208      /**
209       * @return whether the current project is a module
210       */
211      public boolean isModule() {
212        return !isRoot();
213      }
214    
215      /**
216       * @return the type of analysis of the project
217       */
218      public AnalysisType getAnalysisType() {
219        return analysisType;
220      }
221    
222      public Project setAnalysisType(AnalysisType at) {
223        this.analysisType = at;
224        return this;
225      }
226    
227      /**
228       * whether it's the latest analysis done on this project (displayed in sonar dashboard) or an analysis on a past revision.
229       * 
230       * @since 2.0
231       */
232      public boolean isLatestAnalysis() {
233        return latestAnalysis;
234      }
235    
236      /**
237       * For internal use only.
238       */
239      public Project setLatestAnalysis(boolean b) {
240        this.latestAnalysis = b;
241        return this;
242      }
243    
244      /**
245       * @return the project language
246       */
247      public Language getLanguage() {
248        return language;
249      }
250    
251      public Project setLanguage(Language language) {
252        this.language = language;
253        return this;
254      }
255    
256      /**
257       * @return the language key
258       */
259      public String getLanguageKey() {
260        return languageKey;
261      }
262    
263      /**
264       * For internal use only.
265       */
266      public Project setLanguageKey(String languageKey) {
267        this.languageKey = languageKey;
268        return this;
269      }
270    
271      /**
272       * For internal use only.
273       */
274      public Project setAnalysisDate(Date analysisDate) {
275        this.analysisDate = analysisDate;
276        return this;
277      }
278    
279      /**
280       * For internal use only.
281       */
282      public Project setAnalysisVersion(String analysisVersion) {
283        this.analysisVersion = analysisVersion;
284        return this;
285      }
286    
287      /**
288       * @return the scope of the current object
289       */
290      public String getScope() {
291        return Scopes.PROJECT;
292      }
293    
294      /**
295       * @return the qualifier of the current object
296       */
297      public String getQualifier() {
298        return isRoot() ? Qualifiers.PROJECT : Qualifiers.MODULE;
299      }
300    
301      @Override
302      public boolean matchFilePattern(String antPattern) {
303        return false;
304      }
305    
306      public Project getParent() {
307        return parent;
308      }
309    
310    
311    
312      /**
313       * For internal use only.
314       */
315      public Project setParent(Project parent) {
316        this.parent = parent;
317        if (parent != null) {
318          parent.modules.add(this);
319        }
320        return this;
321      }
322    
323      /**
324       * For internal use only.
325       */
326      public void removeFromParent() {
327        if (parent != null) {
328          parent.modules.remove(this);
329        }
330      }
331    
332      /**
333       * @return the list of modules
334       */
335      public List<Project> getModules() {
336        return modules;
337      }
338    
339      /**
340       * @return whether to use external source for rules configuration
341       * @deprecated since 2.5. See discussion from http://jira.codehaus.org/browse/SONAR-1873
342       */
343      @Deprecated
344      public boolean getReuseExistingRulesConfig() {
345        return (configuration != null && configuration.getBoolean(CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY, false));
346      }
347    
348      /**
349       * @return the current version of the project
350       */
351      public String getAnalysisVersion() {
352        return analysisVersion;
353      }
354    
355      /**
356       * @return the analysis date, i.e. the date that will be used to store the snapshot
357       */
358      public Date getAnalysisDate() {
359        return analysisDate;
360      }
361    
362      /**
363       * Patterns of resource exclusion as defined in project settings page.
364       */
365      public String[] getExclusionPatterns() {
366        return exclusionPatterns;
367      }
368    
369      /**
370       * Set exclusion patterns. Configuration is not saved, so this method must be used ONLY IN UNIT TESTS.
371       */
372      public Project setExclusionPatterns(String[] s) {
373        this.exclusionPatterns = s;
374        return this;
375      }
376    
377      /**
378       * Note: it's better to get a reference on ProjectFileSystem as an IoC dependency (constructor parameter)
379       */
380      public ProjectFileSystem getFileSystem() {
381        return fileSystem;
382      }
383    
384      /**
385       * For internal use only.
386       * 
387       * @deprecated since 2.6. See http://jira.codehaus.org/browse/SONAR-2126
388       */
389      @Deprecated
390      public Project setFileSystem(ProjectFileSystem fs) {
391        this.fileSystem = fs;
392        return this;
393      }
394    
395      /**
396       * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011
397       */
398      @Deprecated
399      public String getGroupId() {
400        return pom.getGroupId();
401      }
402    
403      /**
404       * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011
405       */
406      @Deprecated
407      public String getArtifactId() {
408        return pom.getArtifactId();
409      }
410    
411      /**
412       * @return the underlying Maven project
413       * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011 ,
414       *             MavenProject can be retrieved as an IoC dependency
415       */
416      @Deprecated
417      public MavenProject getPom() {
418        return pom;
419      }
420    
421      /**
422       * @return the project configuration
423       */
424      public Configuration getConfiguration() {
425        return configuration;
426      }
427    
428      /**
429       * For internal use only.
430       */
431      public final Project setConfiguration(Configuration configuration) {
432        this.configuration = configuration;
433        return this;
434      }
435    
436      public Object getProperty(String key) {
437        return configuration != null ? configuration.getProperty(key) : null;
438      }
439    
440      public static Project createFromMavenIds(String groupId, String artifactId) {
441        return new Project(String.format("%s:%s", groupId, artifactId));
442      }
443    
444      @Override
445      public String toString() {
446        return new ToStringBuilder(this)
447            .append("id", getId())
448            .append("key", getKey())
449            .append("qualifier", getQualifier())
450            .toString();
451      }
452    }