1 package org.apache.maven.project;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.io.Reader;
26 import java.io.StringReader;
27 import java.net.URL;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Date;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.LinkedHashSet;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Set;
39 import java.util.TreeMap;
40
41 import org.apache.maven.artifact.Artifact;
42 import org.apache.maven.artifact.ArtifactStatus;
43 import org.apache.maven.artifact.ArtifactUtils;
44 import org.apache.maven.artifact.InvalidRepositoryException;
45 import org.apache.maven.artifact.manager.WagonManager;
46 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
47 import org.apache.maven.artifact.repository.ArtifactRepository;
48 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
49 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
50 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
51 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
52 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
53 import org.apache.maven.artifact.resolver.ArtifactResolver;
54 import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
55 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
56 import org.apache.maven.artifact.versioning.ManagedVersionMap;
57 import org.apache.maven.artifact.versioning.VersionRange;
58 import org.apache.maven.model.Build;
59 import org.apache.maven.model.Dependency;
60 import org.apache.maven.model.DependencyManagement;
61 import org.apache.maven.model.DistributionManagement;
62 import org.apache.maven.model.Exclusion;
63 import org.apache.maven.model.Extension;
64 import org.apache.maven.model.Model;
65 import org.apache.maven.model.Parent;
66 import org.apache.maven.model.Plugin;
67 import org.apache.maven.model.PluginExecution;
68 import org.apache.maven.model.PluginManagement;
69 import org.apache.maven.model.Profile;
70 import org.apache.maven.model.ReportPlugin;
71 import org.apache.maven.model.Repository;
72 import org.apache.maven.model.Resource;
73 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
74 import org.apache.maven.profiles.DefaultProfileManager;
75 import org.apache.maven.profiles.MavenProfilesBuilder;
76 import org.apache.maven.profiles.ProfileManager;
77 import org.apache.maven.profiles.ProfilesConversionUtils;
78 import org.apache.maven.profiles.ProfilesRoot;
79 import org.apache.maven.profiles.activation.ProfileActivationException;
80 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
81 import org.apache.maven.project.artifact.ProjectArtifactFactory;
82 import org.apache.maven.project.inheritance.ModelInheritanceAssembler;
83 import org.apache.maven.project.injection.ModelDefaultsInjector;
84 import org.apache.maven.project.injection.ProfileInjector;
85 import org.apache.maven.project.interpolation.ModelInterpolationException;
86 import org.apache.maven.project.interpolation.ModelInterpolator;
87 import org.apache.maven.project.path.PathTranslator;
88 import org.apache.maven.project.validation.ModelValidationResult;
89 import org.apache.maven.project.validation.ModelValidator;
90 import org.apache.maven.wagon.events.TransferListener;
91 import org.codehaus.plexus.PlexusConstants;
92 import org.codehaus.plexus.PlexusContainer;
93 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
94 import org.codehaus.plexus.context.Context;
95 import org.codehaus.plexus.context.ContextException;
96 import org.codehaus.plexus.logging.AbstractLogEnabled;
97 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
98 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
99 import org.codehaus.plexus.util.IOUtil;
100 import org.codehaus.plexus.util.ReaderFactory;
101 import org.codehaus.plexus.util.StringUtils;
102 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 public class DefaultMavenProjectBuilder
142 extends AbstractLogEnabled
143 implements MavenProjectBuilder, Initializable, Contextualizable
144 {
145
146 private PlexusContainer container;
147
148 protected MavenProfilesBuilder profilesBuilder;
149
150 protected ArtifactResolver artifactResolver;
151
152 protected ArtifactMetadataSource artifactMetadataSource;
153
154 private ProjectArtifactFactory artifactFactory;
155
156 private ModelInheritanceAssembler modelInheritanceAssembler;
157
158 private ProfileInjector profileInjector;
159
160 private ModelValidator validator;
161
162 private Map rawProjectCache = new HashMap();
163
164 private Map processedProjectCache = new HashMap();
165
166
167 private MavenXpp3Reader modelReader;
168
169 private PathTranslator pathTranslator;
170
171 private ModelDefaultsInjector modelDefaultsInjector;
172
173 private ModelInterpolator modelInterpolator;
174
175 private ArtifactRepositoryFactory artifactRepositoryFactory;
176
177
178
179
180
181
182
183 private WagonManager wagonManager;
184
185 public static final String MAVEN_MODEL_VERSION = "4.0.0";
186
187 public void initialize()
188 {
189 modelReader = new MavenXpp3Reader();
190 }
191
192
193
194
195
196 public MavenProject build( File pom,
197 ProjectBuilderConfiguration config )
198 throws ProjectBuildingException
199 {
200 return buildFromSourceFileInternal( pom, config, true );
201 }
202
203 public MavenProject build( File pom,
204 ProjectBuilderConfiguration config,
205 boolean checkDistributionManagementStatus )
206 throws ProjectBuildingException
207 {
208 return buildFromSourceFileInternal( pom, config, checkDistributionManagementStatus );
209 }
210
211 public MavenProject build( File projectDescriptor,
212 ArtifactRepository localRepository,
213 ProfileManager profileManager )
214 throws ProjectBuildingException
215 {
216 ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ).setGlobalProfileManager( profileManager );
217 return buildFromSourceFileInternal( projectDescriptor, config, true );
218 }
219
220 public MavenProject build( File projectDescriptor,
221 ArtifactRepository localRepository,
222 ProfileManager profileManager,
223 boolean checkDistributionManagementStatus )
224 throws ProjectBuildingException
225 {
226 ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ).setGlobalProfileManager( profileManager );
227 return buildFromSourceFileInternal( projectDescriptor, config, checkDistributionManagementStatus );
228 }
229
230
231
232
233
234
235
236 public MavenProject buildFromRepository( Artifact artifact,
237 List remoteArtifactRepositories,
238 ArtifactRepository localRepository,
239 boolean allowStubModel )
240 throws ProjectBuildingException
241 {
242 String cacheKey = createCacheKey( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
243
244 MavenProject project = (MavenProject) processedProjectCache.get( cacheKey );
245
246 if ( project != null )
247 {
248 return project;
249 }
250
251 Model model = findModelFromRepository( artifact, remoteArtifactRepositories, localRepository, allowStubModel );
252
253 ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository );
254
255 return buildInternal( "Artifact [" + artifact + "]", model, config, remoteArtifactRepositories,
256 null, false );
257 }
258
259 public MavenProject buildFromRepository( Artifact artifact,
260 List remoteArtifactRepositories,
261 ArtifactRepository localRepository )
262 throws ProjectBuildingException
263 {
264 return buildFromRepository( artifact, remoteArtifactRepositories, localRepository, true );
265 }
266
267
268 public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository )
269 throws ProjectBuildingException
270 {
271
272 ProfileManager profileManager = new DefaultProfileManager( container );
273
274 return buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository )
275 .setGlobalProfileManager( profileManager ) );
276 }
277
278 public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository,
279 ProfileManager profileManager )
280 throws ProjectBuildingException
281 {
282 return buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository )
283 .setGlobalProfileManager( profileManager ) );
284 }
285
286 public MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration config )
287 throws ProjectBuildingException
288 {
289 Model superModel = getSuperModel();
290
291 superModel.setGroupId( STANDALONE_SUPERPOM_GROUPID );
292
293 superModel.setArtifactId( STANDALONE_SUPERPOM_ARTIFACTID );
294
295 superModel.setVersion( STANDALONE_SUPERPOM_VERSION );
296
297
298 List activeProfiles;
299
300 ProfileManager profileManager = config.getGlobalProfileManager();
301
302 if ( profileManager == null )
303 {
304 profileManager = new DefaultProfileManager( container );
305 }
306
307 profileManager.addProfiles( superModel.getProfiles() );
308
309 String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID );
310
311 activeProfiles = injectActiveProfiles( profileManager, superModel );
312
313 MavenProject project = new MavenProject( superModel );
314
315 project.setManagedVersionMap(
316 createManagedVersionMap( projectId, superModel.getDependencyManagement(), null ) );
317
318 project.setActiveProfiles( activeProfiles );
319
320 project.setOriginalModel( superModel );
321
322 try
323 {
324 project = processProjectLogic( "<Super-POM>", project, config, null, null, true, true );
325
326 project.setExecutionRoot( true );
327
328 return project;
329 }
330 catch ( ModelInterpolationException e )
331 {
332 throw new ProjectBuildingException( projectId, e.getMessage(), e );
333 }
334 catch ( InvalidRepositoryException e )
335 {
336 throw new ProjectBuildingException( projectId, e.getMessage(), e );
337 }
338 }
339
340 public MavenProject buildWithDependencies( File projectDescriptor,
341 ArtifactRepository localRepository,
342 ProfileManager profileManager )
343 throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
344 {
345 return buildWithDependencies( projectDescriptor, localRepository, profileManager, null );
346 }
347
348
349
350
351 public MavenProject buildWithDependencies( File projectDescriptor,
352 ArtifactRepository localRepository,
353 ProfileManager profileManager,
354 TransferListener transferListener )
355 throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
356 {
357 MavenProject project = build( projectDescriptor, localRepository, profileManager, false );
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372 Artifact projectArtifact = project.getArtifact();
373
374 String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() );
375
376
377 Map managedVersions = project.getManagedVersionMap();
378
379 ensureMetadataSourceIsInitialized();
380
381 try
382 {
383 project.setDependencyArtifacts( project.createArtifacts( artifactFactory, null, null ) );
384 }
385 catch ( InvalidDependencyVersionException e )
386 {
387 throw new ProjectBuildingException( projectId,
388 "Unable to build project due to an invalid dependency version: " +
389 e.getMessage(), e );
390 }
391
392 if ( transferListener != null )
393 {
394 wagonManager.setDownloadMonitor( transferListener );
395 }
396
397 ArtifactResolutionResult result = artifactResolver.resolveTransitively( project.getDependencyArtifacts(),
398 projectArtifact, managedVersions,
399 localRepository,
400 project.getRemoteArtifactRepositories(),
401 artifactMetadataSource );
402
403 project.setArtifacts( result.getArtifacts() );
404
405 return project;
406 }
407
408
409
410
411
412 private void ensureMetadataSourceIsInitialized()
413 throws ProjectBuildingException
414 {
415 if ( artifactMetadataSource == null )
416 {
417 try
418 {
419 artifactMetadataSource = (ArtifactMetadataSource) container.lookup( ArtifactMetadataSource.ROLE );
420 }
421 catch ( ComponentLookupException e )
422 {
423 throw new ProjectBuildingException( "all", "Cannot lookup metadata source for building the project.",
424 e );
425 }
426 }
427 }
428
429 private Map createManagedVersionMap( String projectId,
430 DependencyManagement dependencyManagement,
431 MavenProject parent )
432 throws ProjectBuildingException
433 {
434 Map map = null;
435 List deps;
436 if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null ) &&
437 ( deps.size() > 0 ) )
438 {
439 map = new ManagedVersionMap( map );
440
441 if ( getLogger().isDebugEnabled() )
442 {
443 getLogger().debug( "Adding managed dependencies for " + projectId );
444 }
445
446 for ( Iterator i = dependencyManagement.getDependencies().iterator(); i.hasNext(); )
447 {
448 Dependency d = (Dependency) i.next();
449
450 try
451 {
452 VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
453
454 Artifact artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(),
455 versionRange, d.getType(),
456 d.getClassifier(), d.getScope(),
457 d.isOptional() );
458 if ( getLogger().isDebugEnabled() )
459 {
460 getLogger().debug( " " + artifact );
461 }
462
463
464
465
466 if ( ( null != d.getExclusions() ) && !d.getExclusions().isEmpty() )
467 {
468 List exclusions = new ArrayList();
469
470 Iterator exclItr = d.getExclusions().iterator();
471
472 while ( exclItr.hasNext() )
473 {
474 Exclusion e = (Exclusion) exclItr.next();
475 exclusions.add( e.getGroupId() + ":" + e.getArtifactId() );
476 }
477 ExcludesArtifactFilter eaf = new ExcludesArtifactFilter( exclusions );
478 artifact.setDependencyFilter( eaf );
479 }
480 else
481 {
482 artifact.setDependencyFilter( null );
483 }
484 map.put( d.getManagementKey(), artifact );
485 }
486 catch ( InvalidVersionSpecificationException e )
487 {
488 throw new ProjectBuildingException( projectId, "Unable to parse version '" + d.getVersion() +
489 "' for dependency '" + d.getManagementKey() + "': " + e.getMessage(), e );
490 }
491 }
492 }
493 else if ( map == null )
494 {
495 map = Collections.EMPTY_MAP;
496 }
497
498 return map;
499 }
500
501 private MavenProject buildFromSourceFileInternal( File projectDescriptor,
502 ProjectBuilderConfiguration config,
503 boolean checkDistributionManagementStatus )
504 throws ProjectBuildingException
505 {
506 Model model = readModel( "unknown", projectDescriptor, true );
507
508 MavenProject project = buildInternal( projectDescriptor.getAbsolutePath(), model, config,
509 buildArtifactRepositories( getSuperModel() ), projectDescriptor,
510 true );
511
512 if ( checkDistributionManagementStatus )
513 {
514 if ( ( project.getDistributionManagement() != null ) &&
515 ( project.getDistributionManagement().getStatus() != null ) )
516 {
517 String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() );
518
519 throw new ProjectBuildingException( projectId,
520 "Invalid project file: distribution status must not be specified for a project outside of the repository" );
521 }
522 }
523
524 return project;
525 }
526
527 private Model findModelFromRepository( Artifact artifact,
528 List remoteArtifactRepositories,
529 ArtifactRepository localRepository,
530 boolean allowStubModel )
531 throws ProjectBuildingException
532 {
533 String projectId = safeVersionlessKey( artifact.getGroupId(), artifact.getArtifactId() );
534
535 normalizeToArtifactRepositories( remoteArtifactRepositories, projectId );
536
537 Artifact projectArtifact;
538
539
540 if ( "pom".equals( artifact.getType() ) )
541 {
542 projectArtifact = artifact;
543 }
544 else
545 {
546 getLogger().debug( "Attempting to build MavenProject instance for Artifact (" + artifact.getGroupId() + ":"
547 + artifact.getArtifactId() + ":" + artifact.getVersion() + ") of type: "
548 + artifact.getType() + "; constructing POM artifact instead." );
549
550 projectArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
551 artifact.getVersion(), artifact.getScope() );
552 }
553
554 Model model;
555
556 try
557 {
558 artifactResolver.resolve( projectArtifact, remoteArtifactRepositories, localRepository );
559
560 File file = projectArtifact.getFile();
561
562 model = readModel( projectId, file, false );
563
564 String downloadUrl = null;
565
566 ArtifactStatus status = ArtifactStatus.NONE;
567
568 DistributionManagement distributionManagement = model.getDistributionManagement();
569
570 if ( distributionManagement != null )
571 {
572 downloadUrl = distributionManagement.getDownloadUrl();
573
574 status = ArtifactStatus.valueOf( distributionManagement.getStatus() );
575 }
576
577 checkStatusAndUpdate( projectArtifact, status, file, remoteArtifactRepositories, localRepository );
578
579
580
581 if ( downloadUrl != null )
582 {
583 projectArtifact.setDownloadUrl( downloadUrl );
584 }
585 else
586 {
587 projectArtifact.setDownloadUrl( model.getUrl() );
588 }
589 }
590 catch ( ArtifactResolutionException e )
591 {
592 throw new ProjectBuildingException( projectId, "Error getting POM for '" + projectId +
593 "' from the repository: " + e.getMessage(), e );
594 }
595 catch ( ArtifactNotFoundException e )
596 {
597 if ( allowStubModel )
598 {
599 getLogger().debug( "Artifact not found - using stub model: " + e.getMessage() );
600
601 model = createStubModel( projectArtifact );
602 }
603 else
604 {
605 throw new ProjectBuildingException( projectId, "POM '" + projectId + "' not found in repository: " +
606 e.getMessage(), e );
607 }
608 }
609
610 return model;
611 }
612
613 private List normalizeToArtifactRepositories( List remoteArtifactRepositories,
614 String projectId )
615 throws ProjectBuildingException
616 {
617 List normalized = new ArrayList( remoteArtifactRepositories.size() );
618
619 boolean normalizationNeeded = false;
620 for ( Iterator it = remoteArtifactRepositories.iterator(); it.hasNext(); )
621 {
622 Object item = it.next();
623
624 if ( item instanceof ArtifactRepository )
625 {
626 normalized.add( item );
627 }
628 else if ( item instanceof Repository )
629 {
630 Repository repo = (Repository) item;
631 try
632 {
633 item = ProjectUtils.buildArtifactRepository( repo, artifactRepositoryFactory, container );
634
635 normalized.add( item );
636 normalizationNeeded = true;
637 }
638 catch ( InvalidRepositoryException e )
639 {
640 throw new ProjectBuildingException( projectId, "Error building artifact repository for id: " + repo.getId(), e );
641 }
642 }
643 else
644 {
645 throw new ProjectBuildingException( projectId, "Error building artifact repository from non-repository information item: " + item );
646 }
647 }
648
649 if ( normalizationNeeded )
650 {
651 return normalized;
652 }
653 else
654 {
655 return remoteArtifactRepositories;
656 }
657 }
658
659 private void checkStatusAndUpdate( Artifact projectArtifact,
660 ArtifactStatus status,
661 File file,
662 List remoteArtifactRepositories,
663 ArtifactRepository localRepository )
664 throws ArtifactNotFoundException
665 {
666
667 if ( !projectArtifact.isSnapshot() && ( status.compareTo( ArtifactStatus.DEPLOYED ) < 0 ) )
668 {
669
670 ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy();
671
672 policy.setUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER );
673
674 if ( policy.checkOutOfDate( new Date( file.lastModified() ) ) )
675 {
676 getLogger().info(
677 projectArtifact.getArtifactId() + ": updating metadata due to status of '" + status + "'" );
678 try
679 {
680 projectArtifact.setResolved( false );
681 artifactResolver.resolveAlways( projectArtifact, remoteArtifactRepositories, localRepository );
682 }
683 catch ( ArtifactResolutionException e )
684 {
685 getLogger().warn( "Error updating POM - using existing version" );
686 getLogger().debug( "Cause", e );
687 }
688 catch ( ArtifactNotFoundException e )
689 {
690 getLogger().warn( "Error updating POM - not found. Removing local copy." );
691 getLogger().debug( "Cause", e );
692 file.delete();
693 throw e;
694 }
695 }
696 }
697 }
698
699
700
701
702 private Model createStubModel( Artifact projectArtifact )
703 {
704 getLogger().debug( "Using defaults for missing POM " + projectArtifact );
705
706 Model model = new Model();
707
708 model.setModelVersion( "4.0.0" );
709
710 model.setArtifactId( projectArtifact.getArtifactId() );
711
712 model.setGroupId( projectArtifact.getGroupId() );
713
714 model.setVersion( projectArtifact.getVersion() );
715
716
717 model.setPackaging( projectArtifact.getType() );
718
719 model.setDistributionManagement( new DistributionManagement() );
720
721 model.getDistributionManagement().setStatus( ArtifactStatus.GENERATED.toString() );
722
723 return model;
724 }
725
726
727
728
729 private MavenProject buildInternal( String pomLocation,
730 Model model,
731 ProjectBuilderConfiguration config,
732 List parentSearchRepositories,
733 File projectDescriptor,
734 boolean strict )
735 throws ProjectBuildingException
736 {
737 File projectDir = null;
738
739 if ( projectDescriptor != null )
740 {
741 projectDir = projectDescriptor.getAbsoluteFile().getParentFile();
742 }
743
744 Model superModel = getSuperModel();
745
746 ProfileManager externalProfileManager = config.getGlobalProfileManager();
747 ProfileManager superProjectProfileManager;
748 if ( externalProfileManager != null )
749 {
750 superProjectProfileManager = new DefaultProfileManager(
751 container,
752 externalProfileManager.getRequestProperties() );
753 }
754 else
755 {
756 superProjectProfileManager = new DefaultProfileManager( container );
757 }
758
759 List activeProfiles;
760
761 superProjectProfileManager.addProfiles( superModel.getProfiles() );
762
763 activeProfiles = injectActiveProfiles( superProjectProfileManager, superModel );
764
765 MavenProject superProject = new MavenProject( superModel );
766
767 superProject.setActiveProfiles( activeProfiles );
768
769
770 LinkedList lineage = new LinkedList();
771
772
773
774
775
776 Set aggregatedRemoteWagonRepositories = new LinkedHashSet();
777
778 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
779
780 List activeExternalProfiles;
781 try
782 {
783 if ( externalProfileManager != null )
784 {
785 activeExternalProfiles = externalProfileManager.getActiveProfiles();
786 }
787 else
788 {
789 activeExternalProfiles = Collections.EMPTY_LIST;
790 }
791 }
792 catch ( ProfileActivationException e )
793 {
794 throw new ProjectBuildingException( projectId, "Failed to calculate active external profiles.", e );
795 }
796
797 for ( Iterator i = activeExternalProfiles.iterator(); i.hasNext(); )
798 {
799 Profile externalProfile = (Profile) i.next();
800
801 for ( Iterator repoIterator = externalProfile.getRepositories().iterator(); repoIterator.hasNext(); )
802 {
803 Repository mavenRepo = (Repository) repoIterator.next();
804
805 ArtifactRepository artifactRepo = null;
806 try
807 {
808 artifactRepo =
809 ProjectUtils.buildArtifactRepository( mavenRepo, artifactRepositoryFactory, container );
810 }
811 catch ( InvalidRepositoryException e )
812 {
813 throw new ProjectBuildingException( projectId, e.getMessage(), e );
814 }
815
816 aggregatedRemoteWagonRepositories.add( artifactRepo );
817 }
818 }
819
820 MavenProject project = null;
821 try
822 {
823 project = assembleLineage( model, lineage, config, projectDir, parentSearchRepositories,
824 aggregatedRemoteWagonRepositories, strict );
825 }
826 catch ( InvalidRepositoryException e )
827 {
828 throw new ProjectBuildingException( projectId, e.getMessage(), e );
829 }
830
831
832 MavenProject previousProject = superProject;
833
834 Model previous = superProject.getModel();
835
836 for ( Iterator i = lineage.iterator(); i.hasNext(); )
837 {
838 MavenProject currentProject = (MavenProject) i.next();
839
840 Model current = currentProject.getModel();
841
842 String pathAdjustment = null;
843
844 try
845 {
846 pathAdjustment = previousProject.getModulePathAdjustment( currentProject );
847 }
848 catch ( IOException e )
849 {
850 getLogger().debug( "Cannot determine whether " + currentProject.getId() + " is a module of " +
851 previousProject.getId() + ". Reason: " + e.getMessage(), e );
852 }
853
854 modelInheritanceAssembler.assembleModelInheritance( current, previous, pathAdjustment );
855
856 previous = current;
857 previousProject = currentProject;
858 }
859
860
861 List repositories = new ArrayList( aggregatedRemoteWagonRepositories );
862
863 List superRepositories = buildArtifactRepositories( superModel );
864
865 for ( Iterator i = superRepositories.iterator(); i.hasNext(); )
866 {
867 ArtifactRepository repository = (ArtifactRepository) i.next();
868
869 if ( !repositories.contains( repository ) )
870 {
871 repositories.add( repository );
872 }
873 }
874
875
876 ModelUtils.mergeDuplicatePluginDefinitions( project.getModel().getBuild() );
877
878 try
879 {
880 project = processProjectLogic( pomLocation, project, config, projectDir, repositories, strict, false );
881 }
882 catch ( ModelInterpolationException e )
883 {
884 throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e );
885 }
886 catch ( InvalidRepositoryException e )
887 {
888 throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e );
889 }
890
891 processedProjectCache.put(
892 createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project );
893
894
895
896 if ( projectDescriptor != null )
897 {
898 Build build = project.getBuild();
899
900 project.addCompileSourceRoot( build.getSourceDirectory() );
901
902 project.addScriptSourceRoot( build.getScriptSourceDirectory() );
903
904 project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
905
906
907 project.setFile( projectDescriptor );
908 }
909
910
911
912
913
914
915
916
917
918
919 project.setManagedVersionMap( createManagedVersionMap( projectId,
920 project.getDependencyManagement(),
921 project.getParent() ) );
922
923 return project;
924 }
925
926 private String safeVersionlessKey( String groupId,
927 String artifactId )
928 {
929 String gid = groupId;
930
931 if ( StringUtils.isEmpty( gid ) )
932 {
933 gid = "unknown";
934 }
935
936 String aid = artifactId;
937
938 if ( StringUtils.isEmpty( aid ) )
939 {
940 aid = "unknown";
941 }
942
943 return ArtifactUtils.versionlessKey( gid, aid );
944 }
945
946 private List buildArtifactRepositories( Model model )
947 throws ProjectBuildingException
948 {
949 try
950 {
951 return ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory,
952 container );
953 }
954 catch ( InvalidRepositoryException e )
955 {
956 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
957
958 throw new ProjectBuildingException( projectId, e.getMessage(), e );
959 }
960 }
961
962
963
964
965
966
967
968
969 private MavenProject processProjectLogic( String pomLocation,
970 MavenProject project,
971 ProjectBuilderConfiguration config,
972 File projectDir,
973 List remoteRepositories,
974 boolean strict,
975 boolean isSuperPom )
976 throws ProjectBuildingException, ModelInterpolationException, InvalidRepositoryException
977 {
978 Model model = project.getModel();
979
980 List activeProfiles = project.getActiveProfiles();
981
982 if ( activeProfiles == null )
983 {
984 activeProfiles = new ArrayList();
985 }
986
987 ProfileManager profileMgr = config == null ? null : config.getGlobalProfileManager();
988
989 List injectedProfiles = injectActiveProfiles( profileMgr, model );
990
991 activeProfiles.addAll( injectedProfiles );
992
993
994
995 Build dynamicBuild = model.getBuild();
996
997 model.setBuild( ModelUtils.cloneBuild( dynamicBuild ) );
998
999 model = modelInterpolator.interpolate( model, projectDir, config, getLogger().isDebugEnabled() );
1000
1001 mergeDeterministicBuildElements( model.getBuild(), dynamicBuild );
1002
1003 model.setBuild( dynamicBuild );
1004
1005
1006 if ( !isSuperPom )
1007 {
1008 mergeManagedDependencies( model, config.getLocalRepository(), remoteRepositories );
1009 }
1010
1011
1012 modelDefaultsInjector.injectDefaults( model );
1013
1014 MavenProject parentProject = project.getParent();
1015
1016 Model originalModel = project.getOriginalModel();
1017
1018
1019 project = new MavenProject( model, getLogger() );
1020
1021 project.setOriginalModel( originalModel );
1022
1023 project.setActiveProfiles( activeProfiles );
1024
1025
1026 Artifact projectArtifact = artifactFactory.create( project );
1027
1028 project.setArtifact( projectArtifact );
1029 project.setProjectBuilderConfiguration( config );
1030
1031 project.setPluginArtifactRepositories( ProjectUtils.buildArtifactRepositories( model.getPluginRepositories(),
1032 artifactRepositoryFactory,
1033 container ) );
1034
1035 DistributionManagement dm = model.getDistributionManagement();
1036 if ( dm != null )
1037 {
1038 ArtifactRepository repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getRepository(),
1039 artifactRepositoryFactory,
1040 container );
1041 project.setReleaseArtifactRepository( repo );
1042
1043 if ( dm.getSnapshotRepository() != null )
1044 {
1045 repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getSnapshotRepository(),
1046 artifactRepositoryFactory, container );
1047 project.setSnapshotArtifactRepository( repo );
1048 }
1049 }
1050
1051 if ( parentProject != null )
1052 {
1053 String cacheKey = createCacheKey( parentProject.getGroupId(),
1054 parentProject.getArtifactId(),
1055 parentProject.getVersion() );
1056
1057 MavenProject processedParent = (MavenProject) processedProjectCache.get( cacheKey );
1058 Artifact parentArtifact;
1059
1060
1061 if ( processedParent != null )
1062 {
1063 project.setParent( processedParent );
1064
1065 parentArtifact = processedParent.getArtifact();
1066 }
1067 else
1068 {
1069 project.setParent( parentProject );
1070
1071 parentArtifact = artifactFactory.createParentArtifact( parentProject.getGroupId(),
1072 parentProject.getArtifactId(),
1073 parentProject.getVersion() );
1074 }
1075
1076 project.setParentArtifact( parentArtifact );
1077 }
1078
1079
1080 ModelValidationResult validationResult = validator.validate( model );
1081
1082 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
1083
1084 if ( validationResult.getMessageCount() > 0 )
1085 {
1086 throw new InvalidProjectModelException( projectId, pomLocation, "Failed to validate POM",
1087 validationResult );
1088 }
1089
1090 project.setRemoteArtifactRepositories(
1091 ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory, container ) );
1092
1093
1094 project.setPluginArtifacts( createPluginArtifacts( projectId, project.getBuildPlugins() ) );
1095
1096 project.setReportArtifacts( createReportArtifacts( projectId, project.getReportPlugins() ) );
1097
1098 project.setExtensionArtifacts( createExtensionArtifacts( projectId, project.getBuildExtensions() ) );
1099
1100 return project;
1101 }
1102
1103 private void mergeDeterministicBuildElements( Build interpolatedBuild,
1104 Build dynamicBuild )
1105 {
1106 mergeDeterministicPluginElements( interpolatedBuild.getPlugins(), dynamicBuild.getPlugins() );
1107
1108 PluginManagement dPluginMgmt = dynamicBuild.getPluginManagement();
1109 PluginManagement iPluginMgmt = interpolatedBuild.getPluginManagement();
1110
1111 if ( dPluginMgmt != null )
1112 {
1113 mergeDeterministicPluginElements( iPluginMgmt.getPlugins(), dPluginMgmt.getPlugins() );
1114 }
1115
1116 if ( dynamicBuild.getExtensions() != null )
1117 {
1118 dynamicBuild.setExtensions( interpolatedBuild.getExtensions() );
1119 }
1120 }
1121
1122 private void mergeDeterministicPluginElements( List iPlugins, List dPlugins )
1123 {
1124 if ( dPlugins != null )
1125 {
1126 for ( int i = 0; i < dPlugins.size(); i++ )
1127 {
1128 Plugin dPlugin = (Plugin) dPlugins.get( i );
1129 Plugin iPlugin = (Plugin) iPlugins.get( i );
1130
1131 dPlugin.setGroupId( iPlugin.getGroupId() );
1132 dPlugin.setArtifactId( iPlugin.getArtifactId() );
1133 dPlugin.setVersion( iPlugin.getVersion() );
1134
1135 dPlugin.setDependencies( iPlugin.getDependencies() );
1136
1137 List dExecutions = dPlugin.getExecutions();
1138 if ( dExecutions != null )
1139 {
1140 List iExecutions = iPlugin.getExecutions();
1141
1142 for ( int j = 0; j < dExecutions.size(); j++ )
1143 {
1144 PluginExecution dExec = (PluginExecution) dExecutions.get( j );
1145 PluginExecution iExec = (PluginExecution) iExecutions.get( j );
1146
1147 dExec.setId( iExec.getId() );
1148 }
1149 }
1150 }
1151 }
1152 }
1153
1154
1155
1156
1157
1158
1159 private MavenProject assembleLineage( Model model,
1160 LinkedList lineage,
1161 ProjectBuilderConfiguration config,
1162 File projectDir,
1163 List parentSearchRepositories,
1164 Set aggregatedRemoteWagonRepositories,
1165 boolean strict )
1166 throws ProjectBuildingException, InvalidRepositoryException
1167 {
1168 Model originalModel = ModelUtils.cloneModel( model );
1169
1170 ProfileManager externalProfileManager = config.getGlobalProfileManager();
1171 ProfileManager profileManager;
1172 if ( externalProfileManager != null )
1173 {
1174 profileManager = new DefaultProfileManager( container, externalProfileManager.getRequestProperties() );
1175 }
1176 else
1177 {
1178
1179 profileManager = new DefaultProfileManager( container );
1180 }
1181
1182 if ( externalProfileManager != null )
1183 {
1184 profileManager.explicitlyActivate( externalProfileManager.getExplicitlyActivatedIds() );
1185
1186 profileManager.explicitlyDeactivate( externalProfileManager.getExplicitlyDeactivatedIds() );
1187 }
1188
1189 List activeProfiles;
1190
1191 try
1192 {
1193 profileManager.addProfiles( model.getProfiles() );
1194
1195 loadProjectExternalProfiles( profileManager, projectDir );
1196
1197 activeProfiles = injectActiveProfiles( profileManager, model );
1198 }
1199 catch ( ProfileActivationException e )
1200 {
1201 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
1202
1203 throw new ProjectBuildingException( projectId, "Failed to activate local (project-level) build profiles: " +
1204 e.getMessage(), e );
1205 }
1206
1207 if ( !model.getRepositories().isEmpty() )
1208 {
1209 List respositories = buildArtifactRepositories( model );
1210
1211 for ( Iterator it = respositories.iterator(); it.hasNext(); )
1212 {
1213 ArtifactRepository repository = (ArtifactRepository) it.next();
1214
1215 if ( !aggregatedRemoteWagonRepositories.contains( repository ) )
1216 {
1217 aggregatedRemoteWagonRepositories.add( repository );
1218 }
1219 }
1220 }
1221
1222 MavenProject project = new MavenProject( model, getLogger() );
1223
1224 project.setActiveProfiles( activeProfiles );
1225 project.setOriginalModel( originalModel );
1226
1227 lineage.addFirst( project );
1228
1229 Parent parentModel = model.getParent();
1230
1231 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
1232
1233 if ( parentModel != null )
1234 {
1235 if ( StringUtils.isEmpty( parentModel.getGroupId() ) )
1236 {
1237 throw new ProjectBuildingException( projectId, "Missing groupId element from parent element" );
1238 }
1239 else if ( StringUtils.isEmpty( parentModel.getArtifactId() ) )
1240 {
1241 throw new ProjectBuildingException( projectId, "Missing artifactId element from parent element" );
1242 }
1243 else if ( parentModel.getGroupId().equals( model.getGroupId() ) &&
1244 parentModel.getArtifactId().equals( model.getArtifactId() ) )
1245 {
1246 throw new ProjectBuildingException( projectId,
1247 "Parent element is a duplicate of " + "the current project " );
1248 }
1249 else if ( StringUtils.isEmpty( parentModel.getVersion() ) )
1250 {
1251 throw new ProjectBuildingException( projectId, "Missing version element from parent element" );
1252 }
1253
1254
1255 File parentDescriptor = null;
1256
1257 model = null;
1258
1259 String parentKey =
1260 createCacheKey( parentModel.getGroupId(), parentModel.getArtifactId(), parentModel.getVersion() );
1261 MavenProject parentProject = (MavenProject) rawProjectCache.get( parentKey );
1262
1263 if ( parentProject != null )
1264 {
1265 model = ModelUtils.cloneModel( parentProject.getOriginalModel() );
1266
1267 parentDescriptor = parentProject.getFile();
1268 }
1269
1270 String parentRelativePath = parentModel.getRelativePath();
1271
1272
1273
1274 if ( ( model == null ) && ( projectDir != null ) && StringUtils.isNotEmpty( parentRelativePath ) )
1275 {
1276 parentDescriptor = new File( projectDir, parentRelativePath );
1277
1278 if ( getLogger().isDebugEnabled() )
1279 {
1280 getLogger().debug( "Searching for parent-POM: " + parentModel.getId() + " of project: " +
1281 project.getId() + " in relative path: " + parentRelativePath );
1282 }
1283
1284 if ( parentDescriptor.isDirectory() )
1285 {
1286 if ( getLogger().isDebugEnabled() )
1287 {
1288 getLogger().debug( "Path specified in <relativePath/> (" + parentRelativePath +
1289 ") is a directory. Searching for 'pom.xml' within this directory." );
1290 }
1291
1292 parentDescriptor = new File( parentDescriptor, "pom.xml" );
1293
1294 if ( !parentDescriptor.exists() )
1295 {
1296 if ( getLogger().isDebugEnabled() )
1297 {
1298 getLogger().debug( "Parent-POM: " + parentModel.getId() + " for project: " +
1299 project.getId() + " cannot be loaded from relative path: " + parentDescriptor +
1300 "; path does not exist." );
1301 }
1302 }
1303 }
1304
1305 if ( parentDescriptor != null )
1306 {
1307 try
1308 {
1309 parentDescriptor = parentDescriptor.getCanonicalFile();
1310 }
1311 catch ( IOException e )
1312 {
1313 getLogger().debug( "Failed to canonicalize potential parent POM: \'" + parentDescriptor + "\'",
1314 e );
1315
1316 parentDescriptor = null;
1317 }
1318 }
1319
1320 if ( ( parentDescriptor != null ) && parentDescriptor.exists() )
1321 {
1322 Model candidateParent = readModel( projectId, parentDescriptor, strict );
1323
1324 String candidateParentGroupId = candidateParent.getGroupId();
1325 if ( ( candidateParentGroupId == null ) && ( candidateParent.getParent() != null ) )
1326 {
1327 candidateParentGroupId = candidateParent.getParent().getGroupId();
1328 }
1329
1330 String candidateParentVersion = candidateParent.getVersion();
1331 if ( ( candidateParentVersion == null ) && ( candidateParent.getParent() != null ) )
1332 {
1333 candidateParentVersion = candidateParent.getParent().getVersion();
1334 }
1335
1336 if ( parentModel.getGroupId().equals( candidateParentGroupId ) &&
1337 parentModel.getArtifactId().equals( candidateParent.getArtifactId() ) &&
1338 parentModel.getVersion().equals( candidateParentVersion ) )
1339 {
1340 model = candidateParent;
1341
1342 getLogger().debug( "Using parent-POM from the project hierarchy at: \'" +
1343 parentModel.getRelativePath() + "\' for project: " + project.getId() );
1344 }
1345 else
1346 {
1347 getLogger().debug( "Invalid parent-POM referenced by relative path '" +
1348 parentModel.getRelativePath() + "' in parent specification in " + project.getId() + ":" +
1349 "\n Specified: " + parentModel.getId() + "\n Found: " + candidateParent.getId() );
1350 }
1351 }
1352 else if ( getLogger().isDebugEnabled() )
1353 {
1354 getLogger().debug(
1355 "Parent-POM: " + parentModel.getId() + " not found in relative path: " + parentRelativePath );
1356 }
1357 }
1358
1359 Artifact parentArtifact = null;
1360
1361
1362 if ( model == null )
1363 {
1364
1365
1366 parentDescriptor = null;
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379 List remoteRepositories = new ArrayList( aggregatedRemoteWagonRepositories );
1380 remoteRepositories.addAll( parentSearchRepositories );
1381
1382 if ( getLogger().isDebugEnabled() )
1383 {
1384 getLogger().debug( "Retrieving parent-POM: " + parentModel.getId() + " for project: " +
1385 project.getId() + " from the repository." );
1386 }
1387
1388 parentArtifact = artifactFactory.createParentArtifact( parentModel.getGroupId(),
1389 parentModel.getArtifactId(),
1390 parentModel.getVersion() );
1391
1392 try
1393 {
1394 model = findModelFromRepository( parentArtifact, remoteRepositories, config.getLocalRepository(), false );
1395 }
1396 catch ( ProjectBuildingException e )
1397 {
1398 throw new ProjectBuildingException( project.getId(), "Cannot find parent: " + e.getProjectId() +
1399 " for project: " + project.getId(), e );
1400 }
1401 }
1402
1403 if ( ( model != null ) && !"pom".equals( model.getPackaging() ) )
1404 {
1405 throw new ProjectBuildingException( projectId, "Parent: " + model.getId() + " of project: " +
1406 projectId + " has wrong packaging: " + model.getPackaging() + ". Must be 'pom'." );
1407 }
1408
1409 File parentProjectDir = null;
1410 if ( parentDescriptor != null )
1411 {
1412 parentProjectDir = parentDescriptor.getParentFile();
1413 }
1414
1415 MavenProject parent = assembleLineage( model,
1416 lineage,
1417 config,
1418 parentProjectDir,
1419 parentSearchRepositories,
1420 aggregatedRemoteWagonRepositories,
1421 strict );
1422
1423 parent.setFile( parentDescriptor );
1424
1425 project.setParent( parent );
1426
1427 project.setParentArtifact( parentArtifact );
1428 }
1429
1430 rawProjectCache.put( createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), new MavenProject( project ) );
1431
1432 return project;
1433 }
1434
1435 private void mergeManagedDependencies(Model model, ArtifactRepository localRepository, List parentSearchRepositories)
1436 throws ProjectBuildingException
1437 {
1438 DependencyManagement modelDepMgmt = model.getDependencyManagement();
1439
1440 if (modelDepMgmt != null)
1441 {
1442 Map depsMap = new TreeMap();
1443 Iterator iter = modelDepMgmt.getDependencies().iterator();
1444 boolean doInclude = false;
1445 while (iter.hasNext())
1446 {
1447 Dependency dep = (Dependency) iter.next();
1448 depsMap.put( dep.getManagementKey(), dep );
1449 if ( dep.getType().equals( "pom" ) && Artifact.SCOPE_IMPORT.equals( dep.getScope() ) )
1450 {
1451 doInclude = true;
1452 }
1453 }
1454 Map newDeps = new TreeMap(depsMap);
1455 iter = modelDepMgmt.getDependencies().iterator();
1456 if (doInclude)
1457 {
1458 while (iter.hasNext())
1459 {
1460 Dependency dep = (Dependency)iter.next();
1461 if ( dep.getType().equals( "pom" )
1462 && Artifact.SCOPE_IMPORT.equals( dep.getScope() ) )
1463 {
1464 Artifact artifact = artifactFactory.createProjectArtifact( dep.getGroupId(), dep.getArtifactId(),
1465 dep.getVersion(), dep.getScope() );
1466 MavenProject project = buildFromRepository(artifact, parentSearchRepositories, localRepository, false);
1467
1468 DependencyManagement depMgmt = project.getDependencyManagement();
1469
1470 if (depMgmt != null)
1471 {
1472 if ( getLogger().isDebugEnabled() )
1473 {
1474 getLogger().debug( "Importing managed dependencies for " + dep.toString() );
1475 }
1476
1477 for ( Iterator it = depMgmt.getDependencies().iterator(); it.hasNext(); )
1478 {
1479 Dependency includedDep = (Dependency) it.next();
1480 String key = includedDep.getManagementKey();
1481 if (!newDeps.containsKey(key))
1482 {
1483 newDeps.put( includedDep.getManagementKey(), includedDep );
1484 }
1485 }
1486 newDeps.remove(dep.getManagementKey());
1487 }
1488 }
1489 }
1490 List deps = new ArrayList(newDeps.values());
1491 modelDepMgmt.setDependencies(deps);
1492 }
1493 }
1494 }
1495
1496 private List injectActiveProfiles( ProfileManager profileManager,
1497 Model model )
1498 throws ProjectBuildingException
1499 {
1500 List activeProfiles;
1501
1502 if ( profileManager != null )
1503 {
1504 try
1505 {
1506 activeProfiles = profileManager.getActiveProfiles();
1507 }
1508 catch ( ProfileActivationException e )
1509 {
1510 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
1511
1512 throw new ProjectBuildingException( projectId, e.getMessage(), e );
1513 }
1514
1515 for ( Iterator it = activeProfiles.iterator(); it.hasNext(); )
1516 {
1517 Profile profile = (Profile) it.next();
1518
1519 profileInjector.inject( profile, model );
1520 }
1521 }
1522 else
1523 {
1524 activeProfiles = Collections.EMPTY_LIST;
1525 }
1526
1527 return activeProfiles;
1528 }
1529
1530 private void loadProjectExternalProfiles( ProfileManager profileManager,
1531 File projectDir )
1532 throws ProfileActivationException
1533 {
1534 if ( projectDir != null )
1535 {
1536 try
1537 {
1538 ProfilesRoot root = profilesBuilder.buildProfiles( projectDir );
1539
1540 if ( root != null )
1541 {
1542 List active = root.getActiveProfiles();
1543
1544 if ( ( active != null ) && !active.isEmpty() )
1545 {
1546 profileManager.explicitlyActivate( root.getActiveProfiles() );
1547 }
1548
1549 for ( Iterator it = root.getProfiles().iterator(); it.hasNext(); )
1550 {
1551 org.apache.maven.profiles.Profile rawProfile = (org.apache.maven.profiles.Profile) it.next();
1552
1553 Profile converted = ProfilesConversionUtils.convertFromProfileXmlProfile( rawProfile );
1554
1555 profileManager.addProfile( converted );
1556 }
1557 }
1558 }
1559 catch ( IOException e )
1560 {
1561 throw new ProfileActivationException( "Cannot read profiles.xml resource from directory: " + projectDir,
1562 e );
1563 }
1564 catch ( XmlPullParserException e )
1565 {
1566 throw new ProfileActivationException(
1567 "Cannot parse profiles.xml resource from directory: " + projectDir, e );
1568 }
1569 }
1570 }
1571
1572 private Model readModel( String projectId,
1573 File file,
1574 boolean strict )
1575 throws ProjectBuildingException
1576 {
1577 Reader reader = null;
1578 try
1579 {
1580 reader = ReaderFactory.newXmlReader( file );
1581 return readModel( projectId, file.getAbsolutePath(), reader, strict );
1582 }
1583 catch ( FileNotFoundException e )
1584 {
1585 throw new ProjectBuildingException( projectId,
1586 "Could not find the model file '" + file.getAbsolutePath() + "'.", e );
1587 }
1588 catch ( IOException e )
1589 {
1590 throw new ProjectBuildingException( projectId, "Failed to build model from file '" +
1591 file.getAbsolutePath() + "'.\nError: \'" + e.getLocalizedMessage() + "\'", e );
1592 }
1593 finally
1594 {
1595 IOUtil.close( reader );
1596 }
1597 }
1598
1599 private Model readModel( String projectId,
1600 String pomLocation,
1601 Reader reader,
1602 boolean strict )
1603 throws IOException, InvalidProjectModelException
1604 {
1605 String modelSource = IOUtil.toString( reader );
1606
1607 if ( modelSource.indexOf( "<modelVersion>" + MAVEN_MODEL_VERSION ) < 0 )
1608 {
1609 throw new InvalidProjectModelException( projectId, pomLocation, "Not a v" + MAVEN_MODEL_VERSION + " POM." );
1610 }
1611
1612 StringReader sReader = new StringReader( modelSource );
1613
1614 try
1615 {
1616 return modelReader.read( sReader, strict );
1617 }
1618 catch ( XmlPullParserException e )
1619 {
1620 throw new InvalidProjectModelException( projectId, pomLocation,
1621 "Parse error reading POM. Reason: " + e.getMessage(), e );
1622 }
1623 }
1624
1625 private Model readModel( String projectId,
1626 URL url,
1627 boolean strict )
1628 throws ProjectBuildingException
1629 {
1630 Reader reader = null;
1631 try
1632 {
1633 reader = ReaderFactory.newXmlReader( url.openStream() );
1634 return readModel( projectId, url.toExternalForm(), reader, strict );
1635 }
1636 catch ( IOException e )
1637 {
1638 throw new ProjectBuildingException( projectId, "Failed build model from URL \'" + url.toExternalForm() +
1639 "\'\nError: \'" + e.getLocalizedMessage() + "\'", e );
1640 }
1641 finally
1642 {
1643 IOUtil.close( reader );
1644 }
1645 }
1646
1647 private static String createCacheKey( String groupId,
1648 String artifactId,
1649 String version )
1650 {
1651 return groupId + ":" + artifactId + ":" + version;
1652 }
1653
1654 protected Set createPluginArtifacts( String projectId,
1655 List plugins )
1656 throws ProjectBuildingException
1657 {
1658 Set pluginArtifacts = new LinkedHashSet();
1659
1660 for ( Iterator i = plugins.iterator(); i.hasNext(); )
1661 {
1662 Plugin p = (Plugin) i.next();
1663
1664 String version;
1665 if ( StringUtils.isEmpty( p.getVersion() ) )
1666 {
1667 version = "RELEASE";
1668 }
1669 else
1670 {
1671 version = p.getVersion();
1672 }
1673
1674 Artifact artifact;
1675 try
1676 {
1677 artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(),
1678 VersionRange.createFromVersionSpec( version ) );
1679 }
1680 catch ( InvalidVersionSpecificationException e )
1681 {
1682 throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
1683 "' for plugin '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " +
1684 e.getMessage(), e );
1685 }
1686
1687 if ( artifact != null )
1688 {
1689 pluginArtifacts.add( artifact );
1690 }
1691 }
1692
1693 return pluginArtifacts;
1694 }
1695
1696
1697 protected Set createReportArtifacts( String projectId,
1698 List reports )
1699 throws ProjectBuildingException
1700 {
1701 Set pluginArtifacts = new LinkedHashSet();
1702
1703 if ( reports != null )
1704 {
1705 for ( Iterator i = reports.iterator(); i.hasNext(); )
1706 {
1707 ReportPlugin p = (ReportPlugin) i.next();
1708
1709 String version;
1710 if ( StringUtils.isEmpty( p.getVersion() ) )
1711 {
1712 version = "RELEASE";
1713 }
1714 else
1715 {
1716 version = p.getVersion();
1717 }
1718
1719 Artifact artifact;
1720 try
1721 {
1722 artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(),
1723 VersionRange.createFromVersionSpec( version ) );
1724 }
1725 catch ( InvalidVersionSpecificationException e )
1726 {
1727 throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
1728 "' for report '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " +
1729 e.getMessage(), e );
1730 }
1731
1732 if ( artifact != null )
1733 {
1734 pluginArtifacts.add( artifact );
1735 }
1736 }
1737 }
1738
1739 return pluginArtifacts;
1740 }
1741
1742
1743 protected Set createExtensionArtifacts( String projectId,
1744 List extensions )
1745 throws ProjectBuildingException
1746 {
1747 Set extensionArtifacts = new LinkedHashSet();
1748
1749 if ( extensions != null )
1750 {
1751 for ( Iterator i = extensions.iterator(); i.hasNext(); )
1752 {
1753 Extension ext = (Extension) i.next();
1754
1755 String version;
1756 if ( StringUtils.isEmpty( ext.getVersion() ) )
1757 {
1758 version = "RELEASE";
1759 }
1760 else
1761 {
1762 version = ext.getVersion();
1763 }
1764
1765 Artifact artifact;
1766 try
1767 {
1768 VersionRange versionRange = VersionRange.createFromVersionSpec( version );
1769 artifact =
1770 artifactFactory.createExtensionArtifact( ext.getGroupId(), ext.getArtifactId(), versionRange );
1771 }
1772 catch ( InvalidVersionSpecificationException e )
1773 {
1774 throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
1775 "' for extension '" + ArtifactUtils.versionlessKey( ext.getGroupId(), ext.getArtifactId() ) +
1776 "': " + e.getMessage(), e );
1777 }
1778
1779 if ( artifact != null )
1780 {
1781 extensionArtifacts.add( artifact );
1782 }
1783 }
1784 }
1785
1786 return extensionArtifacts;
1787 }
1788
1789
1790
1791
1792
1793 private Model getSuperModel()
1794 throws ProjectBuildingException
1795 {
1796 URL url = DefaultMavenProjectBuilder.class.getResource( "pom-" + MAVEN_MODEL_VERSION + ".xml" );
1797
1798 String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID );
1799
1800 return readModel( projectId, url, true );
1801 }
1802
1803 public void contextualize( Context context )
1804 throws ContextException
1805 {
1806 container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
1807 }
1808
1809
1810
1811
1812 public void calculateConcreteState( MavenProject project, ProjectBuilderConfiguration config )
1813 throws ModelInterpolationException
1814 {
1815 calculateConcreteStateInternal( project, config, true, new HashSet() );
1816 }
1817
1818
1819
1820
1821 public void calculateConcreteState( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences )
1822 throws ModelInterpolationException
1823 {
1824 calculateConcreteStateInternal( project, config, processProjectReferences, ( processProjectReferences ? new HashSet() : null ) );
1825 }
1826
1827
1828
1829
1830
1831
1832
1833 private void calculateConcreteStateInternal( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences, Set processedProjects )
1834 throws ModelInterpolationException
1835 {
1836 if ( processProjectReferences )
1837 {
1838 processedProjects.add( project.getId() );
1839 }
1840
1841 restoreDynamicStateInternal( project, config, processProjectReferences, processProjectReferences ? new HashSet( processedProjects ) : null );
1842
1843 if ( !project.isConcrete() )
1844 {
1845 if ( project.getParent() != null )
1846 {
1847 calculateConcreteStateInternal( project.getParent(), config, processProjectReferences, processedProjects );
1848 }
1849
1850 Build build = project.getBuild();
1851 if ( build != null )
1852 {
1853 initResourceMergeIds( build.getResources() );
1854 initResourceMergeIds( build.getTestResources() );
1855 }
1856
1857
1858
1859
1860
1861
1862 File basedir = project.getBasedir();
1863
1864
1865 Model model = ModelUtils.cloneModel( project.getModel() );
1866 model = modelInterpolator.interpolate( model, project.getBasedir(), config, getLogger().isDebugEnabled() );
1867
1868 List originalInterpolatedCompileSourceRoots = interpolateListOfStrings( project.getCompileSourceRoots(),
1869 model,
1870 project.getBasedir(),
1871 config,
1872 getLogger().isDebugEnabled() );
1873
1874 project.preserveCompileSourceRoots( originalInterpolatedCompileSourceRoots );
1875
1876 project.setCompileSourceRoots( originalInterpolatedCompileSourceRoots == null ? null
1877 : translateListOfPaths( originalInterpolatedCompileSourceRoots, basedir ) );
1878
1879 List originalInterpolatedTestCompileSourceRoots = interpolateListOfStrings( project.getTestCompileSourceRoots(),
1880 model,
1881 project.getBasedir(),
1882 config,
1883 getLogger().isDebugEnabled() );
1884
1885 project.preserveTestCompileSourceRoots( originalInterpolatedTestCompileSourceRoots );
1886 project.setTestCompileSourceRoots( originalInterpolatedTestCompileSourceRoots == null ? null
1887 : translateListOfPaths( originalInterpolatedTestCompileSourceRoots, basedir ) );
1888
1889 List originalInterpolatedScriptSourceRoots = interpolateListOfStrings( project.getScriptSourceRoots(),
1890 model,
1891 project.getBasedir(),
1892 config,
1893 getLogger().isDebugEnabled() );
1894
1895 project.preserveScriptSourceRoots( originalInterpolatedScriptSourceRoots );
1896
1897
1898 project.setScriptSourceRoots( originalInterpolatedScriptSourceRoots );
1899
1900
1901
1902 if ( basedir != null )
1903 {
1904 pathTranslator.alignToBaseDirectory( model, basedir );
1905 }
1906
1907 project.preserveBuild( ModelUtils.cloneBuild( model.getBuild() ) );
1908 project.preserveProperties();
1909 project.preserveBasedir();
1910 project.setBuild( model.getBuild() );
1911
1912 if ( project.getExecutionProject() != null )
1913 {
1914 calculateConcreteStateInternal( project.getExecutionProject(), config, processProjectReferences, processedProjects );
1915 }
1916
1917 project.setConcrete( true );
1918 }
1919
1920 if ( processProjectReferences )
1921 {
1922 calculateConcreteProjectReferences( project, config, processedProjects );
1923 }
1924 }
1925
1926 private void initResourceMergeIds( List resources )
1927 {
1928 if ( resources != null )
1929 {
1930 for ( Iterator it = resources.iterator(); it.hasNext(); )
1931 {
1932 Resource resource = (Resource) it.next();
1933
1934 resource.initMergeId();
1935 }
1936 }
1937 }
1938
1939 private void calculateConcreteProjectReferences( MavenProject project,
1940 ProjectBuilderConfiguration config,
1941 Set processedProjects )
1942 throws ModelInterpolationException
1943 {
1944 Map projectRefs = project.getProjectReferences();
1945
1946 if ( projectRefs != null )
1947 {
1948 for ( Iterator it = projectRefs.values().iterator(); it.hasNext(); )
1949 {
1950 MavenProject reference = (MavenProject) it.next();
1951 if ( !processedProjects.contains( reference.getId() ) )
1952 {
1953 calculateConcreteStateInternal( reference, config, true, processedProjects );
1954 }
1955 }
1956 }
1957 }
1958
1959 private List translateListOfPaths( List paths, File basedir )
1960 {
1961 if ( paths == null )
1962 {
1963 return null;
1964 }
1965 else if ( basedir == null )
1966 {
1967 return paths;
1968 }
1969
1970 List result = new ArrayList( paths.size() );
1971 for ( Iterator it = paths.iterator(); it.hasNext(); )
1972 {
1973 String path = (String) it.next();
1974
1975 String aligned = pathTranslator.alignToBaseDirectory( path, basedir );
1976
1977 result.add( aligned );
1978 }
1979
1980 return result;
1981 }
1982
1983
1984
1985
1986 public void restoreDynamicState( MavenProject project, ProjectBuilderConfiguration config )
1987 throws ModelInterpolationException
1988 {
1989 restoreDynamicStateInternal( project, config, true, new HashSet() );
1990 }
1991
1992
1993
1994
1995 public void restoreDynamicState( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences )
1996 throws ModelInterpolationException
1997 {
1998 restoreDynamicStateInternal( project, config, processProjectReferences, ( processProjectReferences ? new HashSet() : null ) );
1999 }
2000
2001
2002
2003
2004
2005
2006
2007 private void restoreDynamicStateInternal( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences, Set processedProjects )
2008 throws ModelInterpolationException
2009 {
2010 if ( processProjectReferences )
2011 {
2012 processedProjects.add( project.getId() );
2013 }
2014
2015 if ( project.isConcrete() && projectWasChanged( project ) )
2016 {
2017 if ( project.getParent() != null )
2018 {
2019 restoreDynamicStateInternal( project.getParent(), config, processProjectReferences, processedProjects );
2020 }
2021
2022 restoreBuildRoots( project, config, getLogger().isDebugEnabled() );
2023 restoreModelBuildSection( project, config, getLogger().isDebugEnabled() );
2024
2025 if ( project.getExecutionProject() != null )
2026 {
2027 restoreDynamicStateInternal( project.getExecutionProject(), config, processProjectReferences, processedProjects );
2028 }
2029
2030 project.setConcrete( false );
2031 }
2032
2033 if ( processProjectReferences )
2034 {
2035 restoreDynamicProjectReferences( project, config, processedProjects );
2036 }
2037 }
2038
2039 private boolean projectWasChanged( MavenProject project )
2040 {
2041 if ( !objectEquals( project.getBasedir(), project.getPreservedBasedir() ) )
2042 {
2043 return true;
2044 }
2045
2046 if ( !objectEquals( project.getProperties(), project.getPreservedProperties() ) )
2047 {
2048 return true;
2049 }
2050
2051 Build oBuild = project.getOriginalInterpolatedBuild();
2052 Build build = project.getBuild();
2053
2054 if ( !objectEquals( oBuild.getDirectory(), build.getDirectory() ) )
2055 {
2056 return true;
2057 }
2058
2059 if ( !objectEquals( oBuild.getOutputDirectory(), build.getOutputDirectory() ) )
2060 {
2061 return true;
2062 }
2063
2064 if ( !objectEquals( oBuild.getSourceDirectory(), build.getSourceDirectory() ) )
2065 {
2066 return true;
2067 }
2068
2069 if ( !objectEquals( oBuild.getTestSourceDirectory(), build.getTestSourceDirectory() ) )
2070 {
2071 return true;
2072 }
2073
2074 if ( !objectEquals( oBuild.getScriptSourceDirectory(), build.getScriptSourceDirectory() ) )
2075 {
2076 return true;
2077 }
2078
2079 return false;
2080 }
2081
2082 private boolean objectEquals( Object obj1, Object obj2 )
2083 {
2084 return obj1 == null ? obj2 == null : obj2 != null && ( obj1 == obj2 || obj1.equals( obj2 ) );
2085 }
2086
2087 private void propagateNewPlugins( MavenProject project )
2088 {
2089 Build changedBuild = project.getBuild();
2090 Build dynamicBuild = project.getDynamicBuild();
2091
2092 if ( changedBuild == null || dynamicBuild == null )
2093 {
2094 return;
2095 }
2096
2097 List changedPlugins = changedBuild.getPlugins();
2098 List dynamicPlugins = dynamicBuild.getPlugins();
2099
2100 if ( changedPlugins != null && dynamicPlugins != null && changedPlugins.size() != dynamicPlugins.size() )
2101 {
2102 changedPlugins.removeAll( dynamicPlugins );
2103 if ( !changedPlugins.isEmpty() )
2104 {
2105 for ( Iterator it = changedPlugins.iterator(); it.hasNext(); )
2106 {
2107 Plugin plugin = (Plugin) it.next();
2108
2109 dynamicBuild.addPlugin( plugin );
2110 }
2111 }
2112 }
2113
2114 dynamicBuild.flushPluginMap();
2115 }
2116
2117 private void restoreDynamicProjectReferences( MavenProject project,
2118 ProjectBuilderConfiguration config,
2119 Set processedProjects )
2120 throws ModelInterpolationException
2121 {
2122 Map projectRefs = project.getProjectReferences();
2123 if ( projectRefs != null )
2124 {
2125 for ( Iterator it = projectRefs.values().iterator(); it.hasNext(); )
2126 {
2127 MavenProject projectRef = (MavenProject) it.next();
2128 if ( !processedProjects.contains( projectRef.getId() ) )
2129 {
2130 restoreDynamicStateInternal( projectRef, config, true, processedProjects );
2131 }
2132 }
2133 }
2134 }
2135
2136 private void restoreBuildRoots( MavenProject project,
2137 ProjectBuilderConfiguration config,
2138 boolean debugMessages )
2139 throws ModelInterpolationException
2140 {
2141 project.setCompileSourceRoots( restoreListOfStrings( project.getDynamicCompileSourceRoots(),
2142 project.getOriginalInterpolatedCompileSourceRoots(),
2143 project.getCompileSourceRoots(),
2144 project,
2145 config,
2146 debugMessages ) );
2147
2148 project.setTestCompileSourceRoots( restoreListOfStrings( project.getDynamicTestCompileSourceRoots(),
2149 project.getOriginalInterpolatedTestCompileSourceRoots(),
2150 project.getTestCompileSourceRoots(),
2151 project,
2152 config,
2153 debugMessages ) );
2154
2155 project.setScriptSourceRoots( restoreListOfStrings( project.getDynamicScriptSourceRoots(),
2156 project.getOriginalInterpolatedScriptSourceRoots(),
2157 project.getScriptSourceRoots(),
2158 project,
2159 config,
2160 debugMessages ) );
2161
2162 project.clearRestorableRoots();
2163 }
2164
2165 private void restoreModelBuildSection( MavenProject project,
2166 ProjectBuilderConfiguration config,
2167 boolean debugMessages )
2168 throws ModelInterpolationException
2169 {
2170 Build changedBuild = project.getBuild();
2171 Build dynamicBuild = project.getDynamicBuild();
2172 Build originalInterpolatedBuild = project.getOriginalInterpolatedBuild();
2173
2174 dynamicBuild.setResources( restoreResources( dynamicBuild.getResources(),
2175 originalInterpolatedBuild.getResources(),
2176 changedBuild.getResources(),
2177 project,
2178 config,
2179 debugMessages ) );
2180
2181 dynamicBuild.setTestResources( restoreResources( dynamicBuild.getTestResources(),
2182 originalInterpolatedBuild.getTestResources(),
2183 changedBuild.getTestResources(),
2184 project,
2185 config,
2186 debugMessages ) );
2187
2188 dynamicBuild.setFilters( restoreListOfStrings( dynamicBuild.getFilters(),
2189 originalInterpolatedBuild.getFilters(),
2190 changedBuild.getFilters(),
2191 project,
2192 config,
2193 debugMessages ) );
2194
2195 dynamicBuild.setFinalName( restoreString( dynamicBuild.getFinalName(),
2196 originalInterpolatedBuild.getFinalName(),
2197 changedBuild.getFinalName(),
2198 project,
2199 config,
2200 debugMessages ) );
2201
2202 dynamicBuild.setDefaultGoal( restoreString( dynamicBuild.getDefaultGoal(),
2203 originalInterpolatedBuild.getDefaultGoal(),
2204 changedBuild.getDefaultGoal(),
2205 project,
2206 config,
2207 debugMessages ) );
2208
2209 dynamicBuild.setSourceDirectory( restoreString( dynamicBuild.getSourceDirectory(),
2210 originalInterpolatedBuild.getSourceDirectory(),
2211 changedBuild.getSourceDirectory(),
2212 project,
2213 config,
2214 debugMessages ) );
2215
2216 dynamicBuild.setTestSourceDirectory( restoreString( dynamicBuild.getTestSourceDirectory(),
2217 originalInterpolatedBuild.getTestSourceDirectory(),
2218 changedBuild.getTestSourceDirectory(),
2219 project,
2220 config,
2221 debugMessages ) );
2222
2223 dynamicBuild.setScriptSourceDirectory( restoreString( dynamicBuild.getScriptSourceDirectory(),
2224 originalInterpolatedBuild.getScriptSourceDirectory(),
2225 changedBuild.getScriptSourceDirectory(),
2226 project,
2227 config,
2228 debugMessages ) );
2229
2230 dynamicBuild.setOutputDirectory( restoreString( dynamicBuild.getOutputDirectory(),
2231 originalInterpolatedBuild.getOutputDirectory(),
2232 changedBuild.getOutputDirectory(),
2233 project,
2234 config,
2235 debugMessages ) );
2236
2237 dynamicBuild.setTestOutputDirectory( restoreString( dynamicBuild.getTestOutputDirectory(),
2238 originalInterpolatedBuild.getTestOutputDirectory(),
2239 changedBuild.getTestOutputDirectory(),
2240 project,
2241 config,
2242 debugMessages ) );
2243
2244 dynamicBuild.setDirectory( restoreString( dynamicBuild.getDirectory(),
2245 originalInterpolatedBuild.getDirectory(),
2246 changedBuild.getDirectory(),
2247 project,
2248 config,
2249 debugMessages ) );
2250
2251 propagateNewPlugins( project );
2252
2253 project.setBuild( dynamicBuild );
2254
2255 project.clearRestorableBuild();
2256 }
2257
2258 private List interpolateListOfStrings( List originalStrings,
2259 Model model,
2260 File projectDir,
2261 ProjectBuilderConfiguration config,
2262 boolean debugMessages )
2263 throws ModelInterpolationException
2264 {
2265 if ( originalStrings == null )
2266 {
2267 return null;
2268 }
2269
2270 List result = new ArrayList();
2271
2272 for ( Iterator it = originalStrings.iterator(); it.hasNext(); )
2273 {
2274 String original = (String) it.next();
2275 String interpolated = modelInterpolator.interpolate( original, model, projectDir, config, debugMessages );
2276
2277 result.add( interpolated );
2278 }
2279
2280 return result;
2281 }
2282
2283 private String restoreString( String originalString,
2284 String originalInterpolatedString,
2285 String changedString,
2286 MavenProject project,
2287 ProjectBuilderConfiguration config,
2288 boolean debugMessages )
2289 throws ModelInterpolationException
2290 {
2291 if ( originalString == null )
2292 {
2293 return changedString;
2294 }
2295 else if ( changedString == null )
2296 {
2297 return originalString;
2298 }
2299
2300 Model model = project.getModel();
2301
2302 String relativeChangedString;
2303 if ( project.getBasedir() != null )
2304 {
2305 relativeChangedString = pathTranslator.unalignFromBaseDirectory( changedString, project.getBasedir() );
2306 }
2307 else
2308 {
2309 relativeChangedString = changedString;
2310 }
2311
2312 String interpolatedOriginal = modelInterpolator.interpolate( originalString,
2313 model,
2314 project.getBasedir(),
2315 config,
2316 debugMessages );
2317
2318 interpolatedOriginal = pathTranslator.unalignFromBaseDirectory( interpolatedOriginal, project.getBasedir() );
2319
2320 String interpolatedOriginal2 = modelInterpolator.interpolate( originalInterpolatedString,
2321 model,
2322 project.getBasedir(),
2323 config,
2324 debugMessages );
2325
2326 interpolatedOriginal2 = pathTranslator.alignToBaseDirectory( interpolatedOriginal2, project.getBasedir() );
2327
2328 String interpolatedChanged = modelInterpolator.interpolate( changedString,
2329 model,
2330 project.getBasedir(),
2331 config,
2332 debugMessages );
2333
2334 interpolatedChanged = pathTranslator.alignToBaseDirectory( interpolatedChanged, project.getBasedir() );
2335
2336 String relativeInterpolatedChanged = modelInterpolator.interpolate( relativeChangedString,
2337 model,
2338 project.getBasedir(),
2339 config,
2340 debugMessages );
2341
2342 if ( interpolatedOriginal.equals( interpolatedChanged ) || interpolatedOriginal2.equals( interpolatedChanged ) )
2343 {
2344 return originalString;
2345 }
2346 else if ( interpolatedOriginal.equals( relativeInterpolatedChanged )
2347 || interpolatedOriginal2.equals( relativeInterpolatedChanged ) )
2348 {
2349 return originalString;
2350 }
2351
2352 return relativeChangedString;
2353 }
2354
2355 private List restoreListOfStrings( List originalStrings,
2356 List originalInterpolatedStrings,
2357 List changedStrings,
2358 MavenProject project,
2359 ProjectBuilderConfiguration config,
2360 boolean debugMessages )
2361 throws ModelInterpolationException
2362 {
2363 if ( originalStrings == null )
2364 {
2365 return changedStrings;
2366 }
2367 else if ( changedStrings == null )
2368 {
2369 return originalStrings;
2370 }
2371
2372 List result = new ArrayList();
2373
2374 Map orig = new HashMap();
2375 for ( int idx = 0; idx < originalStrings.size(); idx++ )
2376 {
2377 String[] permutations = new String[2];
2378
2379 permutations[0] = pathTranslator.alignToBaseDirectory( (String) originalInterpolatedStrings.get( idx ), project.getBasedir() );
2380 permutations[1] = (String) originalStrings.get( idx );
2381
2382 orig.put( permutations[0], permutations );
2383 }
2384
2385 for ( Iterator it = changedStrings.iterator(); it.hasNext(); )
2386 {
2387 String changedString = (String) it.next();
2388 String relativeChangedString;
2389 if ( project.getBasedir() != null )
2390 {
2391 relativeChangedString = pathTranslator.unalignFromBaseDirectory( changedString, project.getBasedir() );
2392 }
2393 else
2394 {
2395 relativeChangedString = changedString;
2396 }
2397
2398 String interpolated = modelInterpolator.interpolate( changedString,
2399 project.getModel(),
2400 project.getBasedir(),
2401 config,
2402 debugMessages );
2403
2404 interpolated = pathTranslator.alignToBaseDirectory( interpolated, project.getBasedir() );
2405
2406 String relativeInterpolated = modelInterpolator.interpolate( relativeChangedString,
2407 project.getModel(),
2408 project.getBasedir(),
2409 config,
2410 debugMessages );
2411
2412 String[] original = (String[]) orig.get( interpolated );
2413 if ( original == null )
2414 {
2415 original = (String[]) orig.get( relativeInterpolated );
2416 }
2417
2418 if ( original == null )
2419 {
2420 result.add( relativeChangedString );
2421 }
2422 else
2423 {
2424 result.add( original[1] );
2425 }
2426 }
2427
2428 return result;
2429 }
2430
2431 private List restoreResources( List originalResources,
2432 List originalInterpolatedResources,
2433 List changedResources,
2434 MavenProject project,
2435 ProjectBuilderConfiguration config,
2436 boolean debugMessages )
2437 throws ModelInterpolationException
2438 {
2439 if ( originalResources == null || changedResources == null )
2440 {
2441 return originalResources;
2442 }
2443
2444 List result = new ArrayList();
2445
2446 Map originalResourcesByMergeId = new HashMap();
2447 for ( int idx = 0; idx < originalResources.size(); idx++ )
2448 {
2449 Resource[] permutations = new Resource[2];
2450
2451 permutations[0] = (Resource) originalInterpolatedResources.get( idx );
2452 permutations[1] = (Resource) originalResources.get( idx );
2453
2454 originalResourcesByMergeId.put( permutations[0].getMergeId(), permutations );
2455 }
2456
2457 for ( Iterator it = changedResources.iterator(); it.hasNext(); )
2458 {
2459 Resource resource = (Resource) it.next();
2460 String mergeId = resource.getMergeId();
2461 if ( mergeId == null || !originalResourcesByMergeId.containsKey( mergeId ) )
2462 {
2463 result.add( resource );
2464 }
2465 else
2466 {
2467 Resource originalInterpolatedResource = ( (Resource[]) originalResourcesByMergeId.get( mergeId ) )[0];
2468 Resource originalResource = ( (Resource[]) originalResourcesByMergeId.get( mergeId ) )[1];
2469
2470 String dir = modelInterpolator.interpolate( resource.getDirectory(), project.getModel(), project.getBasedir(), config, getLogger().isDebugEnabled() );
2471 String oDir = originalInterpolatedResource.getDirectory();
2472
2473 if ( !dir.equals( oDir ) )
2474 {
2475 originalResource.setDirectory( pathTranslator.unalignFromBaseDirectory( dir, project.getBasedir() ) );
2476 }
2477
2478 if ( resource.getTargetPath() != null )
2479 {
2480 String target = modelInterpolator.interpolate( resource.getTargetPath(), project.getModel(), project.getBasedir(), config, getLogger().isDebugEnabled() );
2481
2482 String oTarget = originalInterpolatedResource.getTargetPath();
2483
2484 if ( !target.equals( oTarget ) )
2485 {
2486 originalResource.setTargetPath( pathTranslator.unalignFromBaseDirectory( target, project.getBasedir() ) );
2487 }
2488 }
2489
2490 originalResource.setFiltering( resource.isFiltering() );
2491
2492 originalResource.setExcludes( collectRestoredListOfPatterns( resource.getExcludes(),
2493 originalResource.getExcludes(),
2494 originalInterpolatedResource.getExcludes() ) );
2495
2496 originalResource.setIncludes( collectRestoredListOfPatterns( resource.getIncludes(),
2497 originalResource.getIncludes(),
2498 originalInterpolatedResource.getIncludes() ) );
2499
2500 result.add( originalResource );
2501 }
2502 }
2503
2504 return result;
2505 }
2506
2507 private List collectRestoredListOfPatterns( List patterns,
2508 List originalPatterns,
2509 List originalInterpolatedPatterns )
2510 {
2511 LinkedHashSet collectedPatterns = new LinkedHashSet();
2512
2513 collectedPatterns.addAll( originalPatterns );
2514
2515 for ( Iterator it = patterns.iterator(); it.hasNext(); )
2516 {
2517 String pattern = (String) it.next();
2518 if ( !originalInterpolatedPatterns.contains( pattern ) )
2519 {
2520 collectedPatterns.add( pattern );
2521 }
2522 }
2523
2524 return collectedPatterns.isEmpty() ? Collections.EMPTY_LIST
2525 : new ArrayList( collectedPatterns );
2526 }
2527
2528 }