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