1 package org.apache.maven.artifact.manager;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.artifact.Artifact;
23 import org.apache.maven.artifact.metadata.ArtifactMetadata;
24 import org.apache.maven.artifact.repository.ArtifactRepository;
25 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
26 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
27 import org.apache.maven.artifact.repository.DefaultArtifactRepository;
28 import org.apache.maven.wagon.ConnectionException;
29 import org.apache.maven.wagon.ResourceDoesNotExistException;
30 import org.apache.maven.wagon.TransferFailedException;
31 import org.apache.maven.wagon.UnsupportedProtocolException;
32 import org.apache.maven.wagon.Wagon;
33 import org.apache.maven.wagon.authentication.AuthenticationException;
34 import org.apache.maven.wagon.authentication.AuthenticationInfo;
35 import org.apache.maven.wagon.authorization.AuthorizationException;
36 import org.apache.maven.wagon.events.TransferListener;
37 import org.apache.maven.wagon.observers.ChecksumObserver;
38 import org.apache.maven.wagon.proxy.ProxyInfo;
39 import org.apache.maven.wagon.proxy.ProxyInfoProvider;
40 import org.apache.maven.wagon.repository.Repository;
41 import org.apache.maven.wagon.repository.RepositoryPermissions;
42 import org.codehaus.plexus.PlexusConstants;
43 import org.codehaus.plexus.PlexusContainer;
44 import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
45 import org.codehaus.plexus.component.configurator.ComponentConfigurator;
46 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
47 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
48 import org.codehaus.plexus.configuration.PlexusConfiguration;
49 import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
50 import org.codehaus.plexus.context.Context;
51 import org.codehaus.plexus.context.ContextException;
52 import org.codehaus.plexus.logging.AbstractLogEnabled;
53 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
54 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
55 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
56 import org.codehaus.plexus.util.FileUtils;
57 import org.codehaus.plexus.util.IOUtil;
58 import org.codehaus.plexus.util.xml.Xpp3Dom;
59
60 import java.io.File;
61 import java.io.IOException;
62 import java.io.InputStream;
63 import java.net.MalformedURLException;
64 import java.net.URL;
65 import java.security.NoSuchAlgorithmException;
66 import java.util.Collection;
67 import java.util.HashMap;
68 import java.util.Iterator;
69 import java.util.LinkedHashMap;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.Properties;
73 import java.util.Set;
74
75 public class DefaultWagonManager
76 extends AbstractLogEnabled
77 implements WagonManager, Contextualizable, Initializable
78 {
79 private static final String WILDCARD = "*";
80
81 private static final String EXTERNAL_WILDCARD = "external:*";
82
83 private static final String MAVEN_ARTIFACT_PROPERTIES = "META-INF/maven/org.apache.maven/maven-artifact/pom.properties";
84
85 private static int anonymousMirrorIdSeed = 0;
86
87 private PlexusContainer container;
88
89
90
91 private Map proxies = new HashMap();
92
93 private Map authenticationInfoMap = new HashMap();
94
95 private Map serverPermissionsMap = new HashMap();
96
97
98 private Map mirrors = new LinkedHashMap();
99
100
101 private Map serverConfigurationMap = new HashMap();
102
103 private TransferListener downloadMonitor;
104
105 private boolean online = true;
106
107 private ArtifactRepositoryFactory repositoryFactory;
108
109 private boolean interactive = true;
110
111 private Map availableWagons = new HashMap();
112
113 private RepositoryPermissions defaultRepositoryPermissions;
114
115 private String httpUserAgent;
116
117
118 public Wagon getWagon( Repository repository )
119 throws UnsupportedProtocolException, WagonConfigurationException
120 {
121 String protocol = repository.getProtocol();
122
123 if ( protocol == null )
124 {
125 throw new UnsupportedProtocolException( "The repository " + repository + " does not specify a protocol" );
126 }
127
128 Wagon wagon = getWagon( protocol );
129
130 configureWagon( wagon, repository.getId(), protocol );
131
132 return wagon;
133 }
134
135 public Wagon getWagon( String protocol )
136 throws UnsupportedProtocolException
137 {
138 PlexusContainer container = getWagonContainer( protocol );
139
140 Wagon wagon;
141 try
142 {
143 wagon = (Wagon) container.lookup( Wagon.ROLE, protocol );
144 }
145 catch ( ComponentLookupException e1 )
146 {
147 throw new UnsupportedProtocolException(
148 "Cannot find wagon which supports the requested protocol: " + protocol, e1 );
149 }
150
151 wagon.setInteractive( interactive );
152
153 return wagon;
154 }
155
156 private PlexusContainer getWagonContainer( String protocol )
157 {
158 PlexusContainer container = this.container;
159
160 if ( availableWagons.containsKey( protocol ) )
161 {
162 container = (PlexusContainer) availableWagons.get( protocol );
163 }
164 return container;
165 }
166
167 public void putArtifact( File source,
168 Artifact artifact,
169 ArtifactRepository deploymentRepository )
170 throws TransferFailedException
171 {
172 putRemoteFile( deploymentRepository, source, deploymentRepository.pathOf( artifact ), downloadMonitor );
173 }
174
175 public void putArtifactMetadata( File source,
176 ArtifactMetadata artifactMetadata,
177 ArtifactRepository repository )
178 throws TransferFailedException
179 {
180 getLogger().info( "Uploading " + artifactMetadata );
181 putRemoteFile( repository, source, repository.pathOfRemoteRepositoryMetadata( artifactMetadata ), null );
182 }
183
184 private void putRemoteFile( ArtifactRepository repository,
185 File source,
186 String remotePath,
187 TransferListener downloadMonitor )
188 throws TransferFailedException
189 {
190 failIfNotOnline();
191
192 String protocol = repository.getProtocol();
193
194 Wagon wagon;
195 try
196 {
197 wagon = getWagon( protocol );
198
199 configureWagon( wagon, repository );
200 }
201 catch ( UnsupportedProtocolException e )
202 {
203 throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e );
204 }
205
206 if ( downloadMonitor != null )
207 {
208 wagon.addTransferListener( downloadMonitor );
209 }
210
211 Map checksums = new HashMap( 2 );
212 Map sums = new HashMap( 2 );
213
214
215 try
216 {
217 ChecksumObserver checksumObserver = new ChecksumObserver( "MD5" );
218 wagon.addTransferListener( checksumObserver );
219 checksums.put( "md5", checksumObserver );
220 checksumObserver = new ChecksumObserver( "SHA-1" );
221 wagon.addTransferListener( checksumObserver );
222 checksums.put( "sha1", checksumObserver );
223 }
224 catch ( NoSuchAlgorithmException e )
225 {
226 throw new TransferFailedException( "Unable to add checksum methods: " + e.getMessage(), e );
227 }
228
229 try
230 {
231 Repository artifactRepository = new Repository( repository.getId(), repository.getUrl() );
232
233 if ( serverPermissionsMap.containsKey( repository.getId() ) )
234 {
235 RepositoryPermissions perms = (RepositoryPermissions) serverPermissionsMap.get( repository.getId() );
236
237 getLogger().debug(
238 "adding permissions to wagon connection: " + perms.getFileMode() + " " + perms.getDirectoryMode() );
239
240 artifactRepository.setPermissions( perms );
241 }
242 else
243 {
244 if ( defaultRepositoryPermissions != null )
245 {
246 artifactRepository.setPermissions( defaultRepositoryPermissions );
247 }
248 else
249 {
250 getLogger().debug( "not adding permissions to wagon connection" );
251 }
252 }
253
254 wagon.connect( artifactRepository, getAuthenticationInfo( repository.getId() ), new ProxyInfoProvider()
255 {
256 public ProxyInfo getProxyInfo( String protocol )
257 {
258 return getProxy( protocol );
259 }
260 });
261
262 wagon.put( source, remotePath );
263
264 wagon.removeTransferListener( downloadMonitor );
265
266
267 for ( Iterator i = checksums.keySet().iterator(); i.hasNext(); )
268 {
269 String extension = (String) i.next();
270 ChecksumObserver observer = (ChecksumObserver) checksums.get( extension );
271 sums.put( extension, observer.getActualChecksum() );
272 }
273
274
275 for ( Iterator i = checksums.keySet().iterator(); i.hasNext(); )
276 {
277 String extension = (String) i.next();
278
279
280 File temp = File.createTempFile( "maven-artifact", null );
281 temp.deleteOnExit();
282 FileUtils.fileWrite( temp.getAbsolutePath(), "UTF-8", (String) sums.get( extension ) );
283
284 wagon.put( temp, remotePath + "." + extension );
285 }
286 }
287 catch ( ConnectionException e )
288 {
289 throw new TransferFailedException( "Connection failed: " + e.getMessage(), e );
290 }
291 catch ( AuthenticationException e )
292 {
293 throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e );
294 }
295 catch ( AuthorizationException e )
296 {
297 throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e );
298 }
299 catch ( ResourceDoesNotExistException e )
300 {
301 throw new TransferFailedException( "Resource to deploy not found: " + e.getMessage(), e );
302 }
303 catch ( IOException e )
304 {
305 throw new TransferFailedException( "Error creating temporary file for deployment: " + e.getMessage(), e );
306 }
307 finally
308 {
309 disconnectWagon( wagon );
310
311 releaseWagon( protocol, wagon );
312 }
313 }
314
315 public void getArtifact( Artifact artifact,
316 List remoteRepositories )
317 throws TransferFailedException, ResourceDoesNotExistException
318 {
319
320 boolean successful = false;
321 for ( Iterator iter = remoteRepositories.iterator(); iter.hasNext() && !successful; )
322 {
323 ArtifactRepository repository = (ArtifactRepository) iter.next();
324
325 try
326 {
327 getArtifact( artifact, repository );
328
329 successful = artifact.isResolved();
330 }
331 catch ( ResourceDoesNotExistException e )
332 {
333
334
335
336 getLogger().info( "Unable to find resource '" + artifact.getId() + "' in repository " +
337 repository.getId() + " (" + repository.getUrl() + ")" );
338 }
339 catch ( TransferFailedException e )
340 {
341 getLogger().warn( "Unable to get resource '" + artifact.getId() + "' from repository " +
342 repository.getId() + " (" + repository.getUrl() + "): " + e.getMessage() );
343 }
344 }
345
346
347 if ( !successful && !artifact.getFile().exists() )
348 {
349 throw new ResourceDoesNotExistException( "Unable to download the artifact from any repository" );
350 }
351 }
352
353 public void getArtifact( Artifact artifact,
354 ArtifactRepository repository )
355 throws TransferFailedException, ResourceDoesNotExistException
356 {
357 String remotePath = repository.pathOf( artifact );
358
359 ArtifactRepositoryPolicy policy = artifact.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
360
361 if ( !policy.isEnabled() )
362 {
363 getLogger().debug( "Skipping disabled repository " + repository.getId() );
364 }
365 else if ( repository.isBlacklisted() )
366 {
367 getLogger().debug( "Skipping blacklisted repository " + repository.getId() );
368 }
369 else
370 {
371 getLogger().debug( "Trying repository " + repository.getId() );
372 getRemoteFile( getMirrorRepository( repository ), artifact.getFile(), remotePath, downloadMonitor,
373 policy.getChecksumPolicy(), false );
374 getLogger().debug( " Artifact resolved" );
375
376 artifact.setResolved( true );
377 }
378 }
379
380 public void getArtifactMetadata( ArtifactMetadata metadata,
381 ArtifactRepository repository,
382 File destination,
383 String checksumPolicy )
384 throws TransferFailedException, ResourceDoesNotExistException
385 {
386 String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata );
387
388 getRemoteFile( getMirrorRepository( repository ), destination, remotePath, null, checksumPolicy, true );
389 }
390
391 public void getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, ArtifactRepository repository,
392 File destination, String checksumPolicy )
393 throws TransferFailedException, ResourceDoesNotExistException
394 {
395 String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata );
396
397 getRemoteFile( repository, destination, remotePath, null, checksumPolicy, true );
398 }
399
400 private void getRemoteFile( ArtifactRepository repository,
401 File destination,
402 String remotePath,
403 TransferListener downloadMonitor,
404 String checksumPolicy,
405 boolean force )
406 throws TransferFailedException, ResourceDoesNotExistException
407 {
408
409
410 failIfNotOnline();
411
412 String protocol = repository.getProtocol();
413 Wagon wagon;
414 try
415 {
416 wagon = getWagon( protocol );
417
418 configureWagon( wagon, repository );
419 }
420 catch ( UnsupportedProtocolException e )
421 {
422 throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e );
423 }
424
425 if ( downloadMonitor != null )
426 {
427 wagon.addTransferListener( downloadMonitor );
428 }
429
430 File temp = new File( destination + ".tmp" );
431 temp.deleteOnExit();
432
433 boolean downloaded = false;
434
435 try
436 {
437 getLogger().debug( "Connecting to repository: \'" + repository.getId() + "\' with url: \'" + repository.getUrl() + "\'." );
438
439 wagon.connect( new Repository( repository.getId(), repository.getUrl() ),
440 getAuthenticationInfo( repository.getId() ), new ProxyInfoProvider()
441 {
442 public ProxyInfo getProxyInfo( String protocol )
443 {
444 return getProxy( protocol );
445 }
446 });
447
448 boolean firstRun = true;
449 boolean retry = true;
450
451
452
453
454 while ( firstRun || retry )
455 {
456
457 retry = false;
458
459
460 ChecksumObserver md5ChecksumObserver = null;
461 ChecksumObserver sha1ChecksumObserver = null;
462 try
463 {
464 md5ChecksumObserver = new ChecksumObserver( "MD5" );
465 wagon.addTransferListener( md5ChecksumObserver );
466
467 sha1ChecksumObserver = new ChecksumObserver( "SHA-1" );
468 wagon.addTransferListener( sha1ChecksumObserver );
469
470
471 if ( destination.exists() && !force )
472 {
473 try
474 {
475 downloaded = wagon.getIfNewer( remotePath, temp, destination.lastModified() );
476 if ( !downloaded )
477 {
478
479 destination.setLastModified( System.currentTimeMillis() );
480 }
481 }
482 catch ( UnsupportedOperationException e )
483 {
484
485 wagon.get( remotePath, temp );
486 downloaded = true;
487 }
488 }
489 else
490 {
491 wagon.get( remotePath, temp );
492 downloaded = true;
493 }
494 }
495 catch ( NoSuchAlgorithmException e )
496 {
497 throw new TransferFailedException( "Unable to add checksum methods: " + e.getMessage(), e );
498 }
499 finally
500 {
501 if ( md5ChecksumObserver != null )
502 {
503 wagon.removeTransferListener( md5ChecksumObserver );
504 }
505 if ( sha1ChecksumObserver != null )
506 {
507 wagon.removeTransferListener( sha1ChecksumObserver );
508 }
509 }
510
511 if ( downloaded )
512 {
513
514 if ( downloadMonitor != null )
515 {
516 wagon.removeTransferListener( downloadMonitor );
517 }
518
519
520 try
521 {
522 verifyChecksum( sha1ChecksumObserver, destination, temp, remotePath, ".sha1", wagon );
523 }
524 catch ( ChecksumFailedException e )
525 {
526
527
528
529
530 if ( firstRun )
531 {
532 getLogger().warn( "*** CHECKSUM FAILED - " + e.getMessage() + " - RETRYING" );
533 retry = true;
534 }
535 else
536 {
537 handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() );
538 }
539 }
540 catch ( ResourceDoesNotExistException sha1TryException )
541 {
542 getLogger().debug( "SHA1 not found, trying MD5", sha1TryException );
543
544
545
546 try
547 {
548 verifyChecksum( md5ChecksumObserver, destination, temp, remotePath, ".md5", wagon );
549 }
550 catch ( ChecksumFailedException e )
551 {
552
553
554 if ( firstRun )
555 {
556 retry = true;
557 }
558 else
559 {
560 handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() );
561 }
562 }
563 catch ( ResourceDoesNotExistException md5TryException )
564 {
565
566 handleChecksumFailure( checksumPolicy, "Error retrieving checksum file for " + remotePath,
567 md5TryException );
568 }
569 }
570
571
572 if ( downloadMonitor != null )
573 {
574 wagon.addTransferListener( downloadMonitor );
575 }
576 }
577
578
579 firstRun = false;
580 }
581 }
582 catch ( ConnectionException e )
583 {
584 throw new TransferFailedException( "Connection failed: " + e.getMessage(), e );
585 }
586 catch ( AuthenticationException e )
587 {
588 throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e );
589 }
590 catch ( AuthorizationException e )
591 {
592 throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e );
593 }
594 finally
595 {
596 disconnectWagon( wagon );
597
598 releaseWagon( protocol, wagon );
599 }
600
601 if ( downloaded )
602 {
603 if ( !temp.exists() )
604 {
605 throw new ResourceDoesNotExistException( "Downloaded file does not exist: " + temp );
606 }
607
608
609
610
611
612
613
614 if ( !temp.renameTo( destination ) )
615 {
616 try
617 {
618 FileUtils.copyFile( temp, destination );
619
620 temp.delete();
621 }
622 catch ( IOException e )
623 {
624 throw new TransferFailedException(
625 "Error copying temporary file to the final destination: " + e.getMessage(), e );
626 }
627 }
628 }
629 }
630
631 public ArtifactRepository getMirrorRepository( ArtifactRepository repository )
632 {
633 ArtifactRepository mirror = getMirror( repository );
634 if ( mirror != null )
635 {
636 String id = mirror.getId();
637 if ( id == null )
638 {
639
640 id = repository.getId();
641 }
642
643 getLogger().debug( "Using mirror: " + mirror.getUrl() + " (id: " + id + ")" );
644
645 repository = repositoryFactory.createArtifactRepository( id, mirror.getUrl(),
646 repository.getLayout(), repository.getSnapshots(),
647 repository.getReleases() );
648 }
649 return repository;
650 }
651
652 private void failIfNotOnline()
653 throws TransferFailedException
654 {
655 if ( !isOnline() )
656 {
657 throw new TransferFailedException( "System is offline." );
658 }
659 }
660
661 private void handleChecksumFailure( String checksumPolicy,
662 String message,
663 Throwable cause )
664 throws ChecksumFailedException
665 {
666 if ( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL.equals( checksumPolicy ) )
667 {
668 throw new ChecksumFailedException( message, cause );
669 }
670 else if ( !ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE.equals( checksumPolicy ) )
671 {
672
673 getLogger().warn( "*** CHECKSUM FAILED - " + message + " - IGNORING" );
674 }
675
676 }
677
678 private void verifyChecksum( ChecksumObserver checksumObserver,
679 File destination,
680 File tempDestination,
681 String remotePath,
682 String checksumFileExtension,
683 Wagon wagon )
684 throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException
685 {
686 try
687 {
688
689 String actualChecksum = checksumObserver.getActualChecksum();
690
691 File tempChecksumFile = new File( tempDestination + checksumFileExtension + ".tmp" );
692 tempChecksumFile.deleteOnExit();
693 wagon.get( remotePath + checksumFileExtension, tempChecksumFile );
694
695 String expectedChecksum = FileUtils.fileRead( tempChecksumFile, "UTF-8" );
696
697
698 expectedChecksum = expectedChecksum.trim();
699
700
701 if ( expectedChecksum.regionMatches( true, 0, "MD", 0, 2 )
702 || expectedChecksum.regionMatches( true, 0, "SHA", 0, 3 ) )
703 {
704 int lastSpacePos = expectedChecksum.lastIndexOf( ' ' );
705 expectedChecksum = expectedChecksum.substring( lastSpacePos + 1 );
706 }
707 else
708 {
709
710 int spacePos = expectedChecksum.indexOf( ' ' );
711
712 if ( spacePos != -1 )
713 {
714 expectedChecksum = expectedChecksum.substring( 0, spacePos );
715 }
716 }
717 if ( expectedChecksum.equalsIgnoreCase( actualChecksum ) )
718 {
719 File checksumFile = new File( destination + checksumFileExtension );
720 if ( checksumFile.exists() )
721 {
722 checksumFile.delete();
723 }
724 FileUtils.copyFile( tempChecksumFile, checksumFile );
725 }
726 else
727 {
728 throw new ChecksumFailedException( "Checksum failed on download: local = '" + actualChecksum +
729 "'; remote = '" + expectedChecksum + "'" );
730 }
731 }
732 catch ( IOException e )
733 {
734 throw new ChecksumFailedException( "Invalid checksum file", e );
735 }
736 }
737
738
739 private void disconnectWagon( Wagon wagon )
740 {
741 try
742 {
743 wagon.disconnect();
744 }
745 catch ( ConnectionException e )
746 {
747 getLogger().error( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
748 }
749 }
750
751 private void releaseWagon( String protocol,
752 Wagon wagon )
753 {
754 PlexusContainer container = getWagonContainer( protocol );
755 try
756 {
757 container.release( wagon );
758 }
759 catch ( ComponentLifecycleException e )
760 {
761 getLogger().error( "Problem releasing wagon - ignoring: " + e.getMessage() );
762 }
763 }
764
765 public ProxyInfo getProxy( String protocol )
766 {
767 ProxyInfo info = (ProxyInfo) proxies.get( protocol );
768
769 if ( info != null )
770 {
771 getLogger().debug( "Using Proxy: " + info.getHost() );
772 }
773
774 return info;
775 }
776
777 public AuthenticationInfo getAuthenticationInfo( String id )
778 {
779 return (AuthenticationInfo) authenticationInfoMap.get( id );
780 }
781
782
783
784
785
786
787
788
789 public ArtifactRepository getMirror( ArtifactRepository originalRepository )
790 {
791 ArtifactRepository selectedMirror = (ArtifactRepository) mirrors.get( originalRepository.getId() );
792 if ( null == selectedMirror )
793 {
794
795 Set keySet = mirrors.keySet();
796 if ( keySet != null )
797 {
798 Iterator iter = keySet.iterator();
799 while ( iter.hasNext() )
800 {
801 String pattern = (String) iter.next();
802 if ( matchPattern( originalRepository, pattern ) )
803 {
804 selectedMirror = (ArtifactRepository) mirrors.get( pattern );
805 break;
806 }
807 }
808 }
809
810 }
811 return selectedMirror;
812 }
813
814
815
816
817
818
819
820
821
822
823
824
825
826 public boolean matchPattern( ArtifactRepository originalRepository, String pattern )
827 {
828 boolean result = false;
829 String originalId = originalRepository.getId();
830
831
832 if ( WILDCARD.equals( pattern ) || pattern.equals( originalId ) )
833 {
834 result = true;
835 }
836 else
837 {
838
839 String[] repos = pattern.split( "," );
840 for ( int i = 0; i < repos.length; i++ )
841 {
842 String repo = repos[i];
843
844
845 if ( repo.length() > 1 && repo.startsWith( "!" ) )
846 {
847 if ( originalId.equals( repo.substring( 1 ) ) )
848 {
849
850 result = false;
851 break;
852 }
853 }
854
855 else if ( originalId.equals( repo ) )
856 {
857 result = true;
858 break;
859 }
860
861 else if ( EXTERNAL_WILDCARD.equals( repo ) && isExternalRepo( originalRepository ) )
862 {
863 result = true;
864
865 }
866 else if ( WILDCARD.equals( repo ) )
867 {
868 result = true;
869
870 }
871 }
872 }
873 return result;
874 }
875
876
877
878
879
880
881
882 public boolean isExternalRepo( ArtifactRepository originalRepository )
883 {
884 try
885 {
886 URL url = new URL( originalRepository.getUrl() );
887 return !( url.getHost().equals( "localhost" ) || url.getHost().equals( "127.0.0.1" ) || url.getProtocol().equals(
888 "file" ) );
889 }
890 catch ( MalformedURLException e )
891 {
892
893 return false;
894 }
895 }
896
897
898
899
900
901
902
903
904
905
906
907
908
909 public void addProxy( String protocol,
910 String host,
911 int port,
912 String username,
913 String password,
914 String nonProxyHosts )
915 {
916 ProxyInfo proxyInfo = new ProxyInfo();
917 proxyInfo.setHost( host );
918 proxyInfo.setType( protocol );
919 proxyInfo.setPort( port );
920 proxyInfo.setNonProxyHosts( nonProxyHosts );
921 proxyInfo.setUserName( username );
922 proxyInfo.setPassword( password );
923
924 proxies.put( protocol, proxyInfo );
925 }
926
927 public void contextualize( Context context )
928 throws ContextException
929 {
930 container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
931 }
932
933
934 public void setDownloadMonitor( TransferListener downloadMonitor )
935 {
936 this.downloadMonitor = downloadMonitor;
937 }
938
939 public void addAuthenticationInfo( String repositoryId,
940 String username,
941 String password,
942 String privateKey,
943 String passphrase )
944 {
945 AuthenticationInfo authInfo = new AuthenticationInfo();
946
947 authInfo.setUserName( username );
948
949 authInfo.setPassword( password );
950
951 authInfo.setPrivateKey( privateKey );
952
953 authInfo.setPassphrase( passphrase );
954
955 authenticationInfoMap.put( repositoryId, authInfo );
956 }
957
958 public void addPermissionInfo( String repositoryId,
959 String filePermissions,
960 String directoryPermissions )
961 {
962
963 RepositoryPermissions permissions = new RepositoryPermissions();
964 boolean addPermissions = false;
965
966 if ( filePermissions != null )
967 {
968 permissions.setFileMode( filePermissions );
969 addPermissions = true;
970 }
971
972 if ( directoryPermissions != null )
973 {
974 permissions.setDirectoryMode( directoryPermissions );
975 addPermissions = true;
976 }
977
978 if ( addPermissions )
979 {
980 serverPermissionsMap.put( repositoryId, permissions );
981 }
982 }
983
984 public void addMirror( String id,
985 String mirrorOf,
986 String url )
987 {
988 if ( id == null )
989 {
990 id = "mirror-" + anonymousMirrorIdSeed++;
991 getLogger().warn( "You are using a mirror that doesn't declare an <id/> element. Using \'" + id + "\' instead:\nId: " + id + "\nmirrorOf: " + mirrorOf + "\nurl: " + url + "\n" );
992 }
993
994 ArtifactRepository mirror = new DefaultArtifactRepository( id, url, null );
995
996
997 if (!mirrors.containsKey( mirrorOf ))
998 {
999 mirrors.put( mirrorOf, mirror );
1000 }
1001 }
1002
1003 public void setOnline( boolean online )
1004 {
1005 this.online = online;
1006 }
1007
1008 public boolean isOnline()
1009 {
1010 return online;
1011 }
1012
1013 public void setInteractive( boolean interactive )
1014 {
1015 this.interactive = interactive;
1016 }
1017
1018 public void registerWagons( Collection wagons,
1019 PlexusContainer extensionContainer )
1020 {
1021 for ( Iterator i = wagons.iterator(); i.hasNext(); )
1022 {
1023 availableWagons.put( i.next(), extensionContainer );
1024 }
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034 private void configureWagon( Wagon wagon,
1035 ArtifactRepository repository )
1036 throws WagonConfigurationException
1037 {
1038 configureWagon( wagon, repository.getId(), repository.getProtocol() );
1039 }
1040
1041 private void configureWagon( Wagon wagon, String repositoryId, String protocol )
1042 throws WagonConfigurationException
1043 {
1044 PlexusConfiguration config = (PlexusConfiguration) serverConfigurationMap.get( repositoryId );
1045 if ( protocol.startsWith( "http" ) || protocol.startsWith( "dav" ) )
1046 {
1047 config = updateUserAgentForHttp( wagon, config );
1048 }
1049
1050 if ( config != null )
1051 {
1052 ComponentConfigurator componentConfigurator = null;
1053 try
1054 {
1055 componentConfigurator = (ComponentConfigurator) container.lookup( ComponentConfigurator.ROLE, "wagon" );
1056 componentConfigurator.configureComponent( wagon, config, container.getContainerRealm() );
1057 }
1058 catch ( final ComponentLookupException e )
1059 {
1060 throw new WagonConfigurationException( repositoryId,
1061 "Unable to lookup wagon configurator. Wagon configuration cannot be applied.",
1062 e );
1063 }
1064 catch ( ComponentConfigurationException e )
1065 {
1066 throw new WagonConfigurationException( repositoryId, "Unable to apply wagon configuration.", e );
1067 }
1068 finally
1069 {
1070 if ( componentConfigurator != null )
1071 {
1072 try
1073 {
1074 container.release( componentConfigurator );
1075 }
1076 catch ( ComponentLifecycleException e )
1077 {
1078 getLogger().error( "Problem releasing configurator - ignoring: " + e.getMessage() );
1079 }
1080 }
1081
1082 }
1083 }
1084 }
1085
1086
1087 private PlexusConfiguration updateUserAgentForHttp( Wagon wagon, PlexusConfiguration config )
1088 {
1089 if ( config == null )
1090 {
1091 config = new XmlPlexusConfiguration( "configuration" );
1092 }
1093
1094 if ( httpUserAgent != null )
1095 {
1096 try
1097 {
1098 wagon.getClass().getMethod( "setHttpHeaders", new Class[]{ Properties.class } );
1099
1100 PlexusConfiguration headerConfig = config.getChild( "httpHeaders", true );
1101 PlexusConfiguration[] children = headerConfig.getChildren( "property" );
1102 boolean found = false;
1103
1104 getLogger().debug( "Checking for pre-existing User-Agent configuration." );
1105 for ( int i = 0; i < children.length; i++ )
1106 {
1107 PlexusConfiguration c = children[i].getChild( "name", false );
1108 if ( c != null && "User-Agent".equals( c.getValue( null ) ) )
1109 {
1110 found = true;
1111 break;
1112 }
1113 }
1114
1115 if ( !found )
1116 {
1117 getLogger().debug( "Adding User-Agent configuration." );
1118 XmlPlexusConfiguration propertyConfig = new XmlPlexusConfiguration( "property" );
1119 headerConfig.addChild( propertyConfig );
1120
1121 XmlPlexusConfiguration nameConfig = new XmlPlexusConfiguration( "name" );
1122 nameConfig.setValue( "User-Agent" );
1123 propertyConfig.addChild( nameConfig );
1124
1125 XmlPlexusConfiguration versionConfig = new XmlPlexusConfiguration( "value" );
1126 versionConfig.setValue( httpUserAgent );
1127 propertyConfig.addChild( versionConfig );
1128 }
1129 else
1130 {
1131 getLogger().debug( "User-Agent configuration found." );
1132 }
1133 }
1134 catch ( SecurityException e )
1135 {
1136 getLogger().debug( "setHttpHeaders method not accessible on wagon: " + wagon + "; skipping User-Agent configuration." );
1137
1138 }
1139 catch ( NoSuchMethodException e )
1140 {
1141 getLogger().debug( "setHttpHeaders method not found on wagon: " + wagon + "; skipping User-Agent configuration." );
1142
1143 }
1144 }
1145
1146 return config;
1147 }
1148
1149 public void addConfiguration( String repositoryId,
1150 Xpp3Dom configuration )
1151 {
1152 if ( repositoryId == null || configuration == null )
1153 {
1154 throw new IllegalArgumentException( "arguments can't be null" );
1155 }
1156
1157 final XmlPlexusConfiguration xmlConf = new XmlPlexusConfiguration( configuration );
1158
1159 serverConfigurationMap.put( repositoryId, xmlConf );
1160 }
1161
1162 public void setDefaultRepositoryPermissions( RepositoryPermissions defaultRepositoryPermissions )
1163 {
1164 this.defaultRepositoryPermissions = defaultRepositoryPermissions;
1165 }
1166
1167
1168 public void initialize()
1169 throws InitializationException
1170 {
1171 if ( httpUserAgent == null )
1172 {
1173 InputStream resourceAsStream = null;
1174 try
1175 {
1176 Properties properties = new Properties();
1177 resourceAsStream = getClass().getClassLoader().getResourceAsStream( MAVEN_ARTIFACT_PROPERTIES );
1178
1179 if ( resourceAsStream != null )
1180 {
1181 try
1182 {
1183 properties.load( resourceAsStream );
1184
1185 httpUserAgent =
1186 "maven-artifact/" + properties.getProperty( "version" ) + " (Java "
1187 + System.getProperty( "java.version" ) + "; " + System.getProperty( "os.name" ) + " "
1188 + System.getProperty( "os.version" ) + ")";
1189 }
1190 catch ( IOException e )
1191 {
1192 getLogger().warn(
1193 "Failed to load Maven artifact properties from:\n" + MAVEN_ARTIFACT_PROPERTIES
1194 + "\n\nUser-Agent HTTP header may be incorrect for artifact resolution." );
1195 }
1196 }
1197 }
1198 finally
1199 {
1200 IOUtil.close( resourceAsStream );
1201 }
1202 }
1203 }
1204
1205
1206
1207
1208 public void setHttpUserAgent( String userAgent )
1209 {
1210 this.httpUserAgent = userAgent;
1211 }
1212
1213
1214
1215
1216 public String getHttpUserAgent()
1217 {
1218 return httpUserAgent;
1219 }
1220 }