001    package 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    
022    import java.io.File;
023    import java.io.IOException;
024    
025    import org.apache.maven.execution.MavenExecutionRequest;
026    import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
027    import org.apache.maven.settings.building.SettingsBuilder;
028    import org.apache.maven.settings.building.SettingsBuildingException;
029    import org.apache.maven.settings.building.SettingsBuildingRequest;
030    import org.codehaus.plexus.component.annotations.Component;
031    import org.codehaus.plexus.component.annotations.Requirement;
032    import org.codehaus.plexus.logging.AbstractLogEnabled;
033    import org.codehaus.plexus.util.StringUtils;
034    import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
035    
036    /**
037     * @author jdcasey
038     */
039    @Component( role = MavenSettingsBuilder.class )
040    public 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    }