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.batch;
021    
022    import org.apache.commons.configuration.*;
023    import org.apache.commons.lang.time.DateUtils;
024    import org.apache.maven.project.MavenProject;
025    import org.sonar.api.CoreProperties;
026    import org.sonar.api.database.DatabaseSession;
027    import org.sonar.api.database.model.ResourceModel;
028    import org.sonar.api.database.model.Snapshot;
029    import org.sonar.api.resources.DefaultProjectFileSystem;
030    import org.sonar.api.resources.Java;
031    import org.sonar.api.resources.Project;
032    import org.sonar.api.utils.SonarException;
033    
034    import java.text.DateFormat;
035    import java.text.ParseException;
036    import java.text.SimpleDateFormat;
037    import java.util.Date;
038    
039    public class ProjectBuilder {
040    
041      private DatabaseSession databaseSession;
042    
043      public ProjectBuilder(DatabaseSession databaseSession) {
044        this.databaseSession = databaseSession;
045      }
046    
047      public Project create(MavenProject pom) {
048        Configuration configuration = getStartupConfiguration(pom);
049        return new Project(loadProjectKey(pom), loadProjectBranch(configuration), pom.getName())
050            .setPom(pom)
051            .setDescription(pom.getDescription())
052            .setPackaging(pom.getPackaging());
053      }
054    
055      Configuration getStartupConfiguration(MavenProject pom) {
056        CompositeConfiguration configuration = new CompositeConfiguration();
057        configuration.addConfiguration(new SystemConfiguration());
058        configuration.addConfiguration(new EnvironmentConfiguration());
059        configuration.addConfiguration(new MapConfiguration(pom.getModel().getProperties()));
060        return configuration;
061      }
062    
063      String loadProjectKey(MavenProject pom) {
064        return new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString();
065      }
066    
067      String loadProjectBranch(Configuration configuration) {
068        return configuration.getString(CoreProperties.PROJECT_BRANCH_PROPERTY, configuration.getString("branch" /* deprecated property */));
069      }
070    
071    
072      public void configure(Project project) {
073        ProjectConfiguration projectConfiguration = new ProjectConfiguration(databaseSession, project);
074        configure(project, projectConfiguration);
075      }
076    
077    
078      void configure(Project project, Configuration projectConfiguration) {
079        Date analysisDate = loadAnalysisDate(projectConfiguration);
080        project.setConfiguration(projectConfiguration)
081            .setExclusionPatterns(loadExclusionPatterns(projectConfiguration))
082            .setAnalysisDate(analysisDate)
083            .setLatestAnalysis(isLatestAnalysis(project.getKey(), analysisDate))
084            .setAnalysisVersion(loadAnalysisVersion(projectConfiguration, project.getPom()))
085            .setAnalysisType(loadAnalysisType(projectConfiguration))
086            .setLanguageKey(loadLanguageKey(projectConfiguration))
087            .setFileSystem(new DefaultProjectFileSystem(project));
088      }
089    
090      static String[] loadExclusionPatterns(Configuration configuration) {
091        String[] exclusionPatterns = configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY);
092        if (exclusionPatterns == null) {
093          exclusionPatterns = new String[0];
094        }
095        return exclusionPatterns;
096      }
097    
098      boolean isLatestAnalysis(String projectKey, Date analysisDate) {
099        ResourceModel persistedProject = databaseSession.getSingleResult(ResourceModel.class, "key", projectKey, "enabled", true);
100        if (persistedProject != null) {
101          Snapshot lastSnapshot = databaseSession.getSingleResult(Snapshot.class, "resourceId", persistedProject.getId(), "last", true);
102          return lastSnapshot == null || lastSnapshot.getCreatedAt().before(analysisDate);
103        }
104        return true;
105      }
106    
107    
108      Date loadAnalysisDate(Configuration configuration) {
109        String formattedDate = configuration.getString(CoreProperties.PROJECT_DATE_PROPERTY);
110        if (formattedDate == null) {
111          return new Date();
112        }
113    
114        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
115        try {
116          // see SONAR-908 make sure that a time is defined for the date.
117          Date date = DateUtils.setHours(format.parse(formattedDate), 0);
118          return DateUtils.setMinutes(date, 1);
119    
120        } catch (ParseException e) {
121          throw new SonarException("The property " + CoreProperties.PROJECT_DATE_PROPERTY + " does not respect the format yyyy-MM-dd (for example 2008-05-23) : " + formattedDate, e);
122        }
123      }
124    
125      Project.AnalysisType loadAnalysisType(Configuration configuration) {
126        String value = configuration.getString(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY);
127        if (value == null) {
128          return (configuration.getBoolean("sonar.light", false) ? Project.AnalysisType.STATIC : Project.AnalysisType.DYNAMIC);
129        }
130        if ("true".equals(value)) {
131          return Project.AnalysisType.DYNAMIC;
132        }
133        if ("reuseReports".equals(value)) {
134          return Project.AnalysisType.REUSE_REPORTS;
135        }
136        return Project.AnalysisType.STATIC;
137      }
138    
139      String loadAnalysisVersion(Configuration configuration, MavenProject pom) {
140        String version = configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY);
141        if (version == null && pom != null) {
142          version = pom.getVersion();
143        }
144        return version;
145      }
146    
147      String loadLanguageKey(Configuration configuration) {
148        return configuration.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY, Java.KEY);
149      }
150    }