001package org.apache.maven.repository.legacy;
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.io.File;
023import java.io.IOException;
024import java.util.ArrayList;
025import java.util.Collection;
026import java.util.Collections;
027import java.util.HashMap;
028import java.util.LinkedHashMap;
029import java.util.List;
030import java.util.Map;
031
032import org.apache.maven.RepositoryUtils;
033import org.apache.maven.artifact.Artifact;
034import org.apache.maven.artifact.InvalidRepositoryException;
035import org.apache.maven.artifact.factory.ArtifactFactory;
036import org.apache.maven.artifact.metadata.ArtifactMetadata;
037import org.apache.maven.artifact.repository.ArtifactRepository;
038import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory;
039import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
040import org.apache.maven.artifact.repository.Authentication;
041import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
042import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
043import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
044import org.apache.maven.artifact.resolver.ArtifactResolver;
045import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
046import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
047import org.apache.maven.artifact.versioning.VersionRange;
048import org.apache.maven.model.Dependency;
049import org.apache.maven.model.Exclusion;
050import org.apache.maven.model.Plugin;
051import org.apache.maven.model.Repository;
052import org.apache.maven.model.RepositoryPolicy;
053import org.apache.maven.repository.DelegatingLocalArtifactRepository;
054import org.apache.maven.repository.LocalArtifactRepository;
055import org.apache.maven.repository.ArtifactTransferListener;
056import org.apache.maven.repository.MirrorSelector;
057import org.apache.maven.repository.Proxy;
058import org.apache.maven.repository.RepositorySystem;
059import org.apache.maven.repository.ArtifactDoesNotExistException;
060import org.apache.maven.repository.ArtifactTransferFailedException;
061import org.apache.maven.settings.Mirror;
062import org.apache.maven.settings.Server;
063import org.apache.maven.settings.building.SettingsProblem;
064import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
065import org.apache.maven.settings.crypto.SettingsDecrypter;
066import org.apache.maven.settings.crypto.SettingsDecryptionRequest;
067import org.apache.maven.settings.crypto.SettingsDecryptionResult;
068import org.apache.maven.wagon.proxy.ProxyInfo;
069import org.apache.maven.wagon.proxy.ProxyUtils;
070import org.codehaus.plexus.PlexusContainer;
071import org.codehaus.plexus.component.annotations.Component;
072import org.codehaus.plexus.component.annotations.Requirement;
073import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
074import org.codehaus.plexus.logging.Logger;
075import org.codehaus.plexus.util.StringUtils;
076import org.eclipse.aether.RepositorySystemSession;
077import org.eclipse.aether.repository.AuthenticationContext;
078import org.eclipse.aether.repository.AuthenticationSelector;
079import org.eclipse.aether.repository.ProxySelector;
080import org.eclipse.aether.repository.RemoteRepository;
081
082/**
083 * @author Jason van Zyl
084 */
085@Component( role = RepositorySystem.class, hint = "default" )
086public class LegacyRepositorySystem
087    implements RepositorySystem
088{
089
090    @Requirement
091    private Logger logger;
092
093    @Requirement
094    private ArtifactFactory artifactFactory;
095
096    @Requirement
097    private ArtifactResolver artifactResolver;
098
099    @Requirement
100    private ArtifactRepositoryFactory artifactRepositoryFactory;
101
102    @Requirement( role = ArtifactRepositoryLayout.class )
103    private Map<String, ArtifactRepositoryLayout> layouts;
104
105    @Requirement
106    private WagonManager wagonManager;
107
108    @Requirement
109    private PlexusContainer plexus;
110
111    @Requirement
112    private MirrorSelector mirrorSelector;
113
114    @Requirement
115    private SettingsDecrypter settingsDecrypter;
116
117    public Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type )
118    {
119        return artifactFactory.createArtifact( groupId, artifactId, version, scope, type );
120    }
121
122    public Artifact createArtifact( String groupId, String artifactId, String version, String packaging )
123    {
124        return artifactFactory.createBuildArtifact( groupId, artifactId, version, packaging );
125    }
126
127    public Artifact createArtifactWithClassifier( String groupId, String artifactId, String version, String type,
128                                                  String classifier )
129    {
130        return artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, classifier );
131    }
132
133    public Artifact createProjectArtifact( String groupId, String artifactId, String metaVersionId )
134    {
135        return artifactFactory.createProjectArtifact( groupId, artifactId, metaVersionId );
136    }
137
138    public Artifact createDependencyArtifact( Dependency d )
139    {
140        VersionRange versionRange;
141        try
142        {
143            versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
144        }
145        catch ( InvalidVersionSpecificationException e )
146        {
147            return null;
148        }
149
150        Artifact artifact =
151            artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), versionRange, d.getType(),
152                                                      d.getClassifier(), d.getScope(), d.isOptional() );
153
154        if ( Artifact.SCOPE_SYSTEM.equals( d.getScope() ) && d.getSystemPath() != null )
155        {
156            artifact.setFile( new File( d.getSystemPath() ) );
157        }
158
159        if ( !d.getExclusions().isEmpty() )
160        {
161            List<String> exclusions = new ArrayList<>();
162
163            for ( Exclusion exclusion : d.getExclusions() )
164            {
165                exclusions.add( exclusion.getGroupId() + ':' + exclusion.getArtifactId() );
166            }
167
168            artifact.setDependencyFilter( new ExcludesArtifactFilter( exclusions ) );
169        }
170
171        return artifact;
172    }
173
174    public Artifact createExtensionArtifact( String groupId, String artifactId, String version )
175    {
176        VersionRange versionRange;
177        try
178        {
179            versionRange = VersionRange.createFromVersionSpec( version );
180        }
181        catch ( InvalidVersionSpecificationException e )
182        {
183            return null;
184        }
185
186        return artifactFactory.createExtensionArtifact( groupId, artifactId, versionRange );
187    }
188
189    public Artifact createParentArtifact( String groupId, String artifactId, String version )
190    {
191        return artifactFactory.createParentArtifact( groupId, artifactId, version );
192    }
193
194    public Artifact createPluginArtifact( Plugin plugin )
195    {
196        VersionRange versionRange;
197        try
198        {
199            String version = plugin.getVersion();
200            if ( StringUtils.isEmpty( version ) )
201            {
202                version = "RELEASE";
203            }
204            versionRange = VersionRange.createFromVersionSpec( version );
205        }
206        catch ( InvalidVersionSpecificationException e )
207        {
208            return null;
209        }
210
211        return artifactFactory.createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), versionRange );
212    }
213
214    public ArtifactRepositoryPolicy buildArtifactRepositoryPolicy( RepositoryPolicy policy )
215    {
216        boolean enabled = true;
217
218        String updatePolicy = null;
219
220        String checksumPolicy = null;
221
222        if ( policy != null )
223        {
224            enabled = policy.isEnabled();
225
226            if ( policy.getUpdatePolicy() != null )
227            {
228                updatePolicy = policy.getUpdatePolicy();
229            }
230            if ( policy.getChecksumPolicy() != null )
231            {
232                checksumPolicy = policy.getChecksumPolicy();
233            }
234        }
235
236        return new ArtifactRepositoryPolicy( enabled, updatePolicy, checksumPolicy );
237    }
238
239    public ArtifactRepository createDefaultLocalRepository()
240        throws InvalidRepositoryException
241    {
242        return createLocalRepository( RepositorySystem.defaultUserLocalRepository );
243    }
244
245    public ArtifactRepository createLocalRepository( File localRepository )
246        throws InvalidRepositoryException
247    {
248        return createRepository( "file://" + localRepository.toURI().getRawPath(),
249                                 RepositorySystem.DEFAULT_LOCAL_REPO_ID, true,
250                                 ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, true,
251                                 ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
252                                 ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
253    }
254
255    public ArtifactRepository createDefaultRemoteRepository()
256        throws InvalidRepositoryException
257    {
258        return createRepository( RepositorySystem.DEFAULT_REMOTE_REPO_URL, RepositorySystem.DEFAULT_REMOTE_REPO_ID,
259                                 true, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, false,
260                                 ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY,
261                                 ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
262    }
263
264    public ArtifactRepository createLocalRepository( String url, String repositoryId )
265        throws IOException
266    {
267        return createRepository( canonicalFileUrl( url ), repositoryId, true,
268                                 ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, true,
269                                 ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
270                                 ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
271    }
272
273    private String canonicalFileUrl( String url )
274        throws IOException
275    {
276        if ( !url.startsWith( "file:" ) )
277        {
278            url = "file://" + url;
279        }
280        else if ( url.startsWith( "file:" ) && !url.startsWith( "file://" ) )
281        {
282            url = "file://" + url.substring( "file:".length() );
283        }
284
285        // So now we have an url of the form file://<path>
286
287        // We want to eliminate any relative path nonsense and lock down the path so we
288        // need to fully resolve it before any sub-modules use the path. This can happen
289        // when you are using a custom settings.xml that contains a relative path entry
290        // for the local repository setting.
291
292        File localRepository = new File( url.substring( "file://".length() ) );
293
294        if ( !localRepository.isAbsolute() )
295        {
296            url = "file://" + localRepository.getCanonicalPath();
297        }
298
299        return url;
300    }
301
302    public ArtifactResolutionResult resolve( ArtifactResolutionRequest request )
303    {
304        /*
305         * Probably is not worth it, but here I make sure I restore request
306         * to its original state.
307         */
308        try
309        {
310            LocalArtifactRepository ideWorkspace =
311                plexus.lookup( LocalArtifactRepository.class, LocalArtifactRepository.IDE_WORKSPACE );
312
313            if ( request.getLocalRepository() instanceof DelegatingLocalArtifactRepository )
314            {
315                DelegatingLocalArtifactRepository delegatingLocalRepository =
316                    (DelegatingLocalArtifactRepository) request.getLocalRepository();
317
318                LocalArtifactRepository orig = delegatingLocalRepository.getIdeWorspace();
319
320                delegatingLocalRepository.setIdeWorkspace( ideWorkspace );
321
322                try
323                {
324                    return artifactResolver.resolve( request );
325                }
326                finally
327                {
328                    delegatingLocalRepository.setIdeWorkspace( orig );
329                }
330            }
331            else
332            {
333                ArtifactRepository localRepository = request.getLocalRepository();
334                DelegatingLocalArtifactRepository delegatingLocalRepository =
335                    new DelegatingLocalArtifactRepository( localRepository );
336                delegatingLocalRepository.setIdeWorkspace( ideWorkspace );
337                request.setLocalRepository( delegatingLocalRepository );
338                try
339                {
340                    return artifactResolver.resolve( request );
341                }
342                finally
343                {
344                    request.setLocalRepository( localRepository );
345                }
346            }
347        }
348        catch ( ComponentLookupException e )
349        {
350            // no ide workspace artifact resolution
351        }
352
353        return artifactResolver.resolve( request );
354    }
355
356    /*
357    public void addProxy( String protocol, String host, int port, String username, String password, String nonProxyHosts )
358    {
359        ProxyInfo proxyInfo = new ProxyInfo();
360        proxyInfo.setHost( host );
361        proxyInfo.setType( protocol );
362        proxyInfo.setPort( port );
363        proxyInfo.setNonProxyHosts( nonProxyHosts );
364        proxyInfo.setUserName( username );
365        proxyInfo.setPassword( password );
366
367        proxies.put( protocol, proxyInfo );
368
369        wagonManager.addProxy( protocol, host, port, username, password, nonProxyHosts );
370    }
371    */
372
373    public List<ArtifactRepository> getEffectiveRepositories( List<ArtifactRepository> repositories )
374    {
375        if ( repositories == null )
376        {
377            return null;
378        }
379
380        Map<String, List<ArtifactRepository>> reposByKey = new LinkedHashMap<>();
381
382        for ( ArtifactRepository repository : repositories )
383        {
384            String key = repository.getId();
385
386            List<ArtifactRepository> aliasedRepos = reposByKey.get( key );
387
388            if ( aliasedRepos == null )
389            {
390                aliasedRepos = new ArrayList<>();
391                reposByKey.put( key, aliasedRepos );
392            }
393
394            aliasedRepos.add( repository );
395        }
396
397        List<ArtifactRepository> effectiveRepositories = new ArrayList<>();
398
399        for ( List<ArtifactRepository> aliasedRepos : reposByKey.values() )
400        {
401            List<ArtifactRepository> mirroredRepos = new ArrayList<>();
402
403            List<ArtifactRepositoryPolicy> releasePolicies =
404                new ArrayList<>( aliasedRepos.size() );
405
406            for ( ArtifactRepository aliasedRepo : aliasedRepos )
407            {
408                releasePolicies.add( aliasedRepo.getReleases() );
409                mirroredRepos.addAll( aliasedRepo.getMirroredRepositories() );
410            }
411
412            ArtifactRepositoryPolicy releasePolicy = getEffectivePolicy( releasePolicies );
413
414            List<ArtifactRepositoryPolicy> snapshotPolicies =
415                new ArrayList<>( aliasedRepos.size() );
416
417            for ( ArtifactRepository aliasedRepo : aliasedRepos )
418            {
419                snapshotPolicies.add( aliasedRepo.getSnapshots() );
420            }
421
422            ArtifactRepositoryPolicy snapshotPolicy = getEffectivePolicy( snapshotPolicies );
423
424            ArtifactRepository aliasedRepo = aliasedRepos.get( 0 );
425
426            ArtifactRepository effectiveRepository =
427                createArtifactRepository( aliasedRepo.getId(), aliasedRepo.getUrl(), aliasedRepo.getLayout(),
428                                          snapshotPolicy, releasePolicy );
429
430            effectiveRepository.setAuthentication( aliasedRepo.getAuthentication() );
431
432            effectiveRepository.setProxy( aliasedRepo.getProxy() );
433
434            effectiveRepository.setMirroredRepositories( mirroredRepos );
435
436            effectiveRepositories.add( effectiveRepository );
437        }
438
439        return effectiveRepositories;
440    }
441
442    private ArtifactRepositoryPolicy getEffectivePolicy( Collection<ArtifactRepositoryPolicy> policies )
443    {
444        ArtifactRepositoryPolicy effectivePolicy = null;
445
446        for ( ArtifactRepositoryPolicy policy : policies )
447        {
448            if ( effectivePolicy == null )
449            {
450                effectivePolicy = new ArtifactRepositoryPolicy( policy );
451            }
452            else
453            {
454                effectivePolicy.merge( policy );
455            }
456        }
457
458        return effectivePolicy;
459    }
460
461    public Mirror getMirror( ArtifactRepository repository, List<Mirror> mirrors )
462    {
463        return mirrorSelector.getMirror( repository, mirrors );
464    }
465
466    public void injectMirror( List<ArtifactRepository> repositories, List<Mirror> mirrors )
467    {
468        if ( repositories != null && mirrors != null )
469        {
470            for ( ArtifactRepository repository : repositories )
471            {
472                Mirror mirror = getMirror( repository, mirrors );
473                injectMirror( repository, mirror );
474            }
475        }
476    }
477
478    private Mirror getMirror( RepositorySystemSession session, ArtifactRepository repository )
479    {
480        if ( session != null )
481        {
482            org.eclipse.aether.repository.MirrorSelector selector = session.getMirrorSelector();
483            if ( selector != null )
484            {
485                RemoteRepository repo = selector.getMirror( RepositoryUtils.toRepo( repository ) );
486                if ( repo != null )
487                {
488                    Mirror mirror = new Mirror();
489                    mirror.setId( repo.getId() );
490                    mirror.setUrl( repo.getUrl() );
491                    mirror.setLayout( repo.getContentType() );
492                    return mirror;
493                }
494            }
495        }
496        return null;
497    }
498
499    public void injectMirror( RepositorySystemSession session, List<ArtifactRepository> repositories )
500    {
501        if ( repositories != null && session != null )
502        {
503            for ( ArtifactRepository repository : repositories )
504            {
505                Mirror mirror = getMirror( session, repository );
506                injectMirror( repository, mirror );
507            }
508        }
509    }
510
511    private void injectMirror( ArtifactRepository repository, Mirror mirror )
512    {
513        if ( mirror != null )
514        {
515            ArtifactRepository original =
516                createArtifactRepository( repository.getId(), repository.getUrl(), repository.getLayout(),
517                                          repository.getSnapshots(), repository.getReleases() );
518
519            repository.setMirroredRepositories( Collections.singletonList( original ) );
520
521            repository.setId( mirror.getId() );
522            repository.setUrl( mirror.getUrl() );
523
524            if ( StringUtils.isNotEmpty( mirror.getLayout() ) )
525            {
526                repository.setLayout( getLayout( mirror.getLayout() ) );
527            }
528        }
529    }
530
531    public void injectAuthentication( List<ArtifactRepository> repositories, List<Server> servers )
532    {
533        if ( repositories != null )
534        {
535            Map<String, Server> serversById = new HashMap<>();
536
537            if ( servers != null )
538            {
539                for ( Server server : servers )
540                {
541                    if ( !serversById.containsKey( server.getId() ) )
542                    {
543                        serversById.put( server.getId(), server );
544                    }
545                }
546            }
547
548            for ( ArtifactRepository repository : repositories )
549            {
550                Server server = serversById.get( repository.getId() );
551
552                if ( server != null )
553                {
554                    SettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest( server );
555                    SettingsDecryptionResult result = settingsDecrypter.decrypt( request );
556                    server = result.getServer();
557
558                    if ( logger.isDebugEnabled() )
559                    {
560                        for ( SettingsProblem problem : result.getProblems() )
561                        {
562                            logger.debug( problem.getMessage(), problem.getException() );
563                        }
564                    }
565
566                    Authentication authentication = new Authentication( server.getUsername(), server.getPassword() );
567                    authentication.setPrivateKey( server.getPrivateKey() );
568                    authentication.setPassphrase( server.getPassphrase() );
569
570                    repository.setAuthentication( authentication );
571                }
572                else
573                {
574                    repository.setAuthentication( null );
575                }
576            }
577        }
578    }
579
580    private Authentication getAuthentication( RepositorySystemSession session, ArtifactRepository repository )
581    {
582        if ( session != null )
583        {
584            AuthenticationSelector selector = session.getAuthenticationSelector();
585            if ( selector != null )
586            {
587                RemoteRepository repo = RepositoryUtils.toRepo( repository );
588                org.eclipse.aether.repository.Authentication auth = selector.getAuthentication( repo );
589                if ( auth != null )
590                {
591                    repo = new RemoteRepository.Builder( repo ).setAuthentication( auth ).build();
592                    AuthenticationContext authCtx = AuthenticationContext.forRepository( session, repo );
593                    Authentication result =
594                        new Authentication( authCtx.get( AuthenticationContext.USERNAME ),
595                                            authCtx.get( AuthenticationContext.PASSWORD ) );
596                    result.setPrivateKey( authCtx.get( AuthenticationContext.PRIVATE_KEY_PATH ) );
597                    result.setPassphrase( authCtx.get( AuthenticationContext.PRIVATE_KEY_PASSPHRASE ) );
598                    authCtx.close();
599                    return result;
600                }
601            }
602        }
603        return null;
604    }
605
606    public void injectAuthentication( RepositorySystemSession session, List<ArtifactRepository> repositories )
607    {
608        if ( repositories != null && session != null )
609        {
610            for ( ArtifactRepository repository : repositories )
611            {
612                repository.setAuthentication( getAuthentication( session, repository ) );
613            }
614        }
615    }
616
617    private org.apache.maven.settings.Proxy getProxy( ArtifactRepository repository,
618                                                      List<org.apache.maven.settings.Proxy> proxies )
619    {
620        if ( proxies != null && repository.getProtocol() != null )
621        {
622            for ( org.apache.maven.settings.Proxy proxy : proxies )
623            {
624                if ( proxy.isActive() && repository.getProtocol().equalsIgnoreCase( proxy.getProtocol() ) )
625                {
626                    if ( StringUtils.isNotEmpty( proxy.getNonProxyHosts() ) )
627                    {
628                        ProxyInfo pi = new ProxyInfo();
629                        pi.setNonProxyHosts( proxy.getNonProxyHosts() );
630
631                        org.apache.maven.wagon.repository.Repository repo =
632                            new org.apache.maven.wagon.repository.Repository( repository.getId(), repository.getUrl() );
633
634                        if ( !ProxyUtils.validateNonProxyHosts( pi, repo.getHost() ) )
635                        {
636                            return proxy;
637                        }
638                    }
639                    else
640                    {
641                        return proxy;
642                    }
643                }
644            }
645        }
646
647        return null;
648    }
649
650    public void injectProxy( List<ArtifactRepository> repositories, List<org.apache.maven.settings.Proxy> proxies )
651    {
652        if ( repositories != null )
653        {
654            for ( ArtifactRepository repository : repositories )
655            {
656                org.apache.maven.settings.Proxy proxy = getProxy( repository, proxies );
657
658                if ( proxy != null )
659                {
660                    SettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest( proxy );
661                    SettingsDecryptionResult result = settingsDecrypter.decrypt( request );
662                    proxy = result.getProxy();
663
664                    if ( logger.isDebugEnabled() )
665                    {
666                        for ( SettingsProblem problem : result.getProblems() )
667                        {
668                            logger.debug( problem.getMessage(), problem.getException() );
669                        }
670                    }
671
672                    Proxy p = new Proxy();
673                    p.setHost( proxy.getHost() );
674                    p.setProtocol( proxy.getProtocol() );
675                    p.setPort( proxy.getPort() );
676                    p.setNonProxyHosts( proxy.getNonProxyHosts() );
677                    p.setUserName( proxy.getUsername() );
678                    p.setPassword( proxy.getPassword() );
679
680                    repository.setProxy( p );
681                }
682                else
683                {
684                    repository.setProxy( null );
685                }
686            }
687        }
688    }
689
690    private Proxy getProxy( RepositorySystemSession session, ArtifactRepository repository )
691    {
692        if ( session != null )
693        {
694            ProxySelector selector = session.getProxySelector();
695            if ( selector != null )
696            {
697                RemoteRepository repo = RepositoryUtils.toRepo( repository );
698                org.eclipse.aether.repository.Proxy proxy = selector.getProxy( repo );
699                if ( proxy != null )
700                {
701                    Proxy p = new Proxy();
702                    p.setHost( proxy.getHost() );
703                    p.setProtocol( proxy.getType() );
704                    p.setPort( proxy.getPort() );
705                    if ( proxy.getAuthentication() != null )
706                    {
707                        repo = new RemoteRepository.Builder( repo ).setProxy( proxy ).build();
708                        AuthenticationContext authCtx = AuthenticationContext.forProxy( session, repo );
709                        p.setUserName( authCtx.get( AuthenticationContext.USERNAME ) );
710                        p.setPassword( authCtx.get( AuthenticationContext.PASSWORD ) );
711                        p.setNtlmDomain( authCtx.get( AuthenticationContext.NTLM_DOMAIN ) );
712                        p.setNtlmHost( authCtx.get( AuthenticationContext.NTLM_WORKSTATION ) );
713                        authCtx.close();
714                    }
715                    return p;
716                }
717            }
718        }
719        return null;
720    }
721
722    public void injectProxy( RepositorySystemSession session, List<ArtifactRepository> repositories )
723    {
724        if ( repositories != null && session != null )
725        {
726            for ( ArtifactRepository repository : repositories )
727            {
728                repository.setProxy( getProxy( session, repository ) );
729            }
730        }
731    }
732
733    public void retrieve( ArtifactRepository repository, File destination, String remotePath,
734                          ArtifactTransferListener transferListener )
735        throws ArtifactTransferFailedException, ArtifactDoesNotExistException
736    {
737        try
738        {
739            wagonManager.getRemoteFile( repository, destination, remotePath,
740                                        TransferListenerAdapter.newAdapter( transferListener ),
741                                        ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN, true );
742        }
743        catch ( org.apache.maven.wagon.TransferFailedException e )
744        {
745            throw new ArtifactTransferFailedException( getMessage( e, "Error transferring artifact." ), e );
746        }
747        catch ( org.apache.maven.wagon.ResourceDoesNotExistException e )
748        {
749            throw new ArtifactDoesNotExistException( getMessage( e, "Requested artifact does not exist." ), e );
750        }
751    }
752
753    public void publish( ArtifactRepository repository, File source, String remotePath,
754                         ArtifactTransferListener transferListener )
755        throws ArtifactTransferFailedException
756    {
757        try
758        {
759            wagonManager.putRemoteFile( repository, source, remotePath,
760                                        TransferListenerAdapter.newAdapter( transferListener ) );
761        }
762        catch ( org.apache.maven.wagon.TransferFailedException e )
763        {
764            throw new ArtifactTransferFailedException( getMessage( e, "Error transferring artifact." ), e );
765        }
766    }
767
768    //
769    // Artifact Repository Creation
770    //
771    public ArtifactRepository buildArtifactRepository( Repository repo )
772        throws InvalidRepositoryException
773    {
774        if ( repo != null )
775        {
776            String id = repo.getId();
777
778            if ( StringUtils.isEmpty( id ) )
779            {
780                throw new InvalidRepositoryException( "Repository identifier missing", "" );
781            }
782
783            String url = repo.getUrl();
784
785            if ( StringUtils.isEmpty( url ) )
786            {
787                throw new InvalidRepositoryException( "URL missing for repository " + id, id );
788            }
789
790            ArtifactRepositoryPolicy snapshots = buildArtifactRepositoryPolicy( repo.getSnapshots() );
791
792            ArtifactRepositoryPolicy releases = buildArtifactRepositoryPolicy( repo.getReleases() );
793
794            return createArtifactRepository( id, url, getLayout( repo.getLayout() ), snapshots, releases );
795        }
796        else
797        {
798            return null;
799        }
800    }
801
802    private ArtifactRepository createRepository( String url, String repositoryId, boolean releases,
803                                                 String releaseUpdates, boolean snapshots, String snapshotUpdates,
804                                                 String checksumPolicy )
805    {
806        ArtifactRepositoryPolicy snapshotsPolicy =
807            new ArtifactRepositoryPolicy( snapshots, snapshotUpdates, checksumPolicy );
808
809        ArtifactRepositoryPolicy releasesPolicy =
810            new ArtifactRepositoryPolicy( releases, releaseUpdates, checksumPolicy );
811
812        return createArtifactRepository( repositoryId, url, null, snapshotsPolicy, releasesPolicy );
813    }
814
815    public ArtifactRepository createArtifactRepository( String repositoryId, String url,
816                                                        ArtifactRepositoryLayout repositoryLayout,
817                                                        ArtifactRepositoryPolicy snapshots,
818                                                        ArtifactRepositoryPolicy releases )
819    {
820        if ( repositoryLayout == null )
821        {
822            repositoryLayout = layouts.get( "default" );
823        }
824
825        ArtifactRepository artifactRepository =
826            artifactRepositoryFactory.createArtifactRepository( repositoryId, url, repositoryLayout, snapshots,
827                                                                releases );
828
829        return artifactRepository;
830    }
831
832    private static String getMessage( Throwable error, String def )
833    {
834        if ( error == null )
835        {
836            return def;
837        }
838        String msg = error.getMessage();
839        if ( StringUtils.isNotEmpty( msg ) )
840        {
841            return msg;
842        }
843        return getMessage( error.getCause(), def );
844    }
845
846    private ArtifactRepositoryLayout getLayout( String id )
847    {
848        ArtifactRepositoryLayout layout = layouts.get( id );
849
850        if ( layout == null )
851        {
852            layout = new UnknownRepositoryLayout( id, layouts.get( "default" ) );
853        }
854
855        return layout;
856    }
857
858    /**
859     * In the future, the legacy system might encounter repository types for which no layout components exists because
860     * the actual communication with the repository happens via a repository connector. As a minimum, the legacy system
861     * needs to retain the id of this layout so that the content type of the remote repository can still be accurately
862     * described.
863     */
864    static class UnknownRepositoryLayout
865        implements ArtifactRepositoryLayout
866    {
867
868        private final String id;
869
870        private final ArtifactRepositoryLayout fallback;
871
872        public UnknownRepositoryLayout( String id, ArtifactRepositoryLayout fallback )
873        {
874            this.id = id;
875            this.fallback = fallback;
876        }
877
878        public String getId()
879        {
880            return id;
881        }
882
883        public String pathOf( Artifact artifact )
884        {
885            return fallback.pathOf( artifact );
886        }
887
888        public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
889        {
890            return fallback.pathOfLocalRepositoryMetadata( metadata, repository );
891        }
892
893        public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
894        {
895            return fallback.pathOfRemoteRepositoryMetadata( metadata );
896        }
897
898        @Override
899        public String toString()
900        {
901            return getId();
902        }
903
904    }
905
906}