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