View Javadoc

1   /*
2    * Copyright 2006-2012 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.plugin.buildmetadata.common;
17  
18  import java.text.DateFormat;
19  import java.text.SimpleDateFormat;
20  import java.util.Date;
21  import java.util.Locale;
22  import java.util.Properties;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.maven.scm.ScmFileSet;
27  import org.apache.maven.scm.manager.ScmManager;
28  
29  import de.smartics.maven.plugin.buildmetadata.scm.LocallyModifiedInfo;
30  import de.smartics.maven.plugin.buildmetadata.scm.Revision;
31  import de.smartics.maven.plugin.buildmetadata.scm.RevisionNumberFetcher;
32  import de.smartics.maven.plugin.buildmetadata.scm.ScmException;
33  import de.smartics.maven.plugin.buildmetadata.scm.ScmNoRevisionException;
34  import de.smartics.maven.plugin.buildmetadata.scm.maven.MavenScmRevisionNumberFetcher;
35  import de.smartics.maven.plugin.buildmetadata.scm.maven.ScmAccessInfo;
36  import de.smartics.maven.plugin.buildmetadata.scm.maven.ScmConnectionInfo;
37  
38  /**
39   * Helper to access the revision information.
40   *
41   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
42   * @version $Revision:591 $
43   */
44  public final class RevisionHelper
45  {
46    // ********************************* Fields *********************************
47  
48    // --- constants ------------------------------------------------------------
49  
50    /**
51     * Reference to the logger for this class.
52     */
53    private static final Log LOG = LogFactory.getLog(RevisionHelper.class);
54  
55    // --- members --------------------------------------------------------------
56  
57    /**
58     * The manager instance to access the SCM system. Provides access to the
59     * repository and the provider information.
60     */
61    private final ScmManager scmManager;
62  
63    /**
64     * The information to connect to the SCM.
65     */
66    private final ScmConnectionInfo scmConnectionInfo;
67  
68    /**
69     * The information to query the SCM.
70     */
71    private final ScmAccessInfo scmAccessInfo;
72  
73    /**
74     * The date pattern to use to format revision dates.
75     */
76    private final String buildDatePattern;
77  
78    // ****************************** Initializer *******************************
79  
80    // ****************************** Constructors ******************************
81  
82    /**
83     * Default constructor.
84     *
85     * @param scmManager the manager instance to access the SCM system.
86     * @param scmConnectionInfo the information to connect to the SCM.
87     * @param scmAccessInfo the information to query the SCM.
88     * @param buildDatePattern the date pattern to use to format revision dates.
89     */
90    public RevisionHelper(final ScmManager scmManager,
91        final ScmConnectionInfo scmConnectionInfo,
92        final ScmAccessInfo scmAccessInfo, final String buildDatePattern)
93    {
94      this.scmManager = scmManager;
95      this.scmConnectionInfo = scmConnectionInfo;
96      this.scmAccessInfo = scmAccessInfo;
97      this.buildDatePattern = buildDatePattern;
98    }
99  
100   // ****************************** Inner Classes *****************************
101 
102   // ********************************* Methods ********************************
103 
104   // --- init -----------------------------------------------------------------
105 
106   // --- get&set --------------------------------------------------------------
107 
108   // --- business -------------------------------------------------------------
109 
110   /**
111    * Fetches the revision information and adds it to the property sets.
112    *
113    * @param buildMetaDataProperties the build meta data properties.
114    * @param scmControl the properties to control the gathering of SCM info.
115    * @throws ScmException if the creation of the SCM information failed.
116    */
117   public void provideScmBuildInfo(final Properties buildMetaDataProperties,
118       final ScmControl scmControl) throws ScmException
119   {
120     final boolean failOnMissingRevision = scmControl.isFailOnMissingRevision();
121 
122     final RevisionNumberFetcher revisionFetcher =
123         new MavenScmRevisionNumberFetcher(scmManager, scmConnectionInfo,
124             scmAccessInfo);
125     final Revision revision = revisionFetcher.fetchLatestRevisionNumber();
126     if (revision != null)
127     {
128       buildMetaDataProperties.setProperty(Constant.PROP_NAME_SCM_URL,
129           scmConnectionInfo.getConnectionUrl());
130       final String revisionId = revision.getId();
131       buildMetaDataProperties.setProperty(Constant.PROP_NAME_SCM_REVISION_ID,
132           revisionId);
133       final Date revisionDate = revision.getDate();
134       final DateFormat format =
135           new SimpleDateFormat(buildDatePattern, Locale.ENGLISH);
136       final String revisionDateString = format.format(revisionDate);
137       buildMetaDataProperties.setProperty(Constant.PROP_NAME_SCM_REVISION_DATE,
138           revisionDateString);
139 
140       final boolean validateCheckout = scmControl.isValidateCheckout();
141       if (validateCheckout)
142       {
143         provideLocallyModifiedInfo(buildMetaDataProperties, revisionFetcher);
144       }
145     }
146     else if (failOnMissingRevision)
147     {
148       throw new ScmNoRevisionException("Cannot fetch SCM revision. "
149                                        + scmConnectionInfo);
150     }
151   }
152 
153   // --- object basics --------------------------------------------------------
154 
155   /**
156    * Provides the information of locally modified files to the build properties.
157    *
158    * @param buildMetaDataProperties the build meta data properties.
159    * @param revisionFetcher the fetcher to use.
160    * @throws ScmException if the creation of the modification information
161    *           failed.
162    */
163   private void provideLocallyModifiedInfo(
164       final Properties buildMetaDataProperties,
165       final RevisionNumberFetcher revisionFetcher) throws ScmException
166   {
167     try
168     {
169       final ScmFileSet fileSet =
170           new ScmFileSet(scmAccessInfo.getRootDirectory(), "**/*", null);
171       final LocallyModifiedInfo info =
172           revisionFetcher.containsModifications(fileSet);
173       buildMetaDataProperties.setProperty(
174           Constant.PROP_NAME_SCM_LOCALLY_MODIFIED,
175           String.valueOf(info.isLocallyModified()));
176       if (info.isLocallyModified())
177       {
178         buildMetaDataProperties.setProperty(
179             Constant.PROP_NAME_SCM_LOCALLY_MODIFIED_FILES, info.getFiles());
180         if (scmAccessInfo.isFailIndicated())
181         {
182           throw new ScmException("Local Modifications detected ("
183                                  + info.getFiles() + ").");
184         }
185       }
186     }
187     catch (final Exception e)
188     {
189       if (scmAccessInfo.isFailIndicated())
190       {
191         throw new ScmException(e);
192       }
193       else
194       {
195         buildMetaDataProperties.setProperty(
196             Constant.PROP_NAME_SCM_LOCALLY_MODIFIED, "unknown");
197         if (LOG.isInfoEnabled())
198         {
199           LOG.info("Failed to check modification status.");
200         }
201       }
202     }
203   }
204 }