001package org.apache.maven.settings;
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.IOException;
024
025import org.apache.maven.execution.MavenExecutionRequest;
026import org.apache.maven.properties.internal.SystemProperties;
027import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
028import org.apache.maven.settings.building.SettingsBuilder;
029import org.apache.maven.settings.building.SettingsBuildingException;
030import org.apache.maven.settings.building.SettingsBuildingRequest;
031import org.codehaus.plexus.component.annotations.Component;
032import org.codehaus.plexus.component.annotations.Requirement;
033import org.codehaus.plexus.logging.AbstractLogEnabled;
034import org.codehaus.plexus.util.StringUtils;
035import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
036
037/**
038 * @author jdcasey
039 */
040@Component( role = MavenSettingsBuilder.class )
041public class DefaultMavenSettingsBuilder
042    extends AbstractLogEnabled
043    implements MavenSettingsBuilder
044{
045
046    @Requirement
047    private SettingsBuilder settingsBuilder;
048
049    public Settings buildSettings()
050        throws IOException, XmlPullParserException
051    {
052        File userSettingsFile =
053            getFile( "${user.home}/.m2/settings.xml", "user.home",
054                     MavenSettingsBuilder.ALT_USER_SETTINGS_XML_LOCATION );
055
056        return buildSettings( userSettingsFile );
057    }
058
059    public Settings buildSettings( boolean useCachedSettings )
060        throws IOException, XmlPullParserException
061    {
062        return buildSettings();
063    }
064
065    public Settings buildSettings( File userSettingsFile )
066        throws IOException, XmlPullParserException
067    {
068        File globalSettingsFile =
069            getFile( "${maven.home}/conf/settings.xml", "maven.home",
070                     MavenSettingsBuilder.ALT_GLOBAL_SETTINGS_XML_LOCATION );
071
072        SettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
073        request.setUserSettingsFile( userSettingsFile );
074        request.setGlobalSettingsFile( globalSettingsFile );
075        request.setSystemProperties( SystemProperties.getSystemProperties() );
076        return build( request );
077    }
078
079    public Settings buildSettings( File userSettingsFile, boolean useCachedSettings )
080        throws IOException, XmlPullParserException
081    {
082        return buildSettings( userSettingsFile );
083    }
084
085    private Settings build( SettingsBuildingRequest request )
086        throws IOException, XmlPullParserException
087    {
088        try
089        {
090            return settingsBuilder.build( request ).getEffectiveSettings();
091        }
092        catch ( SettingsBuildingException e )
093        {
094            throw (IOException) new IOException( e.getMessage() ).initCause( e );
095        }
096    }
097
098    /** @since 2.1 */
099    public Settings buildSettings( MavenExecutionRequest request )
100        throws IOException, XmlPullParserException
101    {
102        SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
103        settingsRequest.setUserSettingsFile( request.getUserSettingsFile() );
104        settingsRequest.setGlobalSettingsFile( request.getGlobalSettingsFile() );
105        settingsRequest.setUserProperties( request.getUserProperties() );
106        settingsRequest.setSystemProperties( request.getSystemProperties() );
107
108        return build( settingsRequest );
109    }
110
111    private File getFile( String pathPattern, String basedirSysProp, String altLocationSysProp )
112    {
113        // -------------------------------------------------------------------------------------
114        // Alright, here's the justification for all the regexp wizardry below...
115        //
116        // Continuum and other server-like apps may need to locate the user-level and
117        // global-level settings somewhere other than ${user.home} and ${maven.home},
118        // respectively. Using a simple replacement of these patterns will allow them
119        // to specify the absolute path to these files in a customized components.xml
120        // file. Ideally, we'd do full pattern-evaluation against the sysprops, but this
121        // is a first step. There are several replacements below, in order to normalize
122        // the path character before we operate on the string as a regex input, and
123        // in order to avoid surprises with the File construction...
124        // -------------------------------------------------------------------------------------
125
126        String path = System.getProperty( altLocationSysProp );
127
128        if ( StringUtils.isEmpty( path ) )
129        {
130            // TODO: This replacing shouldn't be necessary as user.home should be in the
131            // context of the container and thus the value would be interpolated by Plexus
132            String basedir = System.getProperty( basedirSysProp );
133            if ( basedir == null )
134            {
135                basedir = System.getProperty( "user.dir" );
136            }
137
138            basedir = basedir.replaceAll( "\\\\", "/" );
139            basedir = basedir.replaceAll( "\\$", "\\\\\\$" );
140
141            path = pathPattern.replaceAll( "\\$\\{" + basedirSysProp + "\\}", basedir );
142            path = path.replaceAll( "\\\\", "/" );
143            // ---------------------------------------------------------------------------------
144            // I'm not sure if this last regexp was really intended to disallow the usage of
145            // network paths as user.home directory. Unfortunately it did. I removed it and
146            // have not detected any problems yet.
147            // ---------------------------------------------------------------------------------
148            // path = path.replaceAll( "//", "/" );
149
150            return new File( path ).getAbsoluteFile();
151        }
152        else
153        {
154            return new File( path ).getAbsoluteFile();
155        }
156    }
157
158}