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.data;
17  
18  import java.util.Locale;
19  import java.util.Properties;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.maven.project.MavenProject;
24  import org.apache.maven.scm.manager.NoSuchScmProviderException;
25  import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
26  import org.apache.maven.scm.repository.ScmRepository;
27  import org.apache.maven.scm.repository.ScmRepositoryException;
28  import org.codehaus.plexus.util.StringUtils;
29  
30  import de.smartics.maven.plugin.buildmetadata.common.RevisionHelper;
31  import de.smartics.maven.plugin.buildmetadata.common.ScmControl;
32  import de.smartics.maven.plugin.buildmetadata.common.ScmCredentials;
33  import de.smartics.maven.plugin.buildmetadata.common.ScmInfo;
34  import de.smartics.maven.plugin.buildmetadata.scm.maven.ScmAccessInfo;
35  import de.smartics.maven.plugin.buildmetadata.scm.maven.ScmConnectionInfo;
36  
37  /**
38   * Extracts information from the Maven project, session, and runtime
39   * information.
40   *
41   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
42   * @version $Revision:591 $
43   */
44  public class ScmMetaDataProvider extends AbstractMetaDataProvider
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(ScmMetaDataProvider.class);
54  
55    // --- members --------------------------------------------------------------
56  
57    // ****************************** Initializer *******************************
58  
59    // ****************************** Constructors ******************************
60  
61    /**
62     * Constructor.
63     *
64     * @param project the Maven project.
65     * @param scmInfo the value for scmInfo.
66     * @see de.smartics.maven.plugin.buildmetadata.data.AbstractMetaDataProvider#AbstractMetaDataProvider()
67     */
68    public ScmMetaDataProvider(final MavenProject project, final ScmInfo scmInfo)
69    {
70      this.project = project;
71      this.scmInfo = scmInfo;
72    }
73  
74    // ****************************** Inner Classes *****************************
75  
76    // ********************************* Methods ********************************
77  
78    // --- init -----------------------------------------------------------------
79  
80    // --- get&set --------------------------------------------------------------
81  
82    // --- business -------------------------------------------------------------
83  
84    /**
85     * Provides the SCM build information to the property sets if the URL to the
86     * SCM is provided.
87     *
88     * @param buildMetaDataProperties the build meta data properties.
89     */
90    public final void provideBuildMetaData(final Properties buildMetaDataProperties)
91    {
92      final ScmControl scmControl = scmInfo.getScmControl();
93      if (scmControl.isAddScmInfo() && !scmControl.isOffline()
94          && project.getScm() != null)
95      {
96        try
97        {
98          final ScmConnectionInfo scmConnectionInfo = loadConnectionInfo();
99          final ScmAccessInfo scmAccessInfo = createScmAccessInfo();
100         final RevisionHelper helper =
101             new RevisionHelper(scmInfo.getScmManager(), scmConnectionInfo,
102                 scmAccessInfo, scmInfo.getBuildDatePattern());
103         helper.provideScmBuildInfo(buildMetaDataProperties, scmControl);
104       }
105       catch (final ScmRepositoryException e)
106       {
107         throw new IllegalStateException(
108             "Cannot fetch SCM revision information.", e);
109       }
110       catch (final NoSuchScmProviderException e)
111       {
112         throw new IllegalStateException(
113             "Cannot fetch SCM revision information.", e);
114       }
115     }
116     else
117     {
118       LOG.debug("Skipping SCM data since addScmInfo="
119                 + scmControl.isAddScmInfo() + ", offline="
120                 + scmControl.isOffline() + ", scmInfoProvided="
121                 + (project.getScm() != null) + ".");
122     }
123   }
124 
125   /**
126    * Load user name password from settings if user has not set them via JVM
127    * properties.
128    *
129    * @return the connection information to connect to the SCM system.
130    * @throws IllegalStateException if the connection string to the SCM cannot be
131    *           fetched.
132    * @throws ScmRepositoryException if the repository information is not
133    *           sufficient to build the repository instance.
134    * @throws NoSuchScmProviderException if there is no provider for the SCM
135    *           connection URL.
136    */
137   private ScmConnectionInfo loadConnectionInfo() throws IllegalStateException,
138     ScmRepositoryException, NoSuchScmProviderException
139   {
140     final String scmConnection = getConnection();
141     final ScmCredentials credentials = scmInfo.getScmCrendentials();
142     if (credentials.getUserName() == null || credentials.getPassword() == null)
143     {
144       final ScmRepository repository =
145           scmInfo.getScmManager().makeScmRepository(scmConnection);
146       if (repository.getProviderRepository() instanceof ScmProviderRepositoryWithHost)
147       {
148         final ScmProviderRepositoryWithHost repositoryWithHost =
149             (ScmProviderRepositoryWithHost) repository.getProviderRepository();
150         final String host = createHostName(repositoryWithHost);
151         credentials.configureByServer(host);
152       }
153     }
154 
155     final ScmConnectionInfo info = new ScmConnectionInfo();
156     info.setUserName(credentials.getUserName());
157     info.setPassword(credentials.getPassword());
158     info.setPrivateKey(credentials.getPrivateKey());
159     info.setScmConnectionUrl(scmConnection);
160     info.setTagBase(scmInfo.getTagBase());
161     return info;
162   }
163 
164   /**
165    * Delegates call to {@link org.apache.maven.model.Scm#getConnection()}.
166    *
167    * @return the result of the call to
168    *         {@link org.apache.maven.model.Scm#getConnection()}.
169    * @throws IllegalStateException when there is insufficient information to
170    *           return the SCM connection string.
171    * @see org.apache.maven.model.Scm#getConnection()
172    */
173   protected final String getConnection() throws IllegalStateException
174   {
175     if (project.getScm() == null)
176     {
177       throw new IllegalStateException("SCM Connection is not set.");
178     }
179 
180     final String scmConnection = project.getScm().getConnection();
181     final String connectionType = scmInfo.getConnectionType();
182     if (StringUtils.isNotEmpty(scmConnection)
183         && "connection".equals(connectionType.toLowerCase(Locale.ENGLISH)))
184     {
185       return scmConnection;
186     }
187 
188     final String scmDeveloper = project.getScm().getDeveloperConnection();
189     if (StringUtils.isNotEmpty(scmDeveloper)
190         && "developerconnection".equals(connectionType
191             .toLowerCase(Locale.ENGLISH)))
192     {
193       return scmDeveloper;
194     }
195 
196     throw new IllegalStateException("SCM Connection is not set.");
197   }
198 
199   /**
200    * Creates the host name by adding the port if present.
201    *
202    * @param repositoryWithHost the host information.
203    * @return the host with port if present.
204    */
205   private String createHostName(
206       final ScmProviderRepositoryWithHost repositoryWithHost)
207   {
208     final String host = repositoryWithHost.getHost();
209     final int port = repositoryWithHost.getPort();
210     if (port > 0)
211     {
212       return host + ":" + port;
213     }
214     return host;
215   }
216 
217   /**
218    * Creates the access information instance to retrieve the change logs from
219    * the SCM.
220    *
221    * @return the SCM access instance.
222    */
223   private ScmAccessInfo createScmAccessInfo()
224   {
225     final ScmAccessInfo accessInfo = new ScmAccessInfo();
226     accessInfo.setDateFormat(scmInfo.getScmDateFormat());
227     accessInfo.setRootDirectory(scmInfo.getBasedir());
228     accessInfo.setFailOnLocalModifications(scmInfo.getScmControl()
229         .isFailOnLocalModifications());
230     accessInfo.setIgnoreDotFilesInBaseDir(scmInfo.getScmControl()
231         .isIgnoreDotFilesInBaseDir());
232     accessInfo.setQueryRangeInDays(scmInfo.getQueryRangeInDays());
233     return accessInfo;
234   }
235 
236   // --- object basics --------------------------------------------------------
237 
238 }