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        return versionResolver.resolveVersion( session, request );
243    }
244
245    public VersionRangeResult resolveVersionRange( RepositorySystemSession session, VersionRangeRequest request )
246        throws VersionRangeResolutionException
247    {
248        validateSession( session );
249        return versionRangeResolver.resolveVersionRange( session, request );
250    }
251
252    public ArtifactDescriptorResult readArtifactDescriptor( RepositorySystemSession session,
253                                                            ArtifactDescriptorRequest request )
254        throws ArtifactDescriptorException
255    {
256        validateSession( session );
257        return artifactDescriptorReader.readArtifactDescriptor( session, request );
258    }
259
260    public ArtifactResult resolveArtifact( RepositorySystemSession session, ArtifactRequest request )
261        throws ArtifactResolutionException
262    {
263        validateSession( session );
264        return artifactResolver.resolveArtifact( session, request );
265    }
266
267    public List<ArtifactResult> resolveArtifacts( RepositorySystemSession session,
268                                                  Collection<? extends ArtifactRequest> requests )
269        throws ArtifactResolutionException
270    {
271        validateSession( session );
272        return artifactResolver.resolveArtifacts( session, requests );
273    }
274
275    public List<MetadataResult> resolveMetadata( RepositorySystemSession session,
276                                                 Collection<? extends MetadataRequest> requests )
277    {
278        validateSession( session );
279        return metadataResolver.resolveMetadata( session, requests );
280    }
281
282    public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request )
283        throws DependencyCollectionException
284    {
285        validateSession( session );
286        return dependencyCollector.collectDependencies( session, request );
287    }
288
289    public DependencyResult resolveDependencies( RepositorySystemSession session, DependencyRequest request )
290        throws DependencyResolutionException
291    {
292        validateSession( session );
293
294        RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
295
296        DependencyResult result = new DependencyResult( request );
297
298        DependencyCollectionException dce = null;
299        ArtifactResolutionException are = null;
300
301        if ( request.getRoot() != null )
302        {
303            result.setRoot( request.getRoot() );
304        }
305        else if ( request.getCollectRequest() != null )
306        {
307            CollectResult collectResult;
308            try
309            {
310                request.getCollectRequest().setTrace( trace );
311                collectResult = dependencyCollector.collectDependencies( session, request.getCollectRequest() );
312            }
313            catch ( DependencyCollectionException e )
314            {
315                dce = e;
316                collectResult = e.getResult();
317            }
318            result.setRoot( collectResult.getRoot() );
319            result.setCycles( collectResult.getCycles() );
320            result.setCollectExceptions( collectResult.getExceptions() );
321        }
322        else
323        {
324            throw new NullPointerException( "dependency node and collect request cannot be null" );
325        }
326
327        ArtifactRequestBuilder builder = new ArtifactRequestBuilder( trace );
328        DependencyFilter filter = request.getFilter();
329        DependencyVisitor visitor = ( filter != null ) ? new FilteringDependencyVisitor( builder, filter ) : builder;
330        visitor = new TreeDependencyVisitor( visitor );
331
332        if ( result.getRoot() != null )
333        {
334            result.getRoot().accept( visitor );
335        }
336
337        List<ArtifactRequest> requests = builder.getRequests();
338
339        List<ArtifactResult> results;
340        try
341        {
342            results = artifactResolver.resolveArtifacts( session, requests );
343        }
344        catch ( ArtifactResolutionException e )
345        {
346            are = e;
347            results = e.getResults();
348        }
349        result.setArtifactResults( results );
350
351        updateNodesWithResolvedArtifacts( results );
352
353        if ( dce != null )
354        {
355            throw new DependencyResolutionException( result, dce );
356        }
357        else if ( are != null )
358        {
359            throw new DependencyResolutionException( result, are );
360        }
361
362        return result;
363    }
364
365    private void updateNodesWithResolvedArtifacts( List<ArtifactResult> results )
366    {
367        for ( ArtifactResult result : results )
368        {
369            Artifact artifact = result.getArtifact();
370            if ( artifact != null )
371            {
372                result.getRequest().getDependencyNode().setArtifact( artifact );
373            }
374        }
375    }
376
377    public InstallResult install( RepositorySystemSession session, InstallRequest request )
378        throws InstallationException
379    {
380        validateSession( session );
381        return installer.install( session, request );
382    }
383
384    public DeployResult deploy( RepositorySystemSession session, DeployRequest request )
385        throws DeploymentException
386    {
387        validateSession( session );
388        return deployer.deploy( session, request );
389    }
390
391    public LocalRepositoryManager newLocalRepositoryManager( RepositorySystemSession session,
392                                                             LocalRepository localRepository )
393    {
394        try
395        {
396            return localRepositoryProvider.newLocalRepositoryManager( session, localRepository );
397        }
398        catch ( NoLocalRepositoryManagerException e )
399        {
400            throw new IllegalArgumentException( e.getMessage(), e );
401        }
402    }
403
404    public SyncContext newSyncContext( RepositorySystemSession session, boolean shared )
405    {
406        validateSession( session );
407        return syncContextFactory.newInstance( session, shared );
408    }
409
410    public List<RemoteRepository> newResolutionRepositories( RepositorySystemSession session,
411                                                             List<RemoteRepository> repositories )
412    {
413        validateSession( session );
414        repositories =
415            remoteRepositoryManager.aggregateRepositories( session, new ArrayList<RemoteRepository>(), repositories,
416                                                           true );
417        return repositories;
418    }
419
420    public RemoteRepository newDeploymentRepository( RepositorySystemSession session, RemoteRepository repository )
421    {
422        validateSession( session );
423        RemoteRepository.Builder builder = new RemoteRepository.Builder( repository );
424        Authentication auth = session.getAuthenticationSelector().getAuthentication( repository );
425        builder.setAuthentication( auth );
426        Proxy proxy = session.getProxySelector().getProxy( repository );
427        builder.setProxy( proxy );
428        return builder.build();
429    }
430
431    private void validateSession( RepositorySystemSession session )
432    {
433        requireNonNull( session, "repository system session cannot be null" );
434        invalidSession( session.getLocalRepositoryManager(), "local repository manager" );
435        invalidSession( session.getSystemProperties(), "system properties" );
436        invalidSession( session.getUserProperties(), "user properties" );
437        invalidSession( session.getConfigProperties(), "config properties" );
438        invalidSession( session.getMirrorSelector(), "mirror selector" );
439        invalidSession( session.getProxySelector(), "proxy selector" );
440        invalidSession( session.getAuthenticationSelector(), "authentication selector" );
441        invalidSession( session.getArtifactTypeRegistry(), "artifact type registry" );
442        invalidSession( session.getData(), "data" );
443    }
444
445    private void invalidSession( Object obj, String name )
446    {
447        requireNonNull( obj, "repository system session's " + name + " cannot be null" );
448    }
449
450}