View Javadoc
1   package org.apache.maven.plugins.help;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.io.StringWriter;
24  import java.net.InetAddress;
25  import java.net.UnknownHostException;
26  import java.util.ArrayList;
27  import java.util.List;
28  import java.util.Properties;
29  
30  import org.apache.maven.plugin.MojoExecutionException;
31  import org.apache.maven.plugins.annotations.Mojo;
32  import org.apache.maven.plugins.annotations.Parameter;
33  import org.apache.maven.settings.Profile;
34  import org.apache.maven.settings.Proxy;
35  import org.apache.maven.settings.Server;
36  import org.apache.maven.settings.Settings;
37  import org.apache.maven.settings.SettingsUtils;
38  import org.apache.maven.settings.io.xpp3.SettingsXpp3Writer;
39  import org.codehaus.plexus.util.StringUtils;
40  import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
41  import org.codehaus.plexus.util.xml.XMLWriter;
42  import org.codehaus.plexus.util.xml.XmlWriterUtil;
43  
44  /**
45   * Displays the calculated settings as XML for this project, given any profile enhancement and the inheritance
46   * of the global settings into the user-level settings.
47   *
48   * @version $Id$
49   * @since 2.0
50   */
51  @Mojo( name = "effective-settings", requiresProject = false )
52  public class EffectiveSettingsMojo
53      extends AbstractEffectiveMojo
54  {
55      // ----------------------------------------------------------------------
56      // Mojo parameters
57      // ----------------------------------------------------------------------
58  
59      /**
60       * The system settings for Maven. This is the instance resulting from
61       * merging global and user-level settings files.
62       */
63      @Parameter( defaultValue = "${settings}", readonly = true, required = true )
64      private Settings settings;
65  
66      /**
67       * For security reasons, all passwords are hidden by default. Set this to <code>true</code> to show all passwords.
68       *
69       * @since 2.1
70       */
71      @Parameter( property = "showPasswords", defaultValue = "false" )
72      private boolean showPasswords;
73  
74      // ----------------------------------------------------------------------
75      // Public methods
76      // ----------------------------------------------------------------------
77  
78      /** {@inheritDoc} */
79      public void execute()
80          throws MojoExecutionException
81      {
82          Settings copySettings;
83          if ( showPasswords )
84          {
85              copySettings = settings;
86          }
87          else
88          {
89              copySettings = copySettings( settings );
90              hidePasswords( copySettings );
91          }
92  
93          StringWriter w = new StringWriter();
94          String encoding = output != null ? copySettings.getModelEncoding()
95                                  : System.getProperty( "file.encoding" );
96          XMLWriter writer =
97              new PrettyPrintXMLWriter( w, StringUtils.repeat( " ", XmlWriterUtil.DEFAULT_INDENTATION_SIZE ),
98                                        encoding, null );
99  
100         writeHeader( writer );
101 
102         writeEffectiveSettings( copySettings, writer );
103 
104         String effectiveSettings = prettyFormat( w.toString(), encoding, false );
105 
106         if ( output != null )
107         {
108             try
109             {
110                 writeXmlFile( output, effectiveSettings );
111             }
112             catch ( IOException e )
113             {
114                 throw new MojoExecutionException( "Cannot write effective-settings to output: " + output, e );
115             }
116 
117             getLog().info( "Effective-settings written to: " + output );
118         }
119         else
120         {
121             StringBuilder message = new StringBuilder();
122 
123             message.append( LS ).append( "Effective user-specific configuration settings:" ).append( LS ).append( LS );
124             message.append( effectiveSettings );
125             message.append( LS );
126 
127             getLog().info( message.toString() );
128         }
129     }
130 
131     // ----------------------------------------------------------------------
132     // Private methods
133     // ----------------------------------------------------------------------
134 
135     /**
136      * Hide proxy and server passwords.
137      *
138      * @param aSettings not null
139      */
140     private static void hidePasswords( Settings aSettings )
141     {
142         List<Proxy> proxies = aSettings.getProxies();
143         for ( Proxy proxy : proxies )
144         {
145             if ( StringUtils.isNotEmpty( proxy.getPassword() ) )
146             {
147                 proxy.setPassword( "***" );
148             }
149         }
150 
151         List<Server> servers = aSettings.getServers();
152         for ( Server server : servers )
153         {
154             // Password
155             if ( StringUtils.isNotEmpty( server.getPassword() ) )
156             {
157                 server.setPassword( "***" );
158             }
159             // Passphrase
160             if ( StringUtils.isNotEmpty( server.getPassphrase() ) )
161             {
162                 server.setPassphrase( "***" );
163             }
164         }
165     }
166 
167     /**
168      * @param settings could be {@code null}
169      * @return a new instance of settings or {@code null} if settings was {@code null}.
170      */
171     private static Settings copySettings( Settings settings )
172     {
173         if ( settings == null )
174         {
175             return null;
176         }
177 
178         // Not a deep copy in M2.2.1 !!!
179         Settings clone = SettingsUtils.copySettings( settings );
180 
181         List<Server> clonedServers = new ArrayList<Server>( settings.getServers().size() );
182         for ( Server server : settings.getServers() )
183         {
184             Server clonedServer = new Server();
185             clonedServer.setConfiguration( server.getConfiguration() );
186             clonedServer.setDirectoryPermissions( server.getDirectoryPermissions() );
187             clonedServer.setFilePermissions( server.getFilePermissions() );
188             clonedServer.setId( server.getId() );
189             clonedServer.setPassphrase( server.getPassphrase() );
190             clonedServer.setPassword( server.getPassword() );
191             clonedServer.setPrivateKey( server.getPrivateKey() );
192             clonedServer.setSourceLevel( server.getSourceLevel() );
193             clonedServer.setUsername( server.getUsername() );
194 
195             clonedServers.add( clonedServer );
196         }
197         clone.setServers( clonedServers );
198 
199         List<Proxy> clonedProxies = new ArrayList<Proxy>( settings.getProxies().size() );
200         for ( Proxy proxy : settings.getProxies() )
201         {
202             Proxy clonedProxy = new Proxy();
203             clonedProxy.setActive( proxy.isActive() );
204             clonedProxy.setHost( proxy.getHost() );
205             clonedProxy.setId( proxy.getId() );
206             clonedProxy.setNonProxyHosts( proxy.getNonProxyHosts() );
207             clonedProxy.setPassword( proxy.getPassword() );
208             clonedProxy.setPort( proxy.getPort() );
209             clonedProxy.setProtocol( proxy.getProtocol() );
210             clonedProxy.setSourceLevel( proxy.getSourceLevel() );
211             clonedProxy.setUsername( proxy.getUsername() );
212 
213             clonedProxies.add( clonedProxy );
214         }
215         clone.setProxies( clonedProxies );
216 
217         return clone;
218     }
219 
220     /**
221      * Method for writing the effective settings informations.
222      *
223      * @param settings the settings, not null.
224      * @param writer the XML writer used, not null.
225      * @throws MojoExecutionException if any
226      */
227     private static void writeEffectiveSettings( Settings settings, XMLWriter writer )
228         throws MojoExecutionException
229     {
230         cleanSettings( settings );
231 
232         StringWriter sWriter = new StringWriter();
233         SettingsXpp3Writer settingsWriter = new SettingsXpp3Writer();
234         try
235         {
236             settingsWriter.write( sWriter, settings );
237         }
238         catch ( IOException e )
239         {
240             throw new MojoExecutionException( "Cannot serialize Settings to XML.", e );
241         }
242 
243         // This removes the XML declaration written by MavenXpp3Writer
244         String effectiveSettings = prettyFormat( sWriter.toString(), null, true );
245 
246         writeComment( writer, "Effective Settings for '" + getUserName() + "' on '" + getHostName() + "'" );
247 
248         writer.writeMarkup( effectiveSettings );
249     }
250 
251     /**
252      * Apply some logic to clean the model before writing it.
253      *
254      * @param settings not null
255      */
256     private static void cleanSettings( Settings settings )
257     {
258         List<Profile> profiles = settings.getProfiles();
259         for ( Profile profile : profiles )
260         {
261             Properties properties = new SortedProperties();
262             properties.putAll( profile.getProperties() );
263             profile.setProperties( properties );
264         }
265     }
266 
267     /**
268      * @return the current host name or <code>unknown</code> if error
269      * @see InetAddress#getLocalHost()
270      */
271     private static String getHostName()
272     {
273         try
274         {
275             return InetAddress.getLocalHost().getHostName();
276         }
277         catch ( UnknownHostException e )
278         {
279             return "unknown";
280         }
281     }
282 
283     /**
284      * @return the user name or <code>unknown</code> if <code>user.name</code> is not a system property.
285      */
286     private static String getUserName()
287     {
288         String userName = System.getProperty( "user.name" );
289         if ( StringUtils.isEmpty( userName ) )
290         {
291             return "unknown";
292         }
293 
294         return userName;
295     }
296 }