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