1 package org.apache.maven.artifact.ant;
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.factory.ArtifactFactory;
24 import org.apache.maven.artifact.manager.WagonManager;
25 import org.apache.maven.artifact.repository.ArtifactRepository;
26 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
27 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
28 import org.apache.maven.artifact.repository.DefaultArtifactRepository;
29 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
30 import org.apache.maven.profiles.DefaultProfileManager;
31 import org.apache.maven.profiles.ProfileManager;
32 import org.apache.maven.project.MavenProject;
33 import org.apache.maven.project.MavenProjectBuilder;
34 import org.apache.maven.project.ProjectBuildingException;
35 import org.apache.maven.settings.Mirror;
36 import org.apache.maven.settings.RuntimeInfo;
37 import org.apache.maven.settings.Server;
38 import org.apache.maven.settings.Settings;
39 import org.apache.maven.settings.SettingsUtils;
40 import org.apache.maven.settings.TrackableBase;
41 import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader;
42 import org.apache.maven.usability.diagnostics.ErrorDiagnostics;
43 import org.apache.maven.wagon.Wagon;
44 import org.apache.tools.ant.BuildException;
45 import org.apache.tools.ant.Project;
46 import org.apache.tools.ant.Task;
47 import org.apache.tools.ant.taskdefs.Execute;
48 import org.codehaus.classworlds.ClassWorld;
49 import org.codehaus.classworlds.DuplicateRealmException;
50 import org.codehaus.plexus.PlexusContainer;
51 import org.codehaus.plexus.PlexusContainerException;
52 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
53 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
54 import org.codehaus.plexus.embed.Embedder;
55 import org.codehaus.plexus.util.IOUtil;
56 import org.codehaus.plexus.util.ReaderFactory;
57 import org.codehaus.plexus.util.StringUtils;
58 import org.codehaus.plexus.util.interpolation.EnvarBasedValueSource;
59 import org.codehaus.plexus.util.interpolation.RegexBasedInterpolator;
60 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
61
62 import java.io.File;
63 import java.io.IOException;
64 import java.io.Reader;
65 import java.io.StringReader;
66 import java.io.StringWriter;
67 import java.util.ArrayList;
68 import java.util.Iterator;
69 import java.util.List;
70 import java.util.Map;
71
72
73
74
75
76
77
78 public abstract class AbstractArtifactTask
79 extends Task
80 {
81 private static ClassLoader plexusClassLoader;
82
83 private File userSettingsFile;
84
85 private File globalSettingsFile;
86
87 private Settings settings;
88
89 private ProfileManager profileManager;
90
91 private PlexusContainer container;
92
93 private Pom pom;
94
95 private String pomRefId;
96
97 private LocalRepository localRepository;
98
99 protected ArtifactRepository createLocalArtifactRepository()
100 {
101 if ( localRepository == null )
102 {
103 localRepository = getDefaultLocalRepository();
104 }
105
106 ArtifactRepositoryLayout repositoryLayout =
107 (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, localRepository.getLayout() );
108
109 return new DefaultArtifactRepository( "local", "file://" + localRepository.getPath(), repositoryLayout );
110 }
111
112
113
114
115
116
117
118 protected ArtifactRepositoryFactory getArtifactRepositoryFactory( RemoteRepository repository )
119 {
120 WagonManager manager = (WagonManager) lookup( WagonManager.ROLE );
121
122 Authentication authentication = repository.getAuthentication();
123 if ( authentication != null )
124 {
125 manager.addAuthenticationInfo( repository.getId(), authentication.getUserName(),
126 authentication.getPassword(), authentication.getPrivateKey(),
127 authentication.getPassphrase() );
128 }
129
130 Proxy proxy = repository.getProxy();
131 if ( proxy != null )
132 {
133 manager.addProxy( proxy.getType(), proxy.getHost(), proxy.getPort(), proxy.getUserName(),
134 proxy.getPassword(), proxy.getNonProxyHosts() );
135 }
136
137 return (ArtifactRepositoryFactory) lookup( ArtifactRepositoryFactory.ROLE );
138 }
139
140 protected void releaseArtifactRepositoryFactory( ArtifactRepositoryFactory repositoryFactory )
141 {
142 try
143 {
144 getContainer().release( repositoryFactory );
145 }
146 catch ( ComponentLifecycleException e )
147 {
148
149 }
150 }
151
152
153
154
155
156
157 protected ArtifactRepository createRemoteArtifactRepository( RemoteRepository repository )
158 {
159 ArtifactRepositoryLayout repositoryLayout =
160 (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, repository.getLayout() );
161
162 ArtifactRepositoryFactory repositoryFactory = null;
163
164 ArtifactRepository artifactRepository;
165
166 try
167 {
168 repositoryFactory = getArtifactRepositoryFactory( repository );
169
170 ArtifactRepositoryPolicy snapshots = buildArtifactRepositoryPolicy( repository.getSnapshots() );
171 ArtifactRepositoryPolicy releases = buildArtifactRepositoryPolicy( repository.getReleases() );
172
173 artifactRepository = repositoryFactory.createArtifactRepository( repository.getId(), repository.getUrl(),
174 repositoryLayout, snapshots, releases );
175 }
176 finally
177 {
178 releaseArtifactRepositoryFactory( repositoryFactory );
179 }
180
181 return artifactRepository;
182 }
183
184 private static ArtifactRepositoryPolicy buildArtifactRepositoryPolicy( RepositoryPolicy policy )
185 {
186 boolean enabled = true;
187 String updatePolicy = null;
188 String checksumPolicy = null;
189
190 if ( policy != null )
191 {
192 enabled = policy.isEnabled();
193 if ( policy.getUpdatePolicy() != null )
194 {
195 updatePolicy = policy.getUpdatePolicy();
196 }
197 if ( policy.getChecksumPolicy() != null )
198 {
199 checksumPolicy = policy.getChecksumPolicy();
200 }
201 }
202
203 return new ArtifactRepositoryPolicy( enabled, updatePolicy, checksumPolicy );
204 }
205
206 protected LocalRepository getDefaultLocalRepository()
207 {
208 Settings settings = getSettings();
209 LocalRepository localRepository = new LocalRepository();
210 localRepository.setId( "local" );
211 localRepository.setPath( new File( settings.getLocalRepository() ) );
212 return localRepository;
213 }
214
215 protected synchronized Settings getSettings()
216 {
217 if ( settings == null )
218 {
219 initSettings();
220 }
221 return settings;
222 }
223
224 private File newFile( String parent, String subdir, String filename )
225 {
226 return new File( new File( parent, subdir ), filename );
227 }
228
229 private void initSettings()
230 {
231 if ( userSettingsFile == null )
232 {
233 File tempSettingsFile = newFile( System.getProperty( "user.home" ), ".ant", "settings.xml" );
234 if ( tempSettingsFile.exists() )
235 {
236 userSettingsFile = tempSettingsFile;
237 }
238 else
239 {
240 tempSettingsFile = newFile( System.getProperty( "user.home" ), ".m2", "settings.xml" );
241 if ( tempSettingsFile.exists() )
242 {
243 userSettingsFile = tempSettingsFile;
244 }
245 }
246 }
247 if ( globalSettingsFile == null )
248 {
249 File tempSettingsFile = newFile( System.getProperty( "ant.home" ), "etc", "settings.xml" );
250 if ( tempSettingsFile.exists() )
251 {
252 globalSettingsFile = tempSettingsFile;
253 }
254 else
255 {
256
257 List env = Execute.getProcEnvironment();
258 for ( Iterator iter = env.iterator(); iter.hasNext(); )
259 {
260 String var = (String) iter.next();
261 if ( var.startsWith( "M2_HOME=" ) )
262 {
263 String m2Home = var.substring( "M2_HOME=".length() );
264 tempSettingsFile = newFile( m2Home, "conf", "settings.xml" );
265 if ( tempSettingsFile.exists() )
266 {
267 globalSettingsFile = tempSettingsFile;
268 }
269 break;
270 }
271 }
272 }
273 }
274
275 Settings userSettings = loadSettings( userSettingsFile );
276 Settings globalSettings = loadSettings( globalSettingsFile );
277
278 SettingsUtils.merge( userSettings, globalSettings, TrackableBase.GLOBAL_LEVEL );
279 settings = userSettings;
280
281 if ( StringUtils.isEmpty( settings.getLocalRepository() ) )
282 {
283 String location = newFile( System.getProperty( "user.home" ), ".m2", "repository" ).getAbsolutePath();
284 settings.setLocalRepository( location );
285 }
286
287 WagonManager wagonManager = (WagonManager) lookup( WagonManager.ROLE );
288 wagonManager.setDownloadMonitor( new AntDownloadMonitor() );
289 if ( settings.isOffline() )
290 {
291 log( "You are working in offline mode.", Project.MSG_INFO );
292 wagonManager.setOnline( false );
293 }
294 else
295 {
296 wagonManager.setOnline( true );
297 }
298 }
299
300 private Settings loadSettings( File settingsFile )
301 {
302 Settings settings = null;
303 try
304 {
305 if ( settingsFile != null )
306 {
307 log( "Loading Maven settings file: " + settingsFile.getPath(), Project.MSG_VERBOSE );
308 settings = readSettings( settingsFile );
309 }
310 }
311 catch ( IOException e )
312 {
313 log( "Error reading settings file '" + settingsFile + "' - ignoring. Error was: " + e.getMessage(),
314 Project.MSG_WARN );
315 }
316 catch ( XmlPullParserException e )
317 {
318 log( "Error parsing settings file '" + settingsFile + "' - ignoring. Error was: " + e.getMessage(),
319 Project.MSG_WARN );
320 }
321
322 if ( settings == null )
323 {
324 settings = new Settings();
325 RuntimeInfo rtInfo = new RuntimeInfo( settings );
326 settings.setRuntimeInfo( rtInfo );
327 }
328
329 return settings;
330 }
331
332 public void setSettingsFile( File settingsFile )
333 {
334 if ( !settingsFile.exists() )
335 {
336 throw new BuildException( "settingsFile does not exist: " + settingsFile.getAbsolutePath() );
337 }
338
339 userSettingsFile = settingsFile;
340 settings = null;
341 }
342
343
344
345
346 private Settings readSettings( File settingsFile )
347 throws IOException, XmlPullParserException
348 {
349 Settings settings = null;
350 Reader reader = null;
351 try
352 {
353 reader = ReaderFactory.newXmlReader( settingsFile );
354 StringWriter sWriter = new StringWriter();
355
356 IOUtil.copy( reader, sWriter );
357
358 String rawInput = sWriter.toString();
359
360 try
361 {
362 RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
363 interpolator.addValueSource( new EnvarBasedValueSource() );
364
365 rawInput = interpolator.interpolate( rawInput, "settings" );
366 }
367 catch ( Exception e )
368 {
369 log( "Failed to initialize environment variable resolver. Skipping environment substitution in "
370 + "settings." );
371 }
372
373 StringReader sReader = new StringReader( rawInput );
374
375 SettingsXpp3Reader modelReader = new SettingsXpp3Reader();
376
377 settings = modelReader.read( sReader );
378
379 RuntimeInfo rtInfo = new RuntimeInfo( settings );
380
381 rtInfo.setFile( settingsFile );
382
383 settings.setRuntimeInfo( rtInfo );
384 }
385 finally
386 {
387 IOUtil.close( reader );
388 }
389 return settings;
390 }
391
392 protected RemoteRepository createAntRemoteRepository( org.apache.maven.model.Repository pomRepository )
393 {
394 RemoteRepository r = createAntRemoteRepositoryBase( pomRepository );
395
396 if ( pomRepository.getSnapshots() != null )
397 {
398 r.addSnapshots( convertRepositoryPolicy( pomRepository.getSnapshots() ) );
399 }
400 if ( pomRepository.getReleases() != null )
401 {
402 r.addReleases( convertRepositoryPolicy( pomRepository.getReleases() ) );
403 }
404
405 return r;
406 }
407
408 protected RemoteRepository createAntRemoteRepositoryBase( org.apache.maven.model.RepositoryBase pomRepository )
409 {
410 RemoteRepository r = new RemoteRepository();
411 r.setId( pomRepository.getId() );
412 r.setUrl( pomRepository.getUrl() );
413 r.setLayout( pomRepository.getLayout() );
414
415 updateRepositoryWithSettings( r );
416 return r;
417 }
418
419 protected void updateRepositoryWithSettings( RemoteRepository repository )
420 {
421
422
423
424
425 if ( repository.getAuthentication() == null )
426 {
427 Server server = getSettings().getServer( repository.getId() );
428 if ( server != null )
429 {
430 repository.addAuthentication( new Authentication( server ) );
431 }
432 }
433
434 if ( repository.getProxy() == null )
435 {
436 org.apache.maven.settings.Proxy proxy = getSettings().getActiveProxy();
437 if ( proxy != null )
438 {
439 repository.addProxy( new Proxy( proxy ) );
440 }
441 }
442
443 Mirror mirror = getSettings().getMirrorOf( repository.getId() );
444 if ( mirror == null )
445 {
446 mirror = getSettings().getMirrorOf( "*" );
447 }
448 if ( mirror != null )
449 {
450 repository.setUrl( mirror.getUrl() );
451 }
452 }
453
454 protected Object lookup( String role )
455 {
456 try
457 {
458 return getContainer().lookup( role );
459 }
460 catch ( ComponentLookupException e )
461 {
462 throw new BuildException( "Unable to find component: " + role, e );
463 }
464 }
465
466 protected Object lookup( String role,
467 String roleHint )
468 {
469 try
470 {
471 return getContainer().lookup( role, roleHint );
472 }
473 catch ( ComponentLookupException e )
474 {
475 throw new BuildException( "Unable to find component: " + role + "[" + roleHint + "]", e );
476 }
477 }
478
479 protected synchronized PlexusContainer getContainer()
480 {
481 if ( container == null )
482 {
483 container = (PlexusContainer) getProject().getReference( PlexusContainer.class.getName() );
484
485 if ( container == null )
486 {
487 try
488 {
489 ClassWorld classWorld = new ClassWorld();
490
491 classWorld.newRealm( "plexus.core", getClass().getClassLoader() );
492
493 Embedder embedder = new Embedder();
494
495 embedder.start( classWorld );
496
497 container = embedder.getContainer();
498 }
499 catch ( PlexusContainerException e )
500 {
501 throw new BuildException( "Unable to start embedder", e );
502 }
503 catch ( DuplicateRealmException e )
504 {
505 throw new BuildException( "Unable to create embedder ClassRealm", e );
506 }
507
508 getProject().addReference( PlexusContainer.class.getName(), container );
509 }
510 }
511
512 return container;
513 }
514
515 public Pom buildPom( ArtifactRepository localArtifactRepository )
516 {
517 if ( pomRefId != null && pom != null )
518 {
519 throw new BuildException( "You cannot specify both a POM element and a pomrefid element" );
520 }
521
522 Pom pom = this.pom;
523 if ( pomRefId != null )
524 {
525 pom = (Pom) getProject().getReference( pomRefId );
526 if ( pom == null )
527 {
528 throw new BuildException( "Reference '" + pomRefId + "' was not found." );
529 }
530 }
531
532 if ( pom != null )
533 {
534 MavenProjectBuilder projectBuilder = (MavenProjectBuilder) lookup( MavenProjectBuilder.ROLE );
535 pom.initialise( projectBuilder, localArtifactRepository );
536 }
537 return pom;
538 }
539
540 protected Pom createDummyPom( ArtifactRepository localArtifactRepository )
541 {
542 MavenProjectBuilder projectBuilder = (MavenProjectBuilder) lookup( MavenProjectBuilder.ROLE );
543
544 MavenProject mavenProject;
545 try
546 {
547 mavenProject = projectBuilder.buildStandaloneSuperProject( localArtifactRepository, getProfileManager() );
548 }
549 catch ( ProjectBuildingException e )
550 {
551 throw new BuildException( "Unable to create dummy Pom", e );
552 }
553
554 Pom pom = new Pom();
555
556 pom.setMavenProject( mavenProject );
557
558 return pom;
559 }
560
561 protected Artifact createDummyArtifact()
562 {
563 ArtifactFactory factory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
564
565 return factory.createBuildArtifact( "unspecified", "unspecified", "0.0", "jar" );
566 }
567
568 public String[] getSupportedProtocols()
569 {
570 try
571 {
572 Map wagonMap = getContainer().lookupMap( Wagon.ROLE );
573 List protocols = new ArrayList();
574 for ( Iterator iter = wagonMap.entrySet().iterator(); iter.hasNext(); )
575 {
576 Map.Entry entry = (Map.Entry) iter.next();
577 protocols.add( entry.getKey() );
578 }
579 return (String[]) protocols.toArray( new String[protocols.size()] );
580 }
581 catch ( ComponentLookupException e )
582 {
583 throw new BuildException( "Unable to lookup Wagon providers", e );
584 }
585 }
586
587 public String getSupportedProtocolsAsString()
588 {
589 return StringUtils.join( getSupportedProtocols(), ", " );
590 }
591
592 public void diagnoseError( Throwable error )
593 {
594 try
595 {
596 ErrorDiagnostics diagnostics = (ErrorDiagnostics) container.lookup( ErrorDiagnostics.ROLE );
597
598 StringBuffer message = new StringBuffer();
599
600 message.append( "An error has occurred while processing the Maven artifact tasks.\n" );
601 message.append( " Diagnosis:\n\n" );
602
603 message.append( diagnostics.diagnose( error ) );
604
605 message.append( "\n\n" );
606
607 log( message.toString(), Project.MSG_INFO );
608 }
609 catch ( ComponentLookupException e )
610 {
611 log( "Failed to retrieve error diagnoser.", Project.MSG_DEBUG );
612 }
613 }
614
615 public void addPom( Pom pom )
616 {
617 this.pom = pom;
618 }
619
620 public String getPomRefId()
621 {
622 return pomRefId;
623 }
624
625 public void setPomRefId( String pomRefId )
626 {
627 this.pomRefId = pomRefId;
628 }
629
630 public LocalRepository getLocalRepository()
631 {
632 return localRepository;
633 }
634
635 protected ProfileManager getProfileManager()
636 {
637 if ( profileManager == null )
638 {
639 profileManager = new DefaultProfileManager( getContainer(), getSettings(), System.getProperties() );
640 }
641 return profileManager;
642 }
643
644 public void addLocalRepository( LocalRepository localRepository )
645 {
646 this.localRepository = localRepository;
647 }
648
649 public void setProfiles( String profiles )
650 {
651 if ( profiles != null )
652 {
653
654 log( "Profiles not yet supported, ignoring profiles '" + profiles + "'", Project.MSG_WARN );
655
656 }
657 }
658
659 private static RepositoryPolicy convertRepositoryPolicy( org.apache.maven.model.RepositoryPolicy pomRepoPolicy )
660 {
661 RepositoryPolicy policy = new RepositoryPolicy();
662 policy.setEnabled( pomRepoPolicy.isEnabled() );
663 policy.setUpdatePolicy( pomRepoPolicy.getUpdatePolicy() );
664 return policy;
665 }
666
667
668 public void execute()
669 {
670 ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
671 try
672 {
673 if ( plexusClassLoader != null )
674 {
675 Thread.currentThread().setContextClassLoader( plexusClassLoader );
676 }
677 initSettings();
678 doExecute();
679 }
680 catch ( BuildException e )
681 {
682 diagnoseError( e );
683
684 throw e;
685 }
686 finally
687 {
688 plexusClassLoader = Thread.currentThread().getContextClassLoader();
689 Thread.currentThread().setContextClassLoader( originalClassLoader );
690 }
691 }
692
693 protected abstract void doExecute();
694 }