View Javadoc
1   package org.apache.maven.resolver.internal.ant;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.BufferedReader;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.InputStreamReader;
27  import java.util.ArrayList;
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.HashMap;
31  import java.util.HashSet;
32  import java.util.LinkedHashMap;
33  import java.util.List;
34  import java.util.Locale;
35  import java.util.Map;
36  import java.util.Properties;
37  import java.util.concurrent.CopyOnWriteArrayList;
38  
39  import org.apache.maven.model.Model;
40  import org.apache.maven.model.building.DefaultModelBuilderFactory;
41  import org.apache.maven.model.building.DefaultModelBuildingRequest;
42  import org.apache.maven.model.building.FileModelSource;
43  import org.apache.maven.model.building.ModelBuilder;
44  import org.apache.maven.model.building.ModelBuildingException;
45  import org.apache.maven.model.building.ModelBuildingRequest;
46  import org.apache.maven.model.resolution.ModelResolver;
47  import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
48  import org.apache.maven.resolver.internal.ant.types.Artifact;
49  import org.apache.maven.resolver.internal.ant.types.Artifacts;
50  import org.apache.maven.resolver.internal.ant.types.Authentication;
51  import org.apache.maven.resolver.internal.ant.types.Dependencies;
52  import org.apache.maven.resolver.internal.ant.types.Dependency;
53  import org.apache.maven.resolver.internal.ant.types.DependencyContainer;
54  import org.apache.maven.resolver.internal.ant.types.Exclusion;
55  import org.apache.maven.resolver.internal.ant.types.LocalRepository;
56  import org.apache.maven.resolver.internal.ant.types.Mirror;
57  import org.apache.maven.resolver.internal.ant.types.Pom;
58  import org.apache.maven.resolver.internal.ant.types.Proxy;
59  import org.apache.maven.resolver.internal.ant.types.RemoteRepositories;
60  import org.apache.maven.resolver.internal.ant.types.RemoteRepository;
61  import org.apache.maven.resolver.internal.ant.types.RemoteRepository.Policy;
62  import org.apache.maven.settings.Profile;
63  import org.apache.maven.settings.Repository;
64  import org.apache.maven.settings.RepositoryPolicy;
65  import org.apache.maven.settings.Server;
66  import org.apache.maven.settings.Settings;
67  import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
68  import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
69  import org.apache.maven.settings.building.SettingsBuilder;
70  import org.apache.maven.settings.building.SettingsBuildingException;
71  import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
72  import org.apache.maven.settings.crypto.SettingsDecrypter;
73  import org.apache.maven.settings.crypto.SettingsDecryptionResult;
74  import org.apache.tools.ant.BuildException;
75  import org.apache.tools.ant.Project;
76  import org.apache.tools.ant.Task;
77  import org.apache.tools.ant.taskdefs.condition.Os;
78  import org.apache.tools.ant.types.Reference;
79  import org.codehaus.plexus.util.xml.Xpp3Dom;
80  import org.eclipse.aether.ConfigurationProperties;
81  import org.eclipse.aether.DefaultRepositoryCache;
82  import org.eclipse.aether.DefaultRepositorySystemSession;
83  import org.eclipse.aether.RepositorySystem;
84  import org.eclipse.aether.RepositorySystemSession;
85  import org.eclipse.aether.artifact.DefaultArtifact;
86  import org.eclipse.aether.collection.CollectRequest;
87  import org.eclipse.aether.collection.CollectResult;
88  import org.eclipse.aether.collection.DependencyCollectionException;
89  import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
90  import org.eclipse.aether.deployment.DeployRequest;
91  import org.eclipse.aether.deployment.DeploymentException;
92  import org.eclipse.aether.impl.DefaultServiceLocator;
93  import org.eclipse.aether.impl.RemoteRepositoryManager;
94  import org.eclipse.aether.installation.InstallRequest;
95  import org.eclipse.aether.installation.InstallationException;
96  import org.eclipse.aether.repository.AuthenticationSelector;
97  import org.eclipse.aether.repository.LocalRepositoryManager;
98  import org.eclipse.aether.repository.MirrorSelector;
99  import org.eclipse.aether.repository.ProxySelector;
100 import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
101 import org.eclipse.aether.spi.connector.transport.TransporterFactory;
102 import org.eclipse.aether.spi.log.Logger;
103 import org.eclipse.aether.transport.classpath.ClasspathTransporterFactory;
104 import org.eclipse.aether.transport.file.FileTransporterFactory;
105 import org.eclipse.aether.transport.http.HttpTransporterFactory;
106 import org.eclipse.aether.util.repository.AuthenticationBuilder;
107 import org.eclipse.aether.util.repository.ConservativeAuthenticationSelector;
108 import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
109 import org.eclipse.aether.util.repository.DefaultMirrorSelector;
110 import org.eclipse.aether.util.repository.DefaultProxySelector;
111 
112 /**
113  */
114 public class AntRepoSys
115 {
116 
117     private static final boolean OS_WINDOWS = Os.isFamily( "windows" );
118 
119     private static final ModelBuilder MODEL_BUILDER = new DefaultModelBuilderFactory().newInstance();
120 
121     private static final SettingsBuilder SETTINGS_BUILDER = new DefaultSettingsBuilderFactory().newInstance();
122 
123     private static final SettingsDecrypter SETTINGS_DECRYPTER = new AntSettingsDecryptorFactory().newInstance();
124 
125     private final Project project;
126 
127     private final DefaultServiceLocator locator;
128 
129     private RepositorySystem repoSys;
130 
131     private RemoteRepositoryManager remoteRepoMan;
132 
133     private File userSettings;
134 
135     private File globalSettings;
136 
137     private Settings settings;
138 
139     private final List<Mirror> mirrors = new CopyOnWriteArrayList<Mirror>();
140 
141     private final List<Proxy> proxies = new CopyOnWriteArrayList<Proxy>();
142 
143     private final List<Authentication> authentications = new CopyOnWriteArrayList<Authentication>();
144 
145     private LocalRepository localRepository;
146 
147     private Pom defaultPom;
148 
149     private static <T> boolean eq( T o1, T o2 )
150     {
151         return ( o1 == null ) ? o2 == null : o1.equals( o2 );
152     }
153 
154     public static synchronized AntRepoSys getInstance( Project project )
155     {
156         Object obj = project.getReference( Names.ID );
157         if ( obj instanceof AntRepoSys )
158         {
159             return (AntRepoSys) obj;
160         }
161         AntRepoSys instance = new AntRepoSys( project );
162         project.addReference( Names.ID, instance );
163         instance.initDefaults();
164         return instance;
165     }
166 
167     private AntRepoSys( Project project )
168     {
169         this.project = project;
170 
171         locator = MavenRepositorySystemUtils.newServiceLocator();
172         locator.setErrorHandler( new AntServiceLocatorErrorHandler( project ) );
173         locator.setServices( Logger.class, new AntLogger( project ) );
174         locator.setServices( ModelBuilder.class, MODEL_BUILDER );
175         locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
176         locator.addService( TransporterFactory.class, FileTransporterFactory.class );
177         locator.addService( TransporterFactory.class, HttpTransporterFactory.class );
178         locator.addService( TransporterFactory.class, ClasspathTransporterFactory.class );
179     }
180 
181     private void initDefaults()
182     {
183         RemoteRepository repo = new RemoteRepository();
184         repo.setProject( project );
185         repo.setId( "central" );
186         repo.setUrl( "https://repo1.maven.org/maven2/" );
187         project.addReference( Names.ID_CENTRAL, repo );
188 
189         repo = new RemoteRepository();
190         repo.setProject( project );
191         repo.setRefid( new Reference( project, Names.ID_CENTRAL ) );
192 
193         RemoteRepositories repos = new RemoteRepositories();
194         repos.setProject( project );
195         repos.addRemoterepo( repo );
196         project.addReference( Names.ID_DEFAULT_REPOS, repos );
197     }
198 
199     public synchronized RepositorySystem getSystem()
200     {
201         if ( repoSys == null )
202         {
203             repoSys = locator.getService( RepositorySystem.class );
204             if ( repoSys == null )
205             {
206                 throw new BuildException( "The repository system could not be initialized" );
207             }
208         }
209         return repoSys;
210     }
211 
212     private synchronized RemoteRepositoryManager getRemoteRepoMan()
213     {
214         if ( remoteRepoMan == null )
215         {
216             remoteRepoMan = locator.getService( RemoteRepositoryManager.class );
217             if ( remoteRepoMan == null )
218             {
219                 throw new BuildException( "The repository system could not be initialized" );
220             }
221         }
222         return remoteRepoMan;
223     }
224 
225     public RepositorySystemSession getSession( Task task, LocalRepository localRepo )
226     {
227         DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
228 
229         Map<Object, Object> configProps = new LinkedHashMap<Object, Object>();
230         configProps.put( ConfigurationProperties.USER_AGENT, getUserAgent() );
231         configProps.putAll( (Map<?, ?>) project.getProperties() );
232         processServerConfiguration( configProps );
233         session.setConfigProperties( configProps );
234 
235         session.setOffline( isOffline() );
236         session.setUserProperties( project.getUserProperties() );
237 
238         session.setProxySelector( getProxySelector() );
239         session.setMirrorSelector( getMirrorSelector() );
240         session.setAuthenticationSelector( getAuthSelector() );
241 
242         session.setCache( new DefaultRepositoryCache() );
243 
244         session.setRepositoryListener( new AntRepositoryListener( task ) );
245         session.setTransferListener( new AntTransferListener( task ) );
246 
247         session.setLocalRepositoryManager( getLocalRepoMan( session, localRepo ) );
248 
249         session.setWorkspaceReader( ProjectWorkspaceReader.getInstance() );
250 
251         return session;
252     }
253 
254     private String getUserAgent()
255     {
256         StringBuilder buffer = new StringBuilder( 128 );
257 
258         buffer.append( "Apache-Ant/" ).append( project.getProperty( "ant.version" ) );
259         buffer.append( " (" );
260         buffer.append( "Java " ).append( System.getProperty( "java.version" ) );
261         buffer.append( "; " );
262         buffer.append( System.getProperty( "os.name" ) ).append( " " ).append( System.getProperty( "os.version" ) );
263         buffer.append( ")" );
264         buffer.append( " Aether" );
265 
266         return buffer.toString();
267     }
268 
269     private boolean isOffline()
270     {
271         String prop = project.getProperty( Names.PROPERTY_OFFLINE );
272         if ( prop != null )
273         {
274             return Boolean.parseBoolean( prop );
275         }
276         return getSettings().isOffline();
277     }
278 
279     private void processServerConfiguration( Map<Object, Object> configProps )
280     {
281         Settings settings = getSettings();
282         for ( Server server : settings.getServers() )
283         {
284             if ( server.getConfiguration() != null )
285             {
286                 Xpp3Dom dom = (Xpp3Dom) server.getConfiguration();
287                 for ( int i = dom.getChildCount() - 1; i >= 0; i-- )
288                 {
289                     Xpp3Dom child = dom.getChild( i );
290                     if ( "wagonProvider".equals( child.getName() ) )
291                     {
292                         dom.removeChild( i );
293                     }
294                     else if ( "httpHeaders".equals( child.getName() ) )
295                     {
296                         configProps.put( ConfigurationProperties.HTTP_HEADERS + "." + server.getId(),
297                                          getHttpHeaders( child ) );
298                     }
299                 }
300 
301                 configProps.put( "aether.connector.wagon.config." + server.getId(), dom );
302             }
303 
304             configProps.put( "aether.connector.perms.fileMode." + server.getId(), server.getFilePermissions() );
305             configProps.put( "aether.connector.perms.dirMode." + server.getId(), server.getDirectoryPermissions() );
306         }
307     }
308 
309     private Map<String, String> getHttpHeaders( Xpp3Dom dom )
310     {
311         Map<String, String> headers = new HashMap<String, String>();
312         for ( int i = 0; i < dom.getChildCount(); i++ )
313         {
314             Xpp3Dom child = dom.getChild( i );
315             Xpp3Dom name = child.getChild( "name" );
316             Xpp3Dom value = child.getChild( "value" );
317             if ( name != null && name.getValue() != null )
318             {
319                 headers.put( name.getValue(), ( value != null ) ? value.getValue() : null );
320             }
321         }
322         return Collections.unmodifiableMap( headers );
323     }
324 
325     private File getDefaultLocalRepoDir()
326     {
327         String dir = project.getProperty( "maven.repo.local" );
328         if ( dir != null )
329         {
330             return project.resolveFile( dir );
331         }
332 
333         Settings settings = getSettings();
334         if ( settings.getLocalRepository() != null )
335         {
336             return new File( settings.getLocalRepository() );
337         }
338 
339         return new File( new File( project.getProperty( "user.home" ), ".m2" ), "repository" );
340     }
341 
342     private LocalRepositoryManager getLocalRepoMan( RepositorySystemSession session, LocalRepository localRepo )
343     {
344         if ( localRepo == null )
345         {
346             localRepo = localRepository;
347         }
348 
349         File repoDir;
350         if ( localRepo != null && localRepo.getDir() != null )
351         {
352             repoDir = localRepo.getDir();
353         }
354         else
355         {
356             repoDir = getDefaultLocalRepoDir();
357         }
358 
359         org.eclipse.aether.repository.LocalRepository repo =
360             new org.eclipse.aether.repository.LocalRepository( repoDir );
361 
362         return getSystem().newLocalRepositoryManager( session, repo );
363     }
364 
365     private synchronized Settings getSettings()
366     {
367         if ( settings == null )
368         {
369             DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
370             request.setUserSettingsFile( getUserSettings() );
371             request.setGlobalSettingsFile( getGlobalSettings() );
372             request.setSystemProperties( getSystemProperties() );
373             request.setUserProperties( getUserProperties() );
374 
375             try
376             {
377                 settings = SETTINGS_BUILDER.build( request ).getEffectiveSettings();
378             }
379             catch ( SettingsBuildingException e )
380             {
381                 project.log( "Could not process settings.xml: " + e.getMessage(), e, Project.MSG_WARN );
382             }
383 
384             SettingsDecryptionResult result =
385                 SETTINGS_DECRYPTER.decrypt( new DefaultSettingsDecryptionRequest( settings ) );
386             settings.setServers( result.getServers() );
387             settings.setProxies( result.getProxies() );
388         }
389         return settings;
390     }
391 
392     private ProxySelector getProxySelector()
393     {
394         DefaultProxySelector selector = new DefaultProxySelector();
395 
396         for ( Proxy proxy : proxies )
397         {
398             selector.add( ConverterUtils.toProxy( proxy ), proxy.getNonProxyHosts() );
399         }
400 
401         Settings settings = getSettings();
402         for ( org.apache.maven.settings.Proxy proxy : settings.getProxies() )
403         {
404             AuthenticationBuilder auth = new AuthenticationBuilder();
405             auth.addUsername( proxy.getUsername() ).addPassword( proxy.getPassword() );
406             selector.add( new org.eclipse.aether.repository.Proxy( proxy.getProtocol(), proxy.getHost(),
407                                                                    proxy.getPort(), auth.build() ),
408                           proxy.getNonProxyHosts() );
409         }
410 
411         return selector;
412     }
413 
414     private MirrorSelector getMirrorSelector()
415     {
416         DefaultMirrorSelector selector = new DefaultMirrorSelector();
417 
418         for ( Mirror mirror : mirrors )
419         {
420             selector.add( mirror.getId(), mirror.getUrl(), mirror.getType(), false, mirror.getMirrorOf(), null );
421         }
422 
423         Settings settings = getSettings();
424         for ( org.apache.maven.settings.Mirror mirror : settings.getMirrors() )
425         {
426             selector.add( String.valueOf( mirror.getId() ), mirror.getUrl(), mirror.getLayout(), false,
427                           mirror.getMirrorOf(), mirror.getMirrorOfLayouts() );
428         }
429 
430         return selector;
431     }
432 
433     private AuthenticationSelector getAuthSelector()
434     {
435         DefaultAuthenticationSelector selector = new DefaultAuthenticationSelector();
436 
437         Collection<String> ids = new HashSet<String>();
438         for ( Authentication auth : authentications )
439         {
440             List<String> servers = auth.getServers();
441             if ( !servers.isEmpty() )
442             {
443                 org.eclipse.aether.repository.Authentication a = ConverterUtils.toAuthentication( auth );
444                 for ( String server : servers )
445                 {
446                     if ( ids.add( server ) )
447                     {
448                         selector.add( server, a );
449                     }
450                 }
451             }
452         }
453 
454         Settings settings = getSettings();
455         for ( Server server : settings.getServers() )
456         {
457             AuthenticationBuilder auth = new AuthenticationBuilder();
458             auth.addUsername( server.getUsername() ).addPassword( server.getPassword() );
459             auth.addPrivateKey( server.getPrivateKey(), server.getPassphrase() );
460             selector.add( server.getId(), auth.build() );
461         }
462 
463         return new ConservativeAuthenticationSelector( selector );
464     }
465 
466     private RemoteRepositories getRemoteRepositories()
467     {
468         RemoteRepositories remoteRepositories = new RemoteRepositories();
469         remoteRepositories.setProject( project );
470 
471         Settings settings = getSettings();
472         List<String> activeProfiles = settings.getActiveProfiles();
473         for ( String profileId : activeProfiles )
474         {
475             Profile profile = settings.getProfilesAsMap().get( profileId );
476             for ( Repository repository : profile.getRepositories() )
477             {
478                 String id = repository.getId();
479                 RemoteRepository repo = new RemoteRepository();
480                 repo.setProject( project );
481                 repo.setId( id );
482                 repo.setUrl( repository.getUrl() );
483                 if ( repository.getReleases() != null )
484                 {
485                     RepositoryPolicy repositoryPolicy = repository.getReleases();
486                     Policy policy = new Policy();
487                     policy.setEnabled( repositoryPolicy.isEnabled() );
488                     if ( repositoryPolicy.getChecksumPolicy() != null )
489                     {
490                         policy.setChecksums( repositoryPolicy.getChecksumPolicy() );
491                     }
492                     if ( repositoryPolicy.getUpdatePolicy() != null )
493                     {
494                         policy.setUpdates( repositoryPolicy.getUpdatePolicy() );
495                     }
496                     repo.addReleases( policy );
497                 }
498                 if ( repository.getSnapshots() != null )
499                 {
500                     RepositoryPolicy repositoryPolicy = repository.getSnapshots();
501                     Policy policy = new Policy();
502                     policy.setEnabled( repositoryPolicy.isEnabled() );
503                     if ( repositoryPolicy.getChecksumPolicy() != null )
504                     {
505                         policy.setChecksums( repositoryPolicy.getChecksumPolicy() );
506                     }
507                     if ( repositoryPolicy.getUpdatePolicy() != null )
508                     {
509                         policy.setUpdates( repositoryPolicy.getUpdatePolicy() );
510                     }
511                     repo.addSnapshots( policy );
512                 }
513                 project.addReference( id, repo );
514 
515                 repo = new RemoteRepository();
516                 repo.setProject( project );
517                 repo.setRefid( new Reference( project, id ) );
518                 remoteRepositories.addRemoterepo( repo );
519             }
520         }
521 
522         return remoteRepositories;
523     }
524 
525     private RemoteRepositories getMergedRepositories()
526     {
527         RemoteRepositories defaultRepositories = AetherUtils.getDefaultRepositories( project );
528         RemoteRepositories settingsRepositories = getRemoteRepositories();
529 
530         RemoteRepositories mergedRepositories = new RemoteRepositories();
531         mergedRepositories.setProject( project );
532         mergedRepositories.addRemoterepos( defaultRepositories );
533         mergedRepositories.addRemoterepos( settingsRepositories );
534 
535         return mergedRepositories;
536     }
537 
538     public synchronized void setUserSettings( File file )
539     {
540         if ( !eq( this.userSettings, file ) )
541         {
542             settings = null;
543         }
544         this.userSettings = file;
545     }
546 
547     /* UT */File getUserSettings()
548     {
549         if ( userSettings == null )
550         {
551             userSettings = AetherUtils.findUserSettings( project );
552         }
553         return userSettings;
554     }
555 
556     public void setGlobalSettings( File file )
557     {
558         if ( !eq( this.globalSettings, file ) )
559         {
560             settings = null;
561         }
562         this.globalSettings = file;
563     }
564 
565     /* UT */File getGlobalSettings()
566     {
567         if ( globalSettings == null )
568         {
569             globalSettings = AetherUtils.findGlobalSettings( project );
570         }
571         return globalSettings;
572     }
573 
574     public void addProxy( Proxy proxy )
575     {
576         proxies.add( proxy );
577     }
578 
579     public void addMirror( Mirror mirror )
580     {
581         mirrors.add( mirror );
582     }
583 
584     public void addAuthentication( Authentication authentication )
585     {
586         authentications.add( authentication );
587     }
588 
589     public void setLocalRepository( LocalRepository localRepository )
590     {
591         this.localRepository = localRepository;
592     }
593 
594     public Model loadModel( Task task, File pomFile, boolean local, RemoteRepositories remoteRepositories )
595     {
596         RepositorySystemSession session = getSession( task, null );
597 
598         remoteRepositories =
599             remoteRepositories == null ? getMergedRepositories() : remoteRepositories;
600 
601         List<org.eclipse.aether.repository.RemoteRepository> repositories =
602             ConverterUtils.toRepositories( task.getProject(), session, remoteRepositories, getRemoteRepoMan() );
603 
604         ModelResolver modelResolver =
605             new AntModelResolver( session, "project", getSystem(), getRemoteRepoMan(), repositories );
606 
607         Settings settings = getSettings();
608 
609         try
610         {
611             DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
612             request.setLocationTracking( true );
613             request.setProcessPlugins( false );
614             if ( local )
615             {
616                 request.setPomFile( pomFile );
617                 request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
618             }
619             else
620             {
621                 request.setModelSource( new FileModelSource( pomFile ) );
622                 request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
623             }
624             request.setSystemProperties( getSystemProperties() );
625             request.setUserProperties( getUserProperties() );
626             request.setProfiles( SettingsUtils.convert( settings.getProfiles() ) );
627             request.setActiveProfileIds( settings.getActiveProfiles() );
628             request.setModelResolver( modelResolver );
629             return MODEL_BUILDER.build( request ).getEffectiveModel();
630         }
631         catch ( ModelBuildingException e )
632         {
633             throw new BuildException( "Could not load POM " + pomFile + ": " + e.getMessage(), e );
634         }
635     }
636 
637     private Properties getSystemProperties()
638     {
639         Properties props = new Properties();
640         getEnvProperties( props );
641         props.putAll( System.getProperties() );
642         ConverterUtils.addProperties( props, project.getProperties() );
643         return props;
644     }
645 
646     private Properties getEnvProperties( Properties props )
647     {
648         if ( props == null )
649         {
650             props = new Properties();
651         }
652         boolean envCaseInsensitive = OS_WINDOWS;
653         for ( Map.Entry<String, String> entry : System.getenv().entrySet() )
654         {
655             String key = entry.getKey();
656             if ( envCaseInsensitive )
657             {
658                 key = key.toUpperCase( Locale.ENGLISH );
659             }
660             key = "env." + key;
661             props.put( key, entry.getValue() );
662         }
663         return props;
664     }
665 
666     private Properties getUserProperties()
667     {
668         return ConverterUtils.addProperties( null, project.getUserProperties() );
669     }
670 
671     /**
672      * Sets the default POM.
673      */
674     public void setDefaultPom( Pom pom )
675     {
676         this.defaultPom = pom;
677     }
678 
679     /**
680      * Returns the current default POM.
681      */
682     public Pom getDefaultPom()
683     {
684         return defaultPom;
685     }
686 
687     public CollectResult collectDependencies( Task task, Dependencies dependencies, LocalRepository localRepository,
688                                               RemoteRepositories remoteRepositories )
689     {
690         RepositorySystemSession session = getSession( task, localRepository );
691 
692         remoteRepositories =
693             remoteRepositories == null ? getMergedRepositories() : remoteRepositories;
694 
695         List<org.eclipse.aether.repository.RemoteRepository> repos =
696             ConverterUtils.toRepositories( project, session, remoteRepositories, getRemoteRepoMan() );
697 
698         CollectRequest collectRequest = new CollectRequest();
699         collectRequest.setRequestContext( "project" );
700 
701         for ( org.eclipse.aether.repository.RemoteRepository repo : repos )
702         {
703             task.getProject().log( "Using remote repository " + repo, Project.MSG_VERBOSE );
704             collectRequest.addRepository( repo );
705         }
706 
707         if ( dependencies != null )
708         {
709             populateCollectRequest( collectRequest, task, session, dependencies, Collections.<Exclusion>emptyList() );
710         }
711 
712         task.getProject().log( "Collecting dependencies", Project.MSG_VERBOSE );
713 
714         CollectResult result;
715         try
716         {
717             result = getSystem().collectDependencies( session, collectRequest );
718         }
719         catch ( DependencyCollectionException e )
720         {
721             throw new BuildException( "Could not collect dependencies: " + e.getMessage(), e );
722         }
723 
724         return result;
725     }
726 
727     private void populateCollectRequest( CollectRequest collectRequest, Task task, RepositorySystemSession session,
728                                          Dependencies dependencies, List<Exclusion> exclusions )
729     {
730         List<Exclusion> globalExclusions = exclusions;
731         if ( !dependencies.getExclusions().isEmpty() )
732         {
733             globalExclusions = new ArrayList<Exclusion>( exclusions );
734             globalExclusions.addAll( dependencies.getExclusions() );
735         }
736 
737         Collection<String> ids = new HashSet<String>();
738 
739         for ( DependencyContainer container : dependencies.getDependencyContainers() )
740         {
741             if ( container instanceof Dependency )
742             {
743                 Dependency dep = (Dependency) container;
744                 ids.add( dep.getVersionlessKey() );
745                 collectRequest.addDependency( ConverterUtils.toDependency( dep, globalExclusions, session ) );
746             }
747             else
748             {
749                 populateCollectRequest( collectRequest, task, session, (Dependencies) container, globalExclusions );
750             }
751         }
752 
753         if ( dependencies.getPom() != null )
754         {
755             Model model = dependencies.getPom().getModel( task );
756             for ( org.apache.maven.model.Dependency dep : model.getDependencies() )
757             {
758                 Dependency dependency = new Dependency();
759                 dependency.setArtifactId( dep.getArtifactId() );
760                 dependency.setClassifier( dep.getClassifier() );
761                 dependency.setGroupId( dep.getGroupId() );
762                 dependency.setScope( dep.getScope() );
763                 dependency.setType( dep.getType() );
764                 dependency.setVersion( dep.getVersion() );
765                 if ( ids.contains( dependency.getVersionlessKey() ) )
766                 {
767                     project.log( "Ignoring dependency " + dependency.getVersionlessKey() + " from " + model.getId()
768                         + ", already declared locally", Project.MSG_VERBOSE );
769                     continue;
770                 }
771                 if ( dep.getSystemPath() != null && dep.getSystemPath().length() > 0 )
772                 {
773                     dependency.setSystemPath( task.getProject().resolveFile( dep.getSystemPath() ) );
774                 }
775                 for ( org.apache.maven.model.Exclusion exc : dep.getExclusions() )
776                 {
777                     Exclusion exclusion = new Exclusion();
778                     exclusion.setGroupId( exc.getGroupId() );
779                     exclusion.setArtifactId( exc.getArtifactId() );
780                     exclusion.setClassifier( "*" );
781                     exclusion.setExtension( "*" );
782                     dependency.addExclusion( exclusion );
783                 }
784                 collectRequest.addDependency( ConverterUtils.toDependency( dependency, globalExclusions, session ) );
785             }
786         }
787 
788         if ( dependencies.getFile() != null )
789         {
790             List<Dependency> deps = readDependencies( dependencies.getFile() );
791             for ( Dependency dependency : deps )
792             {
793                 if ( ids.contains( dependency.getVersionlessKey() ) )
794                 {
795                     project.log( "Ignoring dependency " + dependency.getVersionlessKey() + " from "
796                                      + dependencies.getFile() + ", already declared locally", Project.MSG_VERBOSE );
797                     continue;
798                 }
799                 collectRequest.addDependency( ConverterUtils.toDependency( dependency, globalExclusions, session ) );
800             }
801         }
802     }
803 
804     private List<Dependency> readDependencies( File file )
805     {
806         List<Dependency> dependencies = new ArrayList<Dependency>();
807         try
808         {
809             BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( file ), "UTF-8" ) );
810             try
811             {
812                 for ( String line = reader.readLine(); line != null; line = reader.readLine() )
813                 {
814                     int comment = line.indexOf( '#' );
815                     if ( comment >= 0 )
816                     {
817                         line = line.substring( 0, comment );
818                     }
819                     line = line.trim();
820                     if ( line.length() <= 0 )
821                     {
822                         continue;
823                     }
824                     Dependency dependency = new Dependency();
825                     dependency.setCoords( line );
826                     dependencies.add( dependency );
827                 }
828             }
829             finally
830             {
831                 reader.close();
832             }
833         }
834         catch ( IOException e )
835         {
836             throw new BuildException( "Cannot read " + file, e );
837         }
838         return dependencies;
839     }
840 
841     public void install( Task task, Pom pom, Artifacts artifacts )
842     {
843         RepositorySystemSession session = getSession( task, null );
844 
845         InstallRequest request = new InstallRequest();
846         request.setArtifacts( toArtifacts( task, session, pom, artifacts ) );
847 
848         try
849         {
850             getSystem().install( session, request );
851         }
852         catch ( InstallationException e )
853         {
854             throw new BuildException( "Could not install artifacts: " + e.getMessage(), e );
855         }
856     }
857 
858     public void deploy( Task task, Pom pom, Artifacts artifacts, RemoteRepository releaseRepository,
859                         RemoteRepository snapshotRepository )
860     {
861         RepositorySystemSession session = getSession( task, null );
862 
863         DeployRequest request = new DeployRequest();
864         request.setArtifacts( toArtifacts( task, session, pom, artifacts ) );
865         boolean snapshot = request.getArtifacts().iterator().next().isSnapshot();
866         RemoteRepository distRepo = ( snapshot && snapshotRepository != null ) ? snapshotRepository : releaseRepository;
867         request.setRepository( ConverterUtils.toDistRepository( distRepo, session ) );
868 
869         try
870         {
871             getSystem().deploy( session, request );
872         }
873         catch ( DeploymentException e )
874         {
875             throw new BuildException( "Could not deploy artifacts: " + e.getMessage(), e );
876         }
877     }
878 
879     private List<org.eclipse.aether.artifact.Artifact> toArtifacts( Task task, RepositorySystemSession session,
880                                                                     Pom pom, Artifacts artifacts )
881     {
882         Model model = pom.getModel( task );
883         File pomFile = pom.getFile();
884 
885         List<org.eclipse.aether.artifact.Artifact> results = new ArrayList<org.eclipse.aether.artifact.Artifact>();
886 
887         org.eclipse.aether.artifact.Artifact pomArtifact =
888             new DefaultArtifact( model.getGroupId(), model.getArtifactId(), "pom", model.getVersion() ).setFile( pomFile );
889         results.add( pomArtifact );
890 
891         for ( Artifact artifact : artifacts.getArtifacts() )
892         {
893             org.eclipse.aether.artifact.Artifact buildArtifact =
894                 new DefaultArtifact( model.getGroupId(), model.getArtifactId(), artifact.getClassifier(),
895                                      artifact.getType(), model.getVersion() ).setFile( artifact.getFile() );
896             results.add( buildArtifact );
897         }
898 
899         return results;
900     }
901 
902 }