001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2009 SonarSource SA
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, i.e. mixing MavenProjects with the way it should be analyzed
034     * 
035     * @since 1.10
036     */
037    public class Project extends Resource {
038    
039      /**
040       * @deprecated since version 1.11. Constant moved to CoreProperties
041       */
042      @Deprecated
043      public static final String PARAM_VERSION = "sonar.projectVersion";
044    
045      /**
046       * @deprecated since version 1.11. Constant moved to CoreProperties
047       */
048      @Deprecated
049      public static final String PARAM_DATE = "sonar.projectDate";
050    
051      /**
052       * @deprecated since version 1.11. Constant moved to CoreProperties
053       */
054      @Deprecated
055      public static final String PARAM_LANGUAGE = "sonar.language";
056    
057      /**
058       * @deprecated since version 1.11. Constant moved to CoreProperties
059       */
060      @Deprecated
061      public static final String PARAM_DYNAMIC_ANALYSIS = "sonar.dynamicAnalysis";
062    
063      /**
064       * @deprecated since version 1.11. Constant moved to CoreProperties
065       */
066      @Deprecated
067      public static final String PARAM_EXCLUSIONS = "sonar.exclusions";
068    
069      /**
070       * @deprecated since version 1.11. Constant moved to CoreProperties
071       */
072      @Deprecated
073      public static final String PARAM_REUSE_RULES_CONFIG = "sonar.reuseExistingRulesConfiguration";
074    
075      /**
076       * Enumerates the type of possible analysis
077       */
078      public enum AnalysisType {
079        STATIC, DYNAMIC, REUSE_REPORTS;
080    
081        /**
082         * @param includeReuseReportMode whether to count report reuse as dynamic or not
083         * @return whether this a dynamic analysis
084         */
085        public boolean isDynamic(boolean includeReuseReportMode) {
086          return equals(Project.AnalysisType.DYNAMIC) ||
087              (equals(Project.AnalysisType.REUSE_REPORTS) && includeReuseReportMode);
088        }
089      }
090    
091      private MavenProject pom;
092      private String branch;
093      private ProjectFileSystem fileSystem;
094      private Configuration configuration;
095      private String name;
096      private String description;
097      private String packaging;
098      private Language language;
099      private String languageKey;
100      private Date analysisDate;
101      private AnalysisType analysisType;
102      private String[] exclusionPatterns;
103      private String analysisVersion;
104      private boolean latestAnalysis;
105    
106      // modules tree
107      private Project parent;
108      private List<Project> modules = new ArrayList<Project>();
109    
110      public Project(String key) {
111        setKey(key);
112      }
113    
114      public Project(String key, String branch, String name) {
115        if (StringUtils.isNotBlank(branch)) {
116          setKey(String.format("%s:%s", key, branch));
117          this.name = String.format("%s %s", name, branch);
118        } else {
119          setKey(key);
120          this.name = name;
121        }
122        this.branch = branch;
123      }
124    
125      public String getBranch() {
126        return branch;
127      }
128    
129      /**
130       * For internal use only.
131       */
132      public Project setBranch(String branch) {
133        this.branch = branch;
134        return this;
135      }
136    
137      /**
138       * For internal use only.
139       */
140      public final Project setPom(MavenProject pom) {
141        this.pom = pom;
142        return this;
143      }
144    
145      /**
146       * @return the project's packaging
147       */
148      public String getPackaging() {
149        return packaging;
150      }
151    
152      public String getName() {
153        return name;
154      }
155    
156      public String getLongName() {
157        return name;
158      }
159    
160      public String getDescription() {
161        return description;
162      }
163    
164      /**
165       * For internal use only.
166       */
167      public Project setName(String name) {
168        this.name = name;
169        return this;
170      }
171    
172      /**
173       * For internal use only.
174       */
175      public Project setDescription(String description) {
176        this.description = description;
177        return this;
178      }
179    
180      /**
181       * For internal use only.
182       */
183      public Project setPackaging(String packaging) {
184        this.packaging = packaging;
185        return this;
186      }
187    
188      /**
189       * @return whether the current project is root project
190       */
191      public boolean isRoot() {
192        return getParent() == null;
193      }
194    
195      public Project getRoot() {
196        return (parent == null ? this : parent.getRoot());
197      }
198    
199      /**
200       * @return whether the current project is a module
201       */
202      public boolean isModule() {
203        return !isRoot();
204      }
205    
206      /**
207       * @return the type of analysis of the project
208       */
209      public AnalysisType getAnalysisType() {
210        return analysisType;
211      }
212    
213      public Project setAnalysisType(AnalysisType at) {
214        this.analysisType = at;
215        return this;
216      }
217    
218      /**
219       * whether it's the latest analysis done on this project (displayed in sonar dashboard) or an analysis on a past revision.
220       * 
221       * @since 2.0
222       */
223      public boolean isLatestAnalysis() {
224        return latestAnalysis;
225      }
226    
227      /**
228       * For internal use only.
229       */
230      public Project setLatestAnalysis(boolean b) {
231        this.latestAnalysis = b;
232        return this;
233      }
234    
235      /**
236       * @return the project language
237       */
238      public Language getLanguage() {
239        return language;
240      }
241    
242      public Project setLanguage(Language language) {
243        this.language = language;
244        return this;
245      }
246    
247      /**
248       * @return the language key
249       */
250      public String getLanguageKey() {
251        return languageKey;
252      }
253    
254      /**
255       * For internal use only.
256       */
257      public Project setLanguageKey(String languageKey) {
258        this.languageKey = languageKey;
259        return this;
260      }
261    
262      /**
263       * For internal use only.
264       */
265      public Project setAnalysisDate(Date analysisDate) {
266        this.analysisDate = analysisDate;
267        return this;
268      }
269    
270      /**
271       * For internal use only.
272       */
273      public Project setAnalysisVersion(String analysisVersion) {
274        this.analysisVersion = analysisVersion;
275        return this;
276      }
277    
278      /**
279       * @return the scope of the current object
280       */
281      public String getScope() {
282        return SCOPE_SET;
283      }
284    
285      /**
286       * @return the qualifier of the current object
287       */
288      public String getQualifier() {
289        return isRoot() ? QUALIFIER_PROJECT : QUALIFIER_MODULE;
290      }
291    
292      @Override
293      public boolean matchFilePattern(String antPattern) {
294        return false;
295      }
296    
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 whether to use external source for rules configuration
330       * @deprecated since 2.5. See discussion from http://jira.codehaus.org/browse/SONAR-1873
331       */
332      @Deprecated
333      public boolean getReuseExistingRulesConfig() {
334        return (configuration != null && configuration.getBoolean(CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY, false));
335      }
336    
337      /**
338       * @return the current version of the project
339       */
340      public String getAnalysisVersion() {
341        return analysisVersion;
342      }
343    
344      /**
345       * @return the analysis date, i.e. the date that will be used to store the snapshot
346       */
347      public Date getAnalysisDate() {
348        return analysisDate;
349      }
350    
351      /**
352       * Patterns of resource exclusion as defined in project settings page.
353       */
354      public String[] getExclusionPatterns() {
355        return exclusionPatterns;
356      }
357    
358      /**
359       * Set exclusion patterns. Configuration is not saved, so this method must be used ONLY IN UNIT TESTS.
360       */
361      public Project setExclusionPatterns(String[] s) {
362        this.exclusionPatterns = s;
363        return this;
364      }
365    
366      public ProjectFileSystem getFileSystem() {
367        return fileSystem;
368      }
369    
370      /**
371       * For internal use only.
372       */
373      public Project setFileSystem(ProjectFileSystem fs) {
374        this.fileSystem = fs;
375        return this;
376      }
377    
378      /**
379       * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011
380       */
381      @Deprecated
382      public String getGroupId() {
383        return pom.getGroupId();
384      }
385    
386      /**
387       * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011
388       */
389      @Deprecated
390      public String getArtifactId() {
391        return pom.getArtifactId();
392      }
393    
394      /**
395       * @return the underlying Maven project
396       * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2011 ,
397       *             MavenProject can be retrieved as an IoC dependency
398       */
399      @Deprecated
400      public MavenProject getPom() {
401        return pom;
402      }
403    
404      /**
405       * @return the project configuration
406       */
407      public Configuration getConfiguration() {
408        return configuration;
409      }
410    
411      /**
412       * For internal use only.
413       */
414      public final Project setConfiguration(Configuration configuration) {
415        this.configuration = configuration;
416        return this;
417      }
418    
419      public Object getProperty(String key) {
420        return configuration != null ? configuration.getProperty(key) : null;
421      }
422    
423      public static Project createFromMavenIds(String groupId, String artifactId) {
424        return new Project(String.format("%s:%s", groupId, artifactId));
425      }
426    
427      @Override
428      public String toString() {
429        return new ToStringBuilder(this)
430            .append("id", getId())
431            .append("key", getKey())
432            .append("qualifier", getQualifier())
433            .toString();
434      }
435    }