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