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      /**
077       * Enumerates the type of possible analysis
078       */
079      public enum AnalysisType {
080        STATIC, DYNAMIC, REUSE_REPORTS;
081    
082        /**
083         * @param includeReuseReportMode whether to count report reuse as dynamic or not
084         * @return whether this a dynamic analysis
085         */
086        public boolean isDynamic(boolean includeReuseReportMode) {
087          return equals(Project.AnalysisType.DYNAMIC) ||
088              (equals(Project.AnalysisType.REUSE_REPORTS) && includeReuseReportMode);
089        }
090      }
091    
092      private MavenProject pom;
093      private String branch;
094      private ProjectFileSystem fileSystem;
095      private Configuration configuration;
096      private String name;
097      private String description;
098      private String packaging;
099      private Language language;
100      private String languageKey;
101      private Date analysisDate;
102      private AnalysisType analysisType;
103      private String[] exclusionPatterns;
104      private String analysisVersion;
105      private boolean latestAnalysis;
106      
107      // modules tree
108      private Project parent;
109      private List<Project> modules = new ArrayList<Project>();
110    
111      public Project(String key) {
112        setKey(key);
113      }
114    
115      public Project(String key, String branch, String name) {
116        if (StringUtils.isNotBlank(branch)) {
117          setKey(String.format("%s:%s", key, branch));
118          this.name = String.format("%s %s", name, branch);
119        } else {
120          setKey(key);
121          this.name = name;
122        }
123        this.branch = branch;
124      }
125    
126      public String getBranch() {
127        return branch;
128      }
129    
130      public Project setBranch(String branch) {
131        this.branch = branch;
132        return this;
133      }
134    
135      public final Project setPom(MavenProject pom) {
136        this.pom = pom;
137        return this;
138      }
139    
140      /**
141       * @return the project's packaging
142       */
143      public String getPackaging() {
144        return packaging;
145      }
146    
147      public String getName() {
148        return name;
149      }
150    
151      public String getLongName() {
152        return null;
153      }
154    
155      public String getDescription() {
156        return description;
157      }
158    
159      public Project setName(String name) {
160        this.name = name;
161        return this;
162      }
163    
164      public Project setDescription(String description) {
165        this.description = description;
166        return this;
167      }
168    
169      public Project setPackaging(String packaging) {
170        this.packaging = packaging;
171        return this;
172      }
173    
174      /**
175       * @return whether the current project is root project
176       */
177      public boolean isRoot() {
178        return getParent() == null;
179      }
180    
181      public Project getRoot() {
182        return (parent == null ? this : parent.getRoot());
183      }
184    
185      /**
186       * @return whether the current project is a module
187       */
188      public boolean isModule() {
189        return !isRoot();
190      }
191    
192      /**
193       * @return the type of analysis of the project
194       */
195      public AnalysisType getAnalysisType() {
196        return analysisType;
197      }
198    
199      public Project setAnalysisType(AnalysisType at) {
200        this.analysisType = at;
201        return this;
202      }
203    
204      /**
205       * whether it's the latest analysis done on this project (displayed in sonar dashboard) or an analysis on a past revision.
206       * @since 2.0
207       */
208      public boolean isLatestAnalysis() {
209        return latestAnalysis;
210      }
211    
212      /**
213       * For internal use only.
214       */
215      public Project setLatestAnalysis(boolean b) {
216        this.latestAnalysis = b;
217        return this;
218      }
219    
220      /**
221       * Used for Maven projects
222       */
223      public String getGroupId() {
224        return pom.getGroupId();
225      }
226    
227      /**
228       * Used for Maven projects
229       */
230      public String getArtifactId() {
231        return pom.getArtifactId();
232      }
233    
234      /**
235       * @return the project language
236       */
237      public Language getLanguage() {
238        return language;
239      }
240    
241      public Project setLanguage(Language language) {
242        this.language = language;
243        return this;
244      }
245    
246      /**
247       * @return the language key
248       */
249      public String getLanguageKey() {
250        return languageKey;
251      }
252    
253      /**
254       * For internal use only.
255       */
256      public Project setLanguageKey(String languageKey) {
257        this.languageKey = languageKey;
258        return this;
259      }
260    
261      /**
262       * For internal use only.
263       */
264      public Project setAnalysisDate(Date analysisDate) {
265        this.analysisDate = analysisDate;
266        return this;
267      }
268    
269      /**
270       * For internal use only.
271       */
272      public Project setAnalysisVersion(String analysisVersion) {
273        this.analysisVersion = analysisVersion;
274        return this;
275      }
276    
277      /**
278       * @return the scope of the current object
279       */
280      public String getScope() {
281        return SCOPE_SET;
282      }
283    
284      /**
285       * @return the qualifier of the current object
286       */
287      public String getQualifier() {
288        return isRoot() ? QUALIFIER_PROJECT : QUALIFIER_MODULE;
289      }
290    
291      @Override
292      public boolean matchFilePattern(String antPattern) {
293        return false;
294      }
295    
296      public Project getParent() {
297        return parent;
298      }
299    
300      /**
301       * For internal use only.
302       */
303      public Project setParent(Project parent) {
304        this.parent = parent;
305        if (parent != null) {
306          parent.modules.add(this);
307        }
308        return this;
309      }
310    
311      /**
312       * For internal use only.
313       */
314      public void removeFromParent() {
315        if (parent!=null) {
316          parent.modules.remove(this);
317        }
318      }
319    
320      /**
321       * @return the list of modules
322       */
323      public List<Project> getModules() {
324        return modules;
325      }
326    
327      /**
328       * @return whether to use external source for rules configuration
329       */
330      public boolean getReuseExistingRulesConfig() {
331        return (configuration != null && configuration.getBoolean(CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY, false));
332      }
333    
334      /**
335       * @return the current version of the project
336       */
337      public String getAnalysisVersion() {
338        return analysisVersion;
339      }
340    
341      /**
342       * @return the analysis date, i.e. the date that will be used to store the snapshot
343       */
344      public Date getAnalysisDate() {
345        return analysisDate;
346      }
347    
348      /**
349       * Patterns of resource exclusion as defined in project settings page.
350       */
351      public String[] getExclusionPatterns() {
352        return exclusionPatterns;
353      }
354    
355      /**
356       * Set exclusion patterns. Configuration is not saved, so this method must be used ONLY IN UNIT TESTS.
357       */
358      public Project setExclusionPatterns(String[] s) {
359        this.exclusionPatterns = s;
360        return this;
361      }
362    
363      public ProjectFileSystem getFileSystem() {
364        return fileSystem;
365      }
366    
367      public Project setFileSystem(ProjectFileSystem fs) {
368        this.fileSystem = fs;
369        return this;
370      }
371    
372      /**
373       * @return the underlying maven project
374       */
375      public MavenProject getPom() {
376        return pom;
377      }
378    
379      /**
380       * @return the project configuration
381       */
382      public Configuration getConfiguration() {
383        return configuration;
384      }
385    
386      /**
387       * Sets the configuration
388       *
389       * @return the current object
390       */
391      public final Project setConfiguration(Configuration configuration) {
392        this.configuration = configuration;
393        return this;
394      }
395    
396      public Object getProperty(String key) {
397        return configuration != null ? configuration.getProperty(key) : null;
398      }
399    
400      public static Project createFromMavenIds(String groupId, String artifactId) {
401        return new Project(String.format("%s:%s", groupId, artifactId));
402      }
403    
404      @Override
405      public String toString() {
406        return new ToStringBuilder(this)
407            .append("id", getId())
408            .append("key", getKey())
409            .append("qualifier", getQualifier())
410            .toString();
411      }
412    }