001    package org.apache.maven.project;
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.util.ArrayList;
024    import java.util.Arrays;
025    import java.util.List;
026    import java.util.Properties;
027    
028    import org.apache.maven.artifact.Artifact;
029    import org.apache.maven.artifact.InvalidRepositoryException;
030    import org.apache.maven.artifact.repository.ArtifactRepository;
031    import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
032    import org.apache.maven.artifact.resolver.ArtifactResolutionException;
033    import org.apache.maven.execution.MavenExecutionRequest;
034    import org.apache.maven.execution.MavenSession;
035    import org.apache.maven.model.Repository;
036    import org.apache.maven.model.building.ModelBuildingException;
037    import org.apache.maven.model.building.ModelBuildingRequest;
038    import org.apache.maven.model.building.ModelSource;
039    import org.apache.maven.model.building.UrlModelSource;
040    import org.apache.maven.plugin.LegacySupport;
041    import org.apache.maven.profiles.ProfileManager;
042    import org.apache.maven.properties.internal.EnvironmentUtils;
043    import org.apache.maven.repository.RepositorySystem;
044    import org.apache.maven.wagon.events.TransferListener;
045    import org.codehaus.plexus.component.annotations.Component;
046    import org.codehaus.plexus.component.annotations.Requirement;
047    
048    /**
049     */
050    @Component( role = MavenProjectBuilder.class )
051    @Deprecated
052    public class DefaultMavenProjectBuilder
053        implements MavenProjectBuilder
054    {
055    
056        @Requirement
057        private ProjectBuilder projectBuilder;
058    
059        @Requirement
060        private RepositorySystem repositorySystem;
061    
062        @Requirement
063        private LegacySupport legacySupport;
064    
065        // ----------------------------------------------------------------------
066        // MavenProjectBuilder Implementation
067        // ----------------------------------------------------------------------
068    
069        private ProjectBuildingRequest toRequest( ProjectBuilderConfiguration configuration )
070        {
071            DefaultProjectBuildingRequest request = new DefaultProjectBuildingRequest();
072    
073            request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
074            request.setResolveDependencies( false );
075    
076            request.setLocalRepository( configuration.getLocalRepository() );
077            request.setBuildStartTime( configuration.getBuildStartTime() );
078            request.setUserProperties( configuration.getUserProperties() );
079            request.setSystemProperties( configuration.getExecutionProperties() );
080    
081            ProfileManager profileManager = configuration.getGlobalProfileManager();
082            if ( profileManager != null )
083            {
084                request.setActiveProfileIds( profileManager.getExplicitlyActivatedIds() );
085                request.setInactiveProfileIds( profileManager.getExplicitlyDeactivatedIds() );
086            }
087            else
088            {
089                /*
090                 * MNG-4900: Hack to workaround deficiency of legacy API which makes it impossible for plugins to access the
091                 * global profile manager which is required to build a POM like a CLI invocation does. Failure to consider
092                 * the activated profiles can cause repo declarations to be lost which in turn will result in artifact
093                 * resolution failures, in particular when using the enhanced local repo which guards access to local files
094                 * based on the configured remote repos.
095                 */
096                MavenSession session = legacySupport.getSession();
097                if ( session != null )
098                {
099                    MavenExecutionRequest req = session.getRequest();
100                    if ( req != null )
101                    {
102                        request.setActiveProfileIds( req.getActiveProfiles() );
103                        request.setInactiveProfileIds( req.getInactiveProfiles() );
104                    }
105                }
106            }
107    
108            return request;
109        }
110    
111        private ProjectBuildingRequest injectSession( ProjectBuildingRequest request )
112        {
113            MavenSession session = legacySupport.getSession();
114            if ( session != null )
115            {
116                request.setRepositorySession( session.getRepositorySession() );
117                request.setSystemProperties( session.getSystemProperties() );
118                if ( request.getUserProperties().isEmpty() )
119                {
120                    request.setUserProperties( session.getUserProperties() );
121                }
122    
123                MavenExecutionRequest req = session.getRequest();
124                if ( req != null )
125                {
126                    request.setRemoteRepositories( req.getRemoteRepositories() );
127                }
128            }
129            else
130            {
131                Properties props = new Properties();
132                EnvironmentUtils.addEnvVars( props );
133                props.putAll( System.getProperties() );
134                request.setSystemProperties( props );
135            }
136    
137            return request;
138        }
139    
140        @SuppressWarnings( "unchecked" )
141        private List<ArtifactRepository> normalizeToArtifactRepositories( List<?> repositories,
142                                                                          ProjectBuildingRequest request )
143            throws ProjectBuildingException
144        {
145            /*
146             * This provides backward-compat with 2.x that allowed plugins like the maven-remote-resources-plugin:1.0 to
147             * populate the builder configuration with model repositories instead of artifact repositories.
148             */
149    
150            if ( repositories != null )
151            {
152                boolean normalized = false;
153    
154                List<ArtifactRepository> repos = new ArrayList<ArtifactRepository>( repositories.size() );
155    
156                for ( Object repository : repositories )
157                {
158                    if ( repository instanceof Repository )
159                    {
160                        try
161                        {
162                            ArtifactRepository repo = repositorySystem.buildArtifactRepository( (Repository) repository );
163                            repositorySystem.injectMirror( request.getRepositorySession(), Arrays.asList( repo ) );
164                            repositorySystem.injectProxy( request.getRepositorySession(), Arrays.asList( repo ) );
165                            repositorySystem.injectAuthentication( request.getRepositorySession(), Arrays.asList( repo ) );
166                            repos.add( repo );
167                        }
168                        catch ( InvalidRepositoryException e )
169                        {
170                            throw new ProjectBuildingException( "", "Invalid remote repository " + repository, e );
171                        }
172                        normalized = true;
173                    }
174                    else
175                    {
176                        repos.add( (ArtifactRepository) repository );
177                    }
178                }
179    
180                if ( normalized )
181                {
182                    return repos;
183                }
184            }
185    
186            return (List<ArtifactRepository>) repositories;
187        }
188    
189        private ProjectBuildingException transformError( ProjectBuildingException e )
190        {
191            if ( e.getCause() instanceof ModelBuildingException )
192            {
193                return new InvalidProjectModelException( e.getProjectId(), e.getMessage(), e.getPomFile() );
194            }
195    
196            return e;
197        }
198    
199        public MavenProject build( File pom, ProjectBuilderConfiguration configuration )
200            throws ProjectBuildingException
201        {
202            ProjectBuildingRequest request = injectSession( toRequest( configuration ) );
203    
204            try
205            {
206                return projectBuilder.build( pom, request ).getProject();
207            }
208            catch ( ProjectBuildingException e )
209            {
210                throw transformError( e );
211            }
212        }
213    
214        // This is used by the SITE plugin.
215        public MavenProject build( File pom, ArtifactRepository localRepository, ProfileManager profileManager )
216            throws ProjectBuildingException
217        {
218            ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
219            configuration.setLocalRepository( localRepository );
220            configuration.setGlobalProfileManager( profileManager );
221    
222            return build( pom, configuration );
223        }
224    
225        public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
226                                                 ProjectBuilderConfiguration configuration, boolean allowStubModel )
227            throws ProjectBuildingException
228        {
229            ProjectBuildingRequest request = injectSession( toRequest( configuration ) );
230            request.setRemoteRepositories( normalizeToArtifactRepositories( remoteRepositories, request ) );
231            request.setProcessPlugins( false );
232            request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
233    
234            try
235            {
236                return projectBuilder.build( artifact, allowStubModel, request ).getProject();
237            }
238            catch ( ProjectBuildingException e )
239            {
240                throw transformError( e );
241            }
242        }
243    
244        public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
245                                                 ArtifactRepository localRepository, boolean allowStubModel )
246            throws ProjectBuildingException
247        {
248            ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
249            configuration.setLocalRepository( localRepository );
250    
251            return buildFromRepository( artifact, remoteRepositories, configuration, allowStubModel );
252        }
253    
254        public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
255                                                 ArtifactRepository localRepository )
256            throws ProjectBuildingException
257        {
258            return buildFromRepository( artifact, remoteRepositories, localRepository, true );
259        }
260    
261        /**
262         * This is used for pom-less execution like running archetype:generate. I am taking out the profile handling and the
263         * interpolation of the base directory until we spec this out properly.
264         */
265        public MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration configuration )
266            throws ProjectBuildingException
267        {
268            ProjectBuildingRequest request = injectSession( toRequest( configuration ) );
269            request.setProcessPlugins( false );
270            request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
271    
272            ModelSource modelSource = new UrlModelSource( getClass().getResource( "standalone.xml" ) );
273    
274            MavenProject project = projectBuilder.build( modelSource, request ).getProject();
275            project.setExecutionRoot( true );
276            return project;
277        }
278    
279        public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository )
280            throws ProjectBuildingException
281        {
282            return buildStandaloneSuperProject( localRepository, null );
283        }
284    
285        public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository, ProfileManager profileManager )
286            throws ProjectBuildingException
287        {
288            ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
289            configuration.setLocalRepository( localRepository );
290            configuration.setGlobalProfileManager( profileManager );
291    
292            return buildStandaloneSuperProject( configuration );
293        }
294    
295        public MavenProject buildWithDependencies( File pom, ArtifactRepository localRepository,
296                                                   ProfileManager profileManager, TransferListener transferListener )
297            throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
298        {
299            ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
300            configuration.setLocalRepository( localRepository );
301            configuration.setGlobalProfileManager( profileManager );
302    
303            ProjectBuildingRequest request = injectSession( toRequest( configuration ) );
304    
305            request.setResolveDependencies( true );
306    
307            try
308            {
309                return projectBuilder.build( pom, request ).getProject();
310            }
311            catch ( ProjectBuildingException e )
312            {
313                throw transformError( e );
314            }
315        }
316    
317        public MavenProject buildWithDependencies( File pom, ArtifactRepository localRepository,
318                                                   ProfileManager profileManager )
319            throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
320        {
321            return buildWithDependencies( pom, localRepository, profileManager, null );
322        }
323    
324    }