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   * @since 2.0
49   */
50  @Mojo( name = "effective-settings", requiresProject = false )
51  public class EffectiveSettingsMojo
52      extends AbstractEffectiveMojo
53  {
54      // ----------------------------------------------------------------------
55      // Mojo parameters
56      // ----------------------------------------------------------------------
57  
58      /**
59       * The system settings for Maven. This is the instance resulting from
60       * merging global and user-level settings files.
61       */
62      @Parameter( defaultValue = "${settings}", readonly = true, required = true )
63      private Settings settings;
64  
65      /**
66       * For security reasons, all passwords are hidden by default. Set this to <code>true</code> to show all passwords.
67       *
68       * @since 2.1
69       */
70      @Parameter( property = "showPasswords", defaultValue = "false" )
71      private boolean showPasswords;
72  
73      // ----------------------------------------------------------------------
74      // Public methods
75      // ----------------------------------------------------------------------
76  
77      /** {@inheritDoc} */
78      public void execute()
79          throws MojoExecutionException
80      {
81          Settings copySettings;
82          if ( showPasswords )
83          {
84              copySettings = settings;
85          }
86          else
87          {
88              copySettings = copySettings( settings );
89              if ( copySettings != null )
90              {
91                  hidePasswords( copySettings );
92              }
93          }
94  
95          StringWriter w = new StringWriter();
96          String encoding = output != null && copySettings != null ? copySettings.getModelEncoding()
97                                  : System.getProperty( "file.encoding" );
98          XMLWriter writer =
99              new PrettyPrintXMLWriter( w, StringUtils.repeat( " ", XmlWriterUtil.DEFAULT_INDENTATION_SIZE ),
100                                       encoding, null );
101 
102         writeHeader( writer );
103 
104         writeEffectiveSettings( copySettings, writer );
105 
106         String effectiveSettings = prettyFormat( w.toString(), encoding, false );
107 
108         if ( output != null )
109         {
110             try
111             {
112                 writeXmlFile( output, effectiveSettings );
113             }
114             catch ( IOException e )
115             {
116                 throw new MojoExecutionException( "Cannot write effective-settings to output: " + output, e );
117             }
118 
119             getLog().info( "Effective-settings written to: " + output );
120         }
121         else
122         {
123             getLog().info( LS + "Effective user-specific configuration settings:" + LS + LS + effectiveSettings + LS );
124         }
125     }
126 
127     // ----------------------------------------------------------------------
128     // Private methods
129     // ----------------------------------------------------------------------
130 
131     /**
132      * Hide proxy and server passwords.
133      *
134      * @param aSettings not null
135      */
136     private static void hidePasswords( Settings aSettings )
137     {
138         List<Proxy> proxies = aSettings.getProxies();
139         for ( Proxy proxy : proxies )
140         {
141             if ( StringUtils.isNotEmpty( proxy.getPassword() ) )
142             {
143                 proxy.setPassword( "***" );
144             }
145         }
146 
147         List<Server> servers = aSettings.getServers();
148         for ( Server server : servers )
149         {
150             // Password
151             if ( StringUtils.isNotEmpty( server.getPassword() ) )
152             {
153                 server.setPassword( "***" );
154             }
155             // Passphrase
156             if ( StringUtils.isNotEmpty( server.getPassphrase() ) )
157             {
158                 server.setPassphrase( "***" );
159             }
160         }
161     }
162 
163     /**
164      * @param settings could be {@code null}
165      * @return a new instance of settings or {@code null} if settings was {@code null}.
166      */
167     private static Settings copySettings( Settings settings )
168     {
169         if ( settings == null )
170         {
171             return null;
172         }
173 
174         // Not a deep copy in M2.2.1 !!!
175         Settings clone = SettingsUtils.copySettings( settings );
176 
177         List<Server> clonedServers = new ArrayList<>( settings.getServers().size() );
178         for ( Server server : settings.getServers() )
179         {
180             Server clonedServer = new Server();
181             clonedServer.setConfiguration( server.getConfiguration() );
182             clonedServer.setDirectoryPermissions( server.getDirectoryPermissions() );
183             clonedServer.setFilePermissions( server.getFilePermissions() );
184             clonedServer.setId( server.getId() );
185             clonedServer.setPassphrase( server.getPassphrase() );
186             clonedServer.setPassword( server.getPassword() );
187             clonedServer.setPrivateKey( server.getPrivateKey() );
188             clonedServer.setSourceLevel( server.getSourceLevel() );
189             clonedServer.setUsername( server.getUsername() );
190 
191             clonedServers.add( clonedServer );
192         }
193         clone.setServers( clonedServers );
194 
195         List<Proxy> clonedProxies = new ArrayList<>( settings.getProxies().size() );
196         for ( Proxy proxy : settings.getProxies() )
197         {
198             Proxy clonedProxy = new Proxy();
199             clonedProxy.setActive( proxy.isActive() );
200             clonedProxy.setHost( proxy.getHost() );
201             clonedProxy.setId( proxy.getId() );
202             clonedProxy.setNonProxyHosts( proxy.getNonProxyHosts() );
203             clonedProxy.setPassword( proxy.getPassword() );
204             clonedProxy.setPort( proxy.getPort() );
205             clonedProxy.setProtocol( proxy.getProtocol() );
206             clonedProxy.setSourceLevel( proxy.getSourceLevel() );
207             clonedProxy.setUsername( proxy.getUsername() );
208 
209             clonedProxies.add( clonedProxy );
210         }
211         clone.setProxies( clonedProxies );
212 
213         return clone;
214     }
215 
216     /**
217      * Method for writing the effective settings informations.
218      *
219      * @param settings the settings, not null.
220      * @param writer the XML writer used, not null.
221      * @throws MojoExecutionException if any
222      */
223     private static void writeEffectiveSettings( Settings settings, XMLWriter writer )
224         throws MojoExecutionException
225     {
226         cleanSettings( settings );
227 
228         StringWriter sWriter = new StringWriter();
229         SettingsXpp3Writer settingsWriter = new SettingsXpp3Writer();
230         try
231         {
232             settingsWriter.write( sWriter, settings );
233         }
234         catch ( IOException e )
235         {
236             throw new MojoExecutionException( "Cannot serialize Settings to XML.", e );
237         }
238 
239         // This removes the XML declaration written by MavenXpp3Writer
240         String effectiveSettings = prettyFormat( sWriter.toString(), null, true );
241 
242         writeComment( writer, "Effective Settings for '" + getUserName() + "' on '" + getHostName() + "'" );
243 
244         writer.writeMarkup( effectiveSettings );
245     }
246 
247     /**
248      * Apply some logic to clean the model before writing it.
249      *
250      * @param settings not null
251      */
252     private static void cleanSettings( Settings settings )
253     {
254         List<Profile> profiles = settings.getProfiles();
255         for ( Profile profile : profiles )
256         {
257             Properties properties = new SortedProperties();
258             properties.putAll( profile.getProperties() );
259             profile.setProperties( properties );
260         }
261     }
262 
263     /**
264      * @return the current host name or <code>unknown</code> if error
265      * @see InetAddress#getLocalHost()
266      */
267     private static String getHostName()
268     {
269         try
270         {
271             return InetAddress.getLocalHost().getHostName();
272         }
273         catch ( UnknownHostException e )
274         {
275             return "unknown";
276         }
277     }
278 
279     /**
280      * @return the user name or <code>unknown</code> if <code>user.name</code> is not a system property.
281      */
282     private static String getUserName()
283     {
284         String userName = System.getProperty( "user.name" );
285         if ( StringUtils.isEmpty( userName ) )
286         {
287             return "unknown";
288         }
289 
290         return userName;
291     }
292 }