001    package org.apache.maven;
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.util.Collection;
023    import java.util.Collections;
024    import java.util.HashSet;
025    import java.util.Iterator;
026    import java.util.LinkedHashSet;
027    import java.util.Set;
028    
029    import org.apache.maven.artifact.Artifact;
030    import org.apache.maven.artifact.ArtifactUtils;
031    import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
032    import org.apache.maven.artifact.resolver.ArtifactResolutionException;
033    import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
034    import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
035    import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
036    import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
037    import org.apache.maven.artifact.resolver.filter.CumulativeScopeArtifactFilter;
038    import org.apache.maven.execution.MavenSession;
039    import org.apache.maven.project.MavenProject;
040    import org.apache.maven.project.artifact.ProjectArtifact;
041    import org.apache.maven.repository.RepositorySystem;
042    import org.codehaus.plexus.component.annotations.Component;
043    import org.codehaus.plexus.component.annotations.Requirement;
044    
045    @Component( role = ProjectDependenciesResolver.class )
046    public class DefaultProjectDependenciesResolver
047        implements ProjectDependenciesResolver
048    {
049    
050        @Requirement
051        private RepositorySystem repositorySystem;
052    
053        @Requirement
054        private ResolutionErrorHandler resolutionErrorHandler;
055    
056        public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToResolve, MavenSession session )
057            throws ArtifactResolutionException, ArtifactNotFoundException
058        {
059            return resolve( Collections.singleton( project ), scopesToResolve, session );
060        }
061    
062        public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
063                                      Collection<String> scopesToResolve, MavenSession session )
064            throws ArtifactResolutionException, ArtifactNotFoundException
065        {
066            Set<MavenProject> mavenProjects = Collections.singleton( project );
067            return resolveImpl( mavenProjects, scopesToCollect, scopesToResolve, session,
068                                getIgnorableArtifacts( mavenProjects ) );
069        }
070    
071        public Set<Artifact> resolve( Collection<? extends MavenProject> projects, Collection<String> scopesToResolve,
072                                      MavenSession session )
073            throws ArtifactResolutionException, ArtifactNotFoundException
074        {
075            return resolveImpl( projects, null, scopesToResolve, session, getIgnorableArtifacts( projects ) );
076        }
077    
078        public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
079                                      Collection<String> scopesToResolve, MavenSession session,
080                                      Set<Artifact> ignoreableArtifacts )
081            throws ArtifactResolutionException, ArtifactNotFoundException
082        {
083            return resolveImpl( Collections.singleton( project ), scopesToCollect, scopesToResolve, session,
084                                getIgnorableArtifacts( ignoreableArtifacts ) );
085        }
086    
087    
088        private Set<Artifact> resolveImpl( Collection<? extends MavenProject> projects, Collection<String> scopesToCollect,
089                                           Collection<String> scopesToResolve, MavenSession session,
090                                           Set<String> projectIds )
091            throws ArtifactResolutionException, ArtifactNotFoundException
092        {
093            Set<Artifact> resolved = new LinkedHashSet<Artifact>();
094    
095            if ( projects == null || projects.isEmpty() )
096            {
097                return resolved;
098            }
099    
100            if ( ( scopesToCollect == null || scopesToCollect.isEmpty() )
101                && ( scopesToResolve == null || scopesToResolve.isEmpty() ) )
102            {
103                return resolved;
104            }
105    
106            /*
107    
108            Logic for transitive global exclusions
109    
110            List<String> exclusions = new ArrayList<String>();
111    
112            for ( Dependency d : project.getDependencies() )
113            {
114                if ( d.getExclusions() != null )
115                {
116                    for ( Exclusion e : d.getExclusions() )
117                    {
118                        exclusions.add(  e.getGroupId() + ":" + e.getArtifactId() );
119                    }
120                }
121            }
122    
123            ArtifactFilter scopeFilter = new ScopeArtifactFilter( scope );
124    
125            ArtifactFilter filter;
126    
127            if ( ! exclusions.isEmpty() )
128            {
129                filter = new AndArtifactFilter( Arrays.asList( new ArtifactFilter[]{ new ExcludesArtifactFilter( exclusions ), scopeFilter } ) );
130            }
131            else
132            {
133                filter = scopeFilter;
134            }
135            */
136    
137            CumulativeScopeArtifactFilter resolutionScopeFilter = new CumulativeScopeArtifactFilter( scopesToResolve );
138    
139            CumulativeScopeArtifactFilter collectionScopeFilter = new CumulativeScopeArtifactFilter( scopesToCollect );
140            collectionScopeFilter = new CumulativeScopeArtifactFilter( collectionScopeFilter, resolutionScopeFilter );
141    
142            ArtifactResolutionRequest request =
143                new ArtifactResolutionRequest().setResolveRoot( false ).setResolveTransitively( true ).setCollectionFilter(
144                    collectionScopeFilter ).setResolutionFilter( resolutionScopeFilter ).setLocalRepository(
145                    session.getLocalRepository() ).setOffline( session.isOffline() ).setForceUpdate(
146                    session.getRequest().isUpdateSnapshots() );
147            request.setServers( session.getRequest().getServers() );
148            request.setMirrors( session.getRequest().getMirrors() );
149            request.setProxies( session.getRequest().getProxies() );
150    
151            for ( MavenProject project : projects )
152            {
153                request.setArtifact( new ProjectArtifact( project ) );
154                request.setArtifactDependencies( project.getDependencyArtifacts() );
155                request.setManagedVersionMap( project.getManagedVersionMap() );
156                request.setRemoteRepositories( project.getRemoteArtifactRepositories() );
157    
158                ArtifactResolutionResult result = repositorySystem.resolve( request );
159    
160                try
161                {
162                    resolutionErrorHandler.throwErrors( request, result );
163                }
164                catch ( MultipleArtifactsNotFoundException e )
165                {
166    
167                    Collection<Artifact> missing = new HashSet<Artifact>( e.getMissingArtifacts() );
168    
169                    for ( Iterator<Artifact> it = missing.iterator(); it.hasNext(); )
170                    {
171                        String key = ArtifactUtils.key( it.next() );
172                        if ( projectIds.contains( key ) )
173                        {
174                            it.remove();
175                        }
176                    }
177    
178                    if ( !missing.isEmpty() )
179                    {
180                        throw e;
181                    }
182                }
183    
184                resolved.addAll( result.getArtifacts() );
185            }
186    
187            return resolved;
188        }
189    
190    
191        private Set<String> getIgnorableArtifacts( Collection<? extends MavenProject> projects )
192        {
193            Set<String> projectIds = new HashSet<String>( projects.size() * 2 );
194    
195            for ( MavenProject p : projects )
196            {
197                String key = ArtifactUtils.key( p.getGroupId(), p.getArtifactId(), p.getVersion() );
198                projectIds.add( key );
199            }
200            return projectIds;
201        }
202    
203        private Set<String> getIgnorableArtifacts( Iterable<Artifact> artifactIterable )
204        {
205            Set<String> projectIds = new HashSet<String>();
206    
207            for ( Artifact artifact : artifactIterable )
208            {
209                String key = ArtifactUtils.key( artifact );
210                projectIds.add( key );
211            }
212            return projectIds;
213        }
214    
215    }