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.SettingsDecrypter;
046import org.codehaus.plexus.component.annotations.Component;
047import org.codehaus.plexus.component.annotations.Requirement;
048import org.slf4j.Logger;
049
050@Component( role = ConfigurationProcessor.class, hint = SettingsXmlConfigurationProcessor.HINT )
051public class SettingsXmlConfigurationProcessor
052    implements ConfigurationProcessor
053{
054    public static final String HINT = "settings";
055
056    public static final String USER_HOME = System.getProperty( "user.home" );
057
058    public static final File USER_MAVEN_CONFIGURATION_HOME = new File( USER_HOME, ".m2" );
059
060    public static final File DEFAULT_USER_SETTINGS_FILE = new File( USER_MAVEN_CONFIGURATION_HOME, "settings.xml" );
061
062    public static final File DEFAULT_GLOBAL_SETTINGS_FILE = new File( System.getProperty( "maven.home", System
063        .getProperty( "user.dir", "" ) ), "conf/settings.xml" );
064
065    @Requirement
066    private Logger logger;
067
068    @Requirement
069    private SettingsBuilder settingsBuilder;
070
071    @Requirement
072    private SettingsDecrypter settingsDecrypter;
073
074    @Override
075    public void process( CliRequest cliRequest )
076        throws Exception
077    {
078        CommandLine commandLine = cliRequest.getCommandLine();
079        String workingDirectory = cliRequest.getWorkingDirectory();
080        MavenExecutionRequest request = cliRequest.getRequest();
081
082        File userSettingsFile;
083
084        if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
085        {
086            userSettingsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS ) );
087            userSettingsFile = resolveFile( userSettingsFile, workingDirectory );
088
089            if ( !userSettingsFile.isFile() )
090            {
091                throw new FileNotFoundException( "The specified user settings file does not exist: "
092                    + userSettingsFile );
093            }
094        }
095        else
096        {
097            userSettingsFile = DEFAULT_USER_SETTINGS_FILE;
098        }
099
100        File globalSettingsFile;
101
102        if ( commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) )
103        {
104            globalSettingsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) );
105            globalSettingsFile = resolveFile( globalSettingsFile, workingDirectory );
106
107            if ( !globalSettingsFile.isFile() )
108            {
109                throw new FileNotFoundException( "The specified global settings file does not exist: "
110                    + globalSettingsFile );
111            }
112        }
113        else
114        {
115            globalSettingsFile = DEFAULT_GLOBAL_SETTINGS_FILE;
116        }
117
118        request.setGlobalSettingsFile( globalSettingsFile );
119        request.setUserSettingsFile( userSettingsFile );
120
121        SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
122        settingsRequest.setGlobalSettingsFile( globalSettingsFile );
123        settingsRequest.setUserSettingsFile( userSettingsFile );
124        settingsRequest.setSystemProperties( cliRequest.getSystemProperties() );
125        settingsRequest.setUserProperties( cliRequest.getUserProperties() );
126
127        if ( request.getEventSpyDispatcher() != null )
128        {
129            request.getEventSpyDispatcher().onEvent( settingsRequest );
130        }
131
132        logger.debug( "Reading global settings from "
133            + getLocation( settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile() ) );
134        logger.debug( "Reading user settings from "
135            + getLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
136
137        SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
138
139        if ( request.getEventSpyDispatcher() != null )
140        {
141            request.getEventSpyDispatcher().onEvent( settingsResult );
142        }
143
144        populateFromSettings( request, settingsResult.getEffectiveSettings() );
145
146        if ( !settingsResult.getProblems().isEmpty() && logger.isWarnEnabled() )
147        {
148            logger.warn( "" );
149            logger.warn( "Some problems were encountered while building the effective settings" );
150
151            for ( SettingsProblem problem : settingsResult.getProblems() )
152            {
153                logger.warn( problem.getMessage() + " @ " + problem.getLocation() );
154            }
155            logger.warn( "" );
156        }
157    }
158
159    private MavenExecutionRequest populateFromSettings( MavenExecutionRequest request, Settings settings )
160        throws MavenExecutionRequestPopulationException
161    {
162        if ( settings == null )
163        {
164            return request;
165        }
166
167        request.setOffline( settings.isOffline() );
168
169        request.setInteractiveMode( settings.isInteractiveMode() );
170
171        request.setPluginGroups( settings.getPluginGroups() );
172
173        request.setLocalRepositoryPath( settings.getLocalRepository() );
174
175        for ( Server server : settings.getServers() )
176        {
177            server = server.clone();
178
179            request.addServer( server );
180        }
181
182        //  <proxies>
183        //    <proxy>
184        //      <active>true</active>
185        //      <protocol>http</protocol>
186        //      <host>proxy.somewhere.com</host>
187        //      <port>8080</port>
188        //      <username>proxyuser</username>
189        //      <password>somepassword</password>
190        //      <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
191        //    </proxy>
192        //  </proxies>
193
194        for ( Proxy proxy : settings.getProxies() )
195        {
196            if ( !proxy.isActive() )
197            {
198                continue;
199            }
200
201            proxy = proxy.clone();
202
203            request.addProxy( proxy );
204        }
205
206        // <mirrors>
207        //   <mirror>
208        //     <id>nexus</id>
209        //     <mirrorOf>*</mirrorOf>
210        //     <url>http://repository.sonatype.org/content/groups/public</url>
211        //   </mirror>
212        // </mirrors>
213
214        for ( Mirror mirror : settings.getMirrors() )
215        {
216            mirror = mirror.clone();
217
218            request.addMirror( mirror );
219        }
220
221        request.setActiveProfiles( settings.getActiveProfiles() );
222
223        for ( org.apache.maven.settings.Profile rawProfile : settings.getProfiles() )
224        {
225            request.addProfile( SettingsUtils.convertFromSettingsProfile( rawProfile ) );
226
227            if ( settings.getActiveProfiles().contains( rawProfile.getId() ) )
228            {
229                List<Repository> remoteRepositories = rawProfile.getRepositories();
230                for ( Repository remoteRepository : remoteRepositories )
231                {
232                    try
233                    {
234                        request.addRemoteRepository( 
235                            MavenRepositorySystem.buildArtifactRepository( remoteRepository ) );
236                    }
237                    catch ( InvalidRepositoryException e )
238                    {
239                        // do nothing for now
240                    }
241                }
242                
243                List<Repository> pluginRepositories = rawProfile.getPluginRepositories();
244                for ( Repository pluginRepository : pluginRepositories )
245                {
246                    try
247                    {
248                        request.addPluginArtifactRepository( 
249                            MavenRepositorySystem.buildArtifactRepository( pluginRepository ) );
250                    }
251                    catch ( InvalidRepositoryException e )
252                    {
253                        // do nothing for now
254                    }
255                }                
256            }
257        }
258        return request;
259    }
260
261    private Object getLocation( Source source, File defaultLocation )
262    {
263        if ( source != null )
264        {
265            return source.getLocation();
266        }
267        return defaultLocation;
268    }
269
270    static File resolveFile( File file, String workingDirectory )
271    {
272        if ( file == null )
273        {
274            return null;
275        }
276        else if ( file.isAbsolute() )
277        {
278            return file;
279        }
280        else if ( file.getPath().startsWith( File.separator ) )
281        {
282            // drive-relative Windows path
283            return file.getAbsoluteFile();
284        }
285        else
286        {
287            return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
288        }
289    }
290}