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