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