001package org.eclipse.aether.internal.impl;
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.util.ArrayList;
023import java.util.Collection;
024import java.util.List;
025import static java.util.Objects.requireNonNull;
026
027import javax.inject.Inject;
028import javax.inject.Named;
029import javax.inject.Singleton;
030
031import org.eclipse.aether.RepositorySystem;
032import org.eclipse.aether.RepositorySystemSession;
033import org.eclipse.aether.RequestTrace;
034import org.eclipse.aether.SyncContext;
035import org.eclipse.aether.artifact.Artifact;
036import org.eclipse.aether.collection.CollectRequest;
037import org.eclipse.aether.collection.CollectResult;
038import org.eclipse.aether.collection.DependencyCollectionException;
039import org.eclipse.aether.deployment.DeployRequest;
040import org.eclipse.aether.deployment.DeployResult;
041import org.eclipse.aether.deployment.DeploymentException;
042import org.eclipse.aether.graph.DependencyFilter;
043import org.eclipse.aether.graph.DependencyVisitor;
044import org.eclipse.aether.impl.ArtifactDescriptorReader;
045import org.eclipse.aether.impl.ArtifactResolver;
046import org.eclipse.aether.impl.DependencyCollector;
047import org.eclipse.aether.impl.Deployer;
048import org.eclipse.aether.impl.Installer;
049import org.eclipse.aether.impl.LocalRepositoryProvider;
050import org.eclipse.aether.impl.MetadataResolver;
051import org.eclipse.aether.impl.RemoteRepositoryManager;
052import org.eclipse.aether.spi.synccontext.SyncContextFactory;
053import org.eclipse.aether.impl.VersionRangeResolver;
054import org.eclipse.aether.impl.VersionResolver;
055import org.eclipse.aether.installation.InstallRequest;
056import org.eclipse.aether.installation.InstallResult;
057import org.eclipse.aether.installation.InstallationException;
058import org.eclipse.aether.repository.Authentication;
059import org.eclipse.aether.repository.LocalRepository;
060import org.eclipse.aether.repository.LocalRepositoryManager;
061import org.eclipse.aether.repository.NoLocalRepositoryManagerException;
062import org.eclipse.aether.repository.Proxy;
063import org.eclipse.aether.repository.RemoteRepository;
064import org.eclipse.aether.resolution.ArtifactDescriptorException;
065import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
066import org.eclipse.aether.resolution.ArtifactDescriptorResult;
067import org.eclipse.aether.resolution.ArtifactRequest;
068import org.eclipse.aether.resolution.ArtifactResolutionException;
069import org.eclipse.aether.resolution.ArtifactResult;
070import org.eclipse.aether.resolution.DependencyRequest;
071import org.eclipse.aether.resolution.DependencyResolutionException;
072import org.eclipse.aether.resolution.DependencyResult;
073import org.eclipse.aether.resolution.MetadataRequest;
074import org.eclipse.aether.resolution.MetadataResult;
075import org.eclipse.aether.resolution.VersionRangeRequest;
076import org.eclipse.aether.resolution.VersionRangeResolutionException;
077import org.eclipse.aether.resolution.VersionRangeResult;
078import org.eclipse.aether.resolution.VersionRequest;
079import org.eclipse.aether.resolution.VersionResolutionException;
080import org.eclipse.aether.resolution.VersionResult;
081import org.eclipse.aether.spi.locator.Service;
082import org.eclipse.aether.spi.locator.ServiceLocator;
083import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor;
084import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor;
085
086/**
087 */
088@Singleton
089@Named
090public class DefaultRepositorySystem
091    implements RepositorySystem, Service
092{
093
094    private VersionResolver versionResolver;
095
096    private VersionRangeResolver versionRangeResolver;
097
098    private ArtifactResolver artifactResolver;
099
100    private MetadataResolver metadataResolver;
101
102    private ArtifactDescriptorReader artifactDescriptorReader;
103
104    private DependencyCollector dependencyCollector;
105
106    private Installer installer;
107
108    private Deployer deployer;
109
110    private LocalRepositoryProvider localRepositoryProvider;
111
112    private SyncContextFactory syncContextFactory;
113
114    private RemoteRepositoryManager remoteRepositoryManager;
115
116    public DefaultRepositorySystem()
117    {
118        // enables default constructor
119    }
120
121    @SuppressWarnings( "checkstyle:parameternumber" )
122    @Inject
123    DefaultRepositorySystem( VersionResolver versionResolver, VersionRangeResolver versionRangeResolver,
124                             ArtifactResolver artifactResolver, MetadataResolver metadataResolver,
125                             ArtifactDescriptorReader artifactDescriptorReader,
126                             DependencyCollector dependencyCollector, Installer installer, Deployer deployer,
127                             LocalRepositoryProvider localRepositoryProvider, SyncContextFactory syncContextFactory,
128                             RemoteRepositoryManager remoteRepositoryManager )
129    {
130        setVersionResolver( versionResolver );
131        setVersionRangeResolver( versionRangeResolver );
132        setArtifactResolver( artifactResolver );
133        setMetadataResolver( metadataResolver );
134        setArtifactDescriptorReader( artifactDescriptorReader );
135        setDependencyCollector( dependencyCollector );
136        setInstaller( installer );
137        setDeployer( deployer );
138        setLocalRepositoryProvider( localRepositoryProvider );
139        setSyncContextFactory( syncContextFactory );
140        setRemoteRepositoryManager( remoteRepositoryManager );
141    }
142
143    public void initService( ServiceLocator locator )
144    {
145        setVersionResolver( locator.getService( VersionResolver.class ) );
146        setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) );
147        setArtifactResolver( locator.getService( ArtifactResolver.class ) );
148        setMetadataResolver( locator.getService( MetadataResolver.class ) );
149        setArtifactDescriptorReader( locator.getService( ArtifactDescriptorReader.class ) );
150        setDependencyCollector( locator.getService( DependencyCollector.class ) );
151        setInstaller( locator.getService( Installer.class ) );
152        setDeployer( locator.getService( Deployer.class ) );
153        setLocalRepositoryProvider( locator.getService( LocalRepositoryProvider.class ) );
154        setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
155        setSyncContextFactory( locator.getService( SyncContextFactory.class ) );
156    }
157
158    /**
159     * @deprecated not used any more since MRESOLVER-36 move to slf4j, added back in MRESOLVER-64 for compatibility
160     */
161    @Deprecated
162    public DefaultRepositorySystem setLoggerFactory( org.eclipse.aether.spi.log.LoggerFactory loggerFactory )
163    {
164        // this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
165        return this;
166    }
167
168    public DefaultRepositorySystem setVersionResolver( VersionResolver versionResolver )
169    {
170        this.versionResolver = requireNonNull( versionResolver, "version resolver cannot be null" );
171        return this;
172    }
173
174    public DefaultRepositorySystem setVersionRangeResolver( VersionRangeResolver versionRangeResolver )
175    {
176        this.versionRangeResolver = requireNonNull(
177                versionRangeResolver, "version range resolver cannot be null" );
178        return this;
179    }
180
181    public DefaultRepositorySystem setArtifactResolver( ArtifactResolver artifactResolver )
182    {
183        this.artifactResolver = requireNonNull( artifactResolver, "artifact resolver cannot be null" );
184        return this;
185    }
186
187    public DefaultRepositorySystem setMetadataResolver( MetadataResolver metadataResolver )
188    {
189        this.metadataResolver = requireNonNull( metadataResolver, "metadata resolver cannot be null" );
190        return this;
191    }
192
193    public DefaultRepositorySystem setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader )
194    {
195        this.artifactDescriptorReader = requireNonNull(
196                artifactDescriptorReader, "artifact descriptor reader cannot be null" );
197        return this;
198    }
199
200    public DefaultRepositorySystem setDependencyCollector( DependencyCollector dependencyCollector )
201    {
202        this.dependencyCollector = requireNonNull( dependencyCollector, "dependency collector cannot be null" );
203        return this;
204    }
205
206    public DefaultRepositorySystem setInstaller( Installer installer )
207    {
208        this.installer = requireNonNull( installer, "installer cannot be null" );
209        return this;
210    }
211
212    public DefaultRepositorySystem setDeployer( Deployer deployer )
213    {
214        this.deployer = requireNonNull( deployer, "deployer cannot be null" );
215        return this;
216    }
217
218    public DefaultRepositorySystem setLocalRepositoryProvider( LocalRepositoryProvider localRepositoryProvider )
219    {
220        this.localRepositoryProvider = requireNonNull(
221                localRepositoryProvider, "local repository provider cannot be null" );
222        return this;
223    }
224
225    public DefaultRepositorySystem setSyncContextFactory( SyncContextFactory syncContextFactory )
226    {
227        this.syncContextFactory = requireNonNull( syncContextFactory, "sync context factory cannot be null" );
228        return this;
229    }
230
231    public DefaultRepositorySystem setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager )
232    {
233        this.remoteRepositoryManager = requireNonNull(
234                remoteRepositoryManager, "remote repository provider cannot be null" );
235        return this;
236    }
237
238    public VersionResult resolveVersion( RepositorySystemSession session, VersionRequest request )
239        throws VersionResolutionException
240    {
241        validateSession( session );
242        requireNonNull( request, "request cannot be null" );
243
244        return versionResolver.resolveVersion( session, request );
245    }
246
247    public VersionRangeResult resolveVersionRange( RepositorySystemSession session, VersionRangeRequest request )
248        throws VersionRangeResolutionException
249    {
250        validateSession( session );
251        requireNonNull( request, "request cannot be null" );
252
253        return versionRangeResolver.resolveVersionRange( session, request );
254    }
255
256    public ArtifactDescriptorResult readArtifactDescriptor( RepositorySystemSession session,
257                                                            ArtifactDescriptorRequest request )
258        throws ArtifactDescriptorException
259    {
260        validateSession( session );
261        requireNonNull( request, "request cannot be null" );
262
263        return artifactDescriptorReader.readArtifactDescriptor( session, request );
264    }
265
266    public ArtifactResult resolveArtifact( RepositorySystemSession session, ArtifactRequest request )
267        throws ArtifactResolutionException
268    {
269        validateSession( session );
270        requireNonNull( session, "session cannot be null" );
271
272        return artifactResolver.resolveArtifact( session, request );
273    }
274
275    public List<ArtifactResult> resolveArtifacts( RepositorySystemSession session,
276                                                  Collection<? extends ArtifactRequest> requests )
277        throws ArtifactResolutionException
278    {
279        validateSession( session );
280        requireNonNull( requests, "requests cannot be null" );
281
282        return artifactResolver.resolveArtifacts( session, requests );
283    }
284
285    public List<MetadataResult> resolveMetadata( RepositorySystemSession session,
286                                                 Collection<? extends MetadataRequest> requests )
287    {
288        validateSession( session );
289        requireNonNull( requests, "requests cannot be null" );
290
291        return metadataResolver.resolveMetadata( session, requests );
292    }
293
294    public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request )
295        throws DependencyCollectionException
296    {
297        validateSession( session );
298        requireNonNull( request, "request cannot be null" );
299
300        return dependencyCollector.collectDependencies( session, request );
301    }
302
303    public DependencyResult resolveDependencies( RepositorySystemSession session, DependencyRequest request )
304        throws DependencyResolutionException
305    {
306        validateSession( session );
307        requireNonNull( request, "request cannot be null" );
308
309        RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
310
311        DependencyResult result = new DependencyResult( request );
312
313        DependencyCollectionException dce = null;
314        ArtifactResolutionException are = null;
315
316        if ( request.getRoot() != null )
317        {
318            result.setRoot( request.getRoot() );
319        }
320        else if ( request.getCollectRequest() != null )
321        {
322            CollectResult collectResult;
323            try
324            {
325                request.getCollectRequest().setTrace( trace );
326                collectResult = dependencyCollector.collectDependencies( session, request.getCollectRequest() );
327            }
328            catch ( DependencyCollectionException e )
329            {
330                dce = e;
331                collectResult = e.getResult();
332            }
333            result.setRoot( collectResult.getRoot() );
334            result.setCycles( collectResult.getCycles() );
335            result.setCollectExceptions( collectResult.getExceptions() );
336        }
337        else
338        {
339            throw new NullPointerException( "dependency node and collect request cannot be null" );
340        }
341
342        ArtifactRequestBuilder builder = new ArtifactRequestBuilder( trace );
343        DependencyFilter filter = request.getFilter();
344        DependencyVisitor visitor = ( filter != null ) ? new FilteringDependencyVisitor( builder, filter ) : builder;
345        visitor = new TreeDependencyVisitor( visitor );
346
347        if ( result.getRoot() != null )
348        {
349            result.getRoot().accept( visitor );
350        }
351
352        List<ArtifactRequest> requests = builder.getRequests();
353
354        List<ArtifactResult> results;
355        try
356        {
357            results = artifactResolver.resolveArtifacts( session, requests );
358        }
359        catch ( ArtifactResolutionException e )
360        {
361            are = e;
362            results = e.getResults();
363        }
364        result.setArtifactResults( results );
365
366        updateNodesWithResolvedArtifacts( results );
367
368        if ( dce != null )
369        {
370            throw new DependencyResolutionException( result, dce );
371        }
372        else if ( are != null )
373        {
374            throw new DependencyResolutionException( result, are );
375        }
376
377        return result;
378    }
379
380    private void updateNodesWithResolvedArtifacts( List<ArtifactResult> results )
381    {
382        for ( ArtifactResult result : results )
383        {
384            Artifact artifact = result.getArtifact();
385            if ( artifact != null )
386            {
387                result.getRequest().getDependencyNode().setArtifact( artifact );
388            }
389        }
390    }
391
392    public InstallResult install( RepositorySystemSession session, InstallRequest request )
393        throws InstallationException
394    {
395        validateSession( session );
396        requireNonNull( request, "request cannot be null" );
397
398        return installer.install( session, request );
399    }
400
401    public DeployResult deploy( RepositorySystemSession session, DeployRequest request )
402        throws DeploymentException
403    {
404        validateSession( session );
405        requireNonNull( request, "request cannot be null" );
406
407        return deployer.deploy( session, request );
408    }
409
410    public LocalRepositoryManager newLocalRepositoryManager( RepositorySystemSession session,
411                                                             LocalRepository localRepository )
412    {
413        requireNonNull( session, "session cannot be null" );
414        requireNonNull( localRepository, "localRepository cannot be null" );
415
416        try
417        {
418            return localRepositoryProvider.newLocalRepositoryManager( session, localRepository );
419        }
420        catch ( NoLocalRepositoryManagerException e )
421        {
422            throw new IllegalArgumentException( e.getMessage(), e );
423        }
424    }
425
426    public SyncContext newSyncContext( RepositorySystemSession session, boolean shared )
427    {
428        validateSession( session );
429        return syncContextFactory.newInstance( session, shared );
430    }
431
432    public List<RemoteRepository> newResolutionRepositories( RepositorySystemSession session,
433                                                             List<RemoteRepository> repositories )
434    {
435        validateSession( session );
436        validateRepositories( repositories );
437
438        repositories =
439            remoteRepositoryManager.aggregateRepositories( session, new ArrayList<RemoteRepository>(), repositories,
440                                                           true );
441        return repositories;
442    }
443
444    public RemoteRepository newDeploymentRepository( RepositorySystemSession session, RemoteRepository repository )
445    {
446        validateSession( session );
447        requireNonNull( repository, "repository cannot be null" );
448
449        RemoteRepository.Builder builder = new RemoteRepository.Builder( repository );
450        Authentication auth = session.getAuthenticationSelector().getAuthentication( repository );
451        builder.setAuthentication( auth );
452        Proxy proxy = session.getProxySelector().getProxy( repository );
453        builder.setProxy( proxy );
454        return builder.build();
455    }
456
457    private void validateSession( RepositorySystemSession session )
458    {
459        requireNonNull( session, "repository system session cannot be null" );
460        invalidSession( session.getLocalRepositoryManager(), "local repository manager" );
461        invalidSession( session.getSystemProperties(), "system properties" );
462        invalidSession( session.getUserProperties(), "user properties" );
463        invalidSession( session.getConfigProperties(), "config properties" );
464        invalidSession( session.getMirrorSelector(), "mirror selector" );
465        invalidSession( session.getProxySelector(), "proxy selector" );
466        invalidSession( session.getAuthenticationSelector(), "authentication selector" );
467        invalidSession( session.getArtifactTypeRegistry(), "artifact type registry" );
468        invalidSession( session.getData(), "data" );
469    }
470
471    private void validateRepositories( List<RemoteRepository> repositories )
472    {
473        requireNonNull( repositories, "repositories cannot be null" );
474        for ( RemoteRepository repository: repositories )
475        {
476            requireNonNull( repository, "repository cannot be null" );
477        }
478    }
479
480    private void invalidSession( Object obj, String name )
481    {
482        requireNonNull( obj, "repository system session's " + name + " cannot be null" );
483    }
484
485}