001package org.apache.maven.cli.configuration;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.io.FileNotFoundException;
024import java.util.List;
025
026import org.apache.commons.cli.CommandLine;
027import org.apache.maven.artifact.InvalidRepositoryException;
028import org.apache.maven.bridge.MavenRepositorySystem;
029import org.apache.maven.building.Source;
030import org.apache.maven.cli.CLIManager;
031import org.apache.maven.cli.CliRequest;
032import org.apache.maven.execution.MavenExecutionRequest;
033import org.apache.maven.execution.MavenExecutionRequestPopulationException;
034import org.apache.maven.settings.Mirror;
035import org.apache.maven.settings.Proxy;
036import org.apache.maven.settings.Repository;
037import org.apache.maven.settings.Server;
038import org.apache.maven.settings.Settings;
039import org.apache.maven.settings.SettingsUtils;
040import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
041import org.apache.maven.settings.building.SettingsBuilder;
042import org.apache.maven.settings.building.SettingsBuildingRequest;
043import org.apache.maven.settings.building.SettingsBuildingResult;
044import org.apache.maven.settings.building.SettingsProblem;
045import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
046import org.apache.maven.settings.crypto.SettingsDecrypter;
047import org.apache.maven.settings.crypto.SettingsDecryptionResult;
048import org.codehaus.plexus.component.annotations.Component;
049import org.codehaus.plexus.component.annotations.Requirement;
050import org.slf4j.Logger;
051
052@Component( role = ConfigurationProcessor.class, hint = SettingsXmlConfigurationProcessor.HINT )
053public class SettingsXmlConfigurationProcessor
054    implements ConfigurationProcessor
055{
056    public static final String HINT = "settings";
057
058    public static final String USER_HOME = System.getProperty( "user.home" );
059
060    public static final File USER_MAVEN_CONFIGURATION_HOME = new File( USER_HOME, ".m2" );
061
062    public static final File DEFAULT_USER_SETTINGS_FILE = new File( USER_MAVEN_CONFIGURATION_HOME, "settings.xml" );
063
064    public static final File DEFAULT_GLOBAL_SETTINGS_FILE = new File( System.getProperty( "maven.home", System
065        .getProperty( "user.dir", "" ) ), "conf/settings.xml" );
066
067    @Requirement
068    private Logger logger;
069
070    @Requirement
071    private SettingsBuilder settingsBuilder;
072
073    @Requirement
074    private SettingsDecrypter settingsDecrypter;
075
076    @Override
077    public void process( CliRequest cliRequest )
078        throws Exception
079    {
080        CommandLine commandLine = cliRequest.getCommandLine();
081        String workingDirectory = cliRequest.getWorkingDirectory();
082        MavenExecutionRequest request = cliRequest.getRequest();
083
084        File userSettingsFile;
085
086        if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
087        {
088            userSettingsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS ) );
089            userSettingsFile = resolveFile( userSettingsFile, workingDirectory );
090
091            if ( !userSettingsFile.isFile() )
092            {
093                throw new FileNotFoundException( "The specified user settings file does not exist: "
094                    + userSettingsFile );
095            }
096        }
097        else
098        {
099            userSettingsFile = DEFAULT_USER_SETTINGS_FILE;
100        }
101
102        File globalSettingsFile;
103
104        if ( commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) )
105        {
106            globalSettingsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) );
107            globalSettingsFile = resolveFile( globalSettingsFile, workingDirectory );
108
109            if ( !globalSettingsFile.isFile() )
110            {
111                throw new FileNotFoundException( "The specified global settings file does not exist: "
112                    + globalSettingsFile );
113            }
114        }
115        else
116        {
117            globalSettingsFile = DEFAULT_GLOBAL_SETTINGS_FILE;
118        }
119
120        request.setGlobalSettingsFile( globalSettingsFile );
121        request.setUserSettingsFile( userSettingsFile );
122
123        SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
124        settingsRequest.setGlobalSettingsFile( globalSettingsFile );
125        settingsRequest.setUserSettingsFile( userSettingsFile );
126        settingsRequest.setSystemProperties( cliRequest.getSystemProperties() );
127        settingsRequest.setUserProperties( cliRequest.getUserProperties() );
128
129        if ( request.getEventSpyDispatcher() != null )
130        {
131            request.getEventSpyDispatcher().onEvent( settingsRequest );
132        }
133
134        logger.debug( "Reading global settings from "
135            + getLocation( settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile() ) );
136        logger.debug( "Reading user settings from "
137            + getLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
138
139        SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
140
141        if ( request.getEventSpyDispatcher() != null )
142        {
143            request.getEventSpyDispatcher().onEvent( settingsResult );
144        }
145
146        populateFromSettings( request, settingsResult.getEffectiveSettings() );
147
148        if ( !settingsResult.getProblems().isEmpty() && logger.isWarnEnabled() )
149        {
150            logger.warn( "" );
151            logger.warn( "Some problems were encountered while building the effective settings" );
152
153            for ( SettingsProblem problem : settingsResult.getProblems() )
154            {
155                logger.warn( problem.getMessage() + " @ " + problem.getLocation() );
156            }
157            logger.warn( "" );
158        }
159
160        DefaultSettingsDecryptionRequest decrypt = new DefaultSettingsDecryptionRequest();
161        decrypt.setProxies( request.getProxies() );
162        decrypt.setServers( request.getServers() );
163        SettingsDecryptionResult decrypted = settingsDecrypter.decrypt( decrypt );
164
165        if ( logger.isDebugEnabled() )
166        {
167            for ( SettingsProblem problem : decrypted.getProblems() )
168            {
169                logger.debug( problem.getMessage(), problem.getException() );
170            }
171        }
172
173        request.setProxies( decrypt.getProxies() );
174        request.setServers( decrypt.getServers() );
175    }
176
177    public MavenExecutionRequest populateFromSettings( MavenExecutionRequest request, Settings settings )
178        throws MavenExecutionRequestPopulationException
179    {
180        if ( settings == null )
181        {
182            return request;
183        }
184
185        request.setOffline( settings.isOffline() );
186
187        request.setInteractiveMode( settings.isInteractiveMode() );
188
189        request.setPluginGroups( settings.getPluginGroups() );
190
191        request.setLocalRepositoryPath( settings.getLocalRepository() );
192
193        for ( Server server : settings.getServers() )
194        {
195            server = server.clone();
196
197            request.addServer( server );
198        }
199
200        //  <proxies>
201        //    <proxy>
202        //      <active>true</active>
203        //      <protocol>http</protocol>
204        //      <host>proxy.somewhere.com</host>
205        //      <port>8080</port>
206        //      <username>proxyuser</username>
207        //      <password>somepassword</password>
208        //      <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
209        //    </proxy>
210        //  </proxies>
211
212        for ( Proxy proxy : settings.getProxies() )
213        {
214            if ( !proxy.isActive() )
215            {
216                continue;
217            }
218
219            proxy = proxy.clone();
220
221            request.addProxy( proxy );
222        }
223
224        // <mirrors>
225        //   <mirror>
226        //     <id>nexus</id>
227        //     <mirrorOf>*</mirrorOf>
228        //     <url>http://repository.sonatype.org/content/groups/public</url>
229        //   </mirror>
230        // </mirrors>
231
232        for ( Mirror mirror : settings.getMirrors() )
233        {
234            mirror = mirror.clone();
235
236            request.addMirror( mirror );
237        }
238
239        request.setActiveProfiles( settings.getActiveProfiles() );
240
241        for ( org.apache.maven.settings.Profile rawProfile : settings.getProfiles() )
242        {
243            request.addProfile( SettingsUtils.convertFromSettingsProfile( rawProfile ) );
244
245            if ( settings.getActiveProfiles().contains( rawProfile.getId() ) )
246            {
247                List<Repository> remoteRepositories = rawProfile.getRepositories();
248                for ( Repository remoteRepository : remoteRepositories )
249                {
250                    try
251                    {
252                        request.addRemoteRepository( 
253                            MavenRepositorySystem.buildArtifactRepository( remoteRepository ) );
254                    }
255                    catch ( InvalidRepositoryException e )
256                    {
257                        // do nothing for now
258                    }
259                }
260                
261                List<Repository> pluginRepositories = rawProfile.getPluginRepositories();
262                for ( Repository pluginRepository : pluginRepositories )
263                {
264                    try
265                    {
266                        request.addPluginArtifactRepository( 
267                            MavenRepositorySystem.buildArtifactRepository( pluginRepository ) );
268                    }
269                    catch ( InvalidRepositoryException e )
270                    {
271                        // do nothing for now
272                    }
273                }                
274            }
275        }
276        return request;
277    }
278
279    private Object getLocation( Source source, File defaultLocation )
280    {
281        if ( source != null )
282        {
283            return source.getLocation();
284        }
285        return defaultLocation;
286    }
287
288    static File resolveFile( File file, String workingDirectory )
289    {
290        if ( file == null )
291        {
292            return null;
293        }
294        else if ( file.isAbsolute() )
295        {
296            return file;
297        }
298        else if ( file.getPath().startsWith( File.separator ) )
299        {
300            // drive-relative Windows path
301            return file.getAbsoluteFile();
302        }
303        else
304        {
305            return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
306        }
307    }
308}