View Javadoc

1   package org.apache.maven.project;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.io.Writer;
25  import java.util.ArrayList;
26  import java.util.Collections;
27  import java.util.Enumeration;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  import java.util.LinkedHashSet;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Properties;
34  import java.util.Set;
35  
36  import org.apache.maven.artifact.Artifact;
37  import org.apache.maven.artifact.ArtifactUtils;
38  import org.apache.maven.artifact.DependencyResolutionRequiredException;
39  import org.apache.maven.artifact.versioning.ManagedVersionMap;
40  import org.apache.maven.artifact.factory.ArtifactFactory;
41  import org.apache.maven.artifact.repository.ArtifactRepository;
42  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
43  import org.apache.maven.model.Build;
44  import org.apache.maven.model.CiManagement;
45  import org.apache.maven.model.Contributor;
46  import org.apache.maven.model.Dependency;
47  import org.apache.maven.model.DependencyManagement;
48  import org.apache.maven.model.Developer;
49  import org.apache.maven.model.DistributionManagement;
50  import org.apache.maven.model.IssueManagement;
51  import org.apache.maven.model.License;
52  import org.apache.maven.model.MailingList;
53  import org.apache.maven.model.Model;
54  import org.apache.maven.model.Organization;
55  import org.apache.maven.model.Plugin;
56  import org.apache.maven.model.PluginExecution;
57  import org.apache.maven.model.PluginManagement;
58  import org.apache.maven.model.Prerequisites;
59  import org.apache.maven.model.ReportPlugin;
60  import org.apache.maven.model.ReportSet;
61  import org.apache.maven.model.Reporting;
62  import org.apache.maven.model.Resource;
63  import org.apache.maven.model.Scm;
64  import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
65  import org.apache.maven.project.artifact.ActiveProjectArtifact;
66  import org.apache.maven.project.artifact.InvalidDependencyVersionException;
67  import org.apache.maven.project.artifact.MavenMetadataSource;
68  import org.codehaus.plexus.logging.Logger;
69  import org.codehaus.plexus.util.xml.Xpp3Dom;
70  
71  /**
72   * The concern of the project is provide runtime values based on the model. <p/>
73   * The values in the model remain untouched but during the process of building a
74   * project notions like inheritance and interpolation can be added. This allows
75   * to have an entity which is useful in a runtime while preserving the model so
76   * that it can be marshalled and unmarshalled without being tainted by runtime
77   * requirements. <p/>We need to leave the model intact because we don't want
78   * the following:
79   * <ol>
80   * <li>We don't want interpolated values being written back into the model.
81   * <li>We don't want inherited values being written back into the model.
82   * </ol>
83   */
84  public class MavenProject
85      implements Cloneable
86  {
87      public static final String EMPTY_PROJECT_GROUP_ID = "unknown";
88      
89      public static final String EMPTY_PROJECT_ARTIFACT_ID = "empty-project";
90      
91      public static final String EMPTY_PROJECT_VERSION = "0";
92      
93      private Model model;
94  
95      private MavenProject parent;
96  
97      private File file;
98  
99      private Set artifacts;
100 
101     private Artifact parentArtifact;
102 
103     private Set pluginArtifacts;
104 
105     private List remoteArtifactRepositories;
106 
107     private List collectedProjects = Collections.EMPTY_LIST;
108 
109     private List attachedArtifacts;
110 
111     private MavenProject executionProject;
112 
113     private List compileSourceRoots = new ArrayList();
114 
115     private List testCompileSourceRoots = new ArrayList();
116 
117     private List scriptSourceRoots = new ArrayList();
118 
119     private List pluginArtifactRepositories;
120 
121     private ArtifactRepository releaseArtifactRepository;
122 
123     private ArtifactRepository snapshotArtifactRepository;
124 
125     private List activeProfiles = new ArrayList();
126 
127     private Set dependencyArtifacts;
128 
129     private Artifact artifact;
130 
131     // calculated.
132     private Map artifactMap;
133 
134     private Model originalModel;
135 
136     private Map pluginArtifactMap;
137 
138     private Set reportArtifacts;
139 
140     private Map reportArtifactMap;
141 
142     private Set extensionArtifacts;
143 
144     private Map extensionArtifactMap;
145 
146     private Map managedVersionMap;
147 
148     private Map projectReferences = new HashMap();
149 
150     private boolean executionRoot;
151     
152     private Map moduleAdjustments;
153 
154     private File basedir;
155     
156     private Logger logger;
157     
158     private ProjectBuilderConfiguration projectBuilderConfiguration;
159     
160     public MavenProject()
161     {
162         Model model = new Model();
163         
164         model.setGroupId( EMPTY_PROJECT_GROUP_ID );
165         model.setArtifactId( EMPTY_PROJECT_ARTIFACT_ID );
166         model.setVersion( EMPTY_PROJECT_VERSION );
167         
168         this.setModel( model );
169     }
170 
171     public MavenProject( Model model )
172     {
173         this.setModel( model );
174     }
175 
176     public MavenProject( Model model, Logger logger )
177     {
178         this.setModel( model );
179         this.setLogger( logger );
180     }
181 
182     /**
183      * @deprecated use {@link #clone()} so subclasses can provide a copy of the same class
184      */
185     public MavenProject( MavenProject project )
186     {
187         deepCopy( project );
188     }
189 
190     private final void deepCopy(MavenProject project){
191         // disown the parent
192 
193         // copy fields
194         setFile( project.getFile() );
195 
196         // don't need a deep copy, they don't get modified or added/removed to/from - but make them unmodifiable to be
197         // sure!
198         if ( project.getDependencyArtifacts() != null )
199         {
200             setDependencyArtifacts( Collections.unmodifiableSet( project.getDependencyArtifacts() ) );
201         }
202 
203         if ( project.getArtifacts() != null )
204         {
205             setArtifacts( Collections.unmodifiableSet( project.getArtifacts() ) );
206         }
207 
208         if ( project.getPluginArtifacts() != null )
209         {
210             setPluginArtifacts( Collections.unmodifiableSet( project.getPluginArtifacts() ) );
211         }
212 
213         if ( project.getReportArtifacts() != null )
214         {
215             setReportArtifacts( Collections.unmodifiableSet( project.getReportArtifacts() ) );
216         }
217 
218         if ( project.getExtensionArtifacts() != null )
219         {
220             setExtensionArtifacts( Collections.unmodifiableSet( project.getExtensionArtifacts() ) );
221         }
222 
223         setParentArtifact( ( project.getParentArtifact() ) );
224 
225         if ( project.getRemoteArtifactRepositories() != null )
226         {
227             setRemoteArtifactRepositories( Collections.unmodifiableList( project.getRemoteArtifactRepositories() ) );
228         }
229 
230         if ( project.getPluginArtifactRepositories() != null )
231         {
232             setPluginArtifactRepositories( ( Collections.unmodifiableList( project.getPluginArtifactRepositories() ) ) );
233         }
234 
235         if ( project.getCollectedProjects() != null )
236         {
237             setCollectedProjects( ( Collections.unmodifiableList( project.getCollectedProjects() ) ) );
238         }
239 
240         if ( project.getActiveProfiles() != null )
241         {
242             setActiveProfiles( ( Collections.unmodifiableList( project.getActiveProfiles() ) ) );
243         }
244 
245         if ( project.getAttachedArtifacts() != null )
246         {
247             // clone properties modifyable by plugins in a forked lifecycle
248             setAttachedArtifacts( new ArrayList( project.getAttachedArtifacts() ) );
249         }
250 
251         if ( project.getCompileSourceRoots() != null )
252         {
253             // clone source roots
254             setCompileSourceRoots( ( new ArrayList( project.getCompileSourceRoots() ) ) );
255         }
256 
257         if ( project.getTestCompileSourceRoots() != null )
258         {
259             setTestCompileSourceRoots( ( new ArrayList( project.getTestCompileSourceRoots() ) ) );
260         }
261 
262         if ( project.getScriptSourceRoots() != null )
263         {
264             setScriptSourceRoots( ( new ArrayList( project.getScriptSourceRoots() ) ) );
265         }
266 
267         setModel( ( ModelUtils.cloneModel( project.getModel() ) ) );
268 
269         if ( project.getOriginalModel() != null )
270         {
271             setOriginalModel( ( ModelUtils.cloneModel( project.getOriginalModel() ) ) );
272         }
273 
274         setExecutionRoot( project.isExecutionRoot() );
275 
276         if ( project.getArtifact() != null )
277         {
278             setArtifact( ArtifactUtils.copyArtifact( project.getArtifact() ) );
279         }
280 
281         if ( project.getManagedVersionMap() != null )
282         {
283             setManagedVersionMap( new ManagedVersionMap( project.getManagedVersionMap() ) );
284         }
285         
286         if ( project.getReleaseArtifactRepository() != null )
287         {
288             setReleaseArtifactRepository( project.getReleaseArtifactRepository() );
289         }
290         
291         if ( project.getSnapshotArtifactRepository() != null )
292         {
293             setSnapshotArtifactRepository( project.getSnapshotArtifactRepository() );
294         }
295 
296         if ( project.isConcrete() )
297         {
298             setDynamicBuild( ModelUtils.cloneBuild( project.getDynamicBuild() ) );
299             setOriginalInterpolatedBuild( ModelUtils.cloneBuild( project.getOriginalInterpolatedBuild() ) );
300 
301             List dynamicRoots = project.getDynamicCompileSourceRoots();
302             if ( dynamicRoots != null )
303             {
304                 setDynamicCompileSourceRoots( new ArrayList( dynamicRoots ) );
305                 setOriginalInterpolatedCompileSourceRoots( new ArrayList( project.getOriginalInterpolatedCompileSourceRoots() ) );
306             }
307 
308             dynamicRoots = project.getDynamicTestCompileSourceRoots();
309             if ( dynamicRoots != null )
310             {
311                 setDynamicTestCompileSourceRoots( new ArrayList( dynamicRoots ) );
312                 setOriginalInterpolatedTestCompileSourceRoots( new ArrayList( project.getOriginalInterpolatedTestCompileSourceRoots() ) );
313             }
314 
315             dynamicRoots = project.getDynamicScriptSourceRoots();
316             if ( dynamicRoots != null )
317             {
318                 setDynamicScriptSourceRoots( new ArrayList( dynamicRoots ) );
319                 setOriginalInterpolatedScriptSourceRoots( new ArrayList( project.getOriginalInterpolatedScriptSourceRoots() ) );
320             }
321         }
322 
323         preservedProperties = project.preservedProperties;
324         preservedBasedir = project.preservedBasedir;
325         setConcrete( project.isConcrete() );
326     }
327     
328     public String getModulePathAdjustment( MavenProject moduleProject ) throws IOException
329     {
330         // FIXME: This is hacky. What if module directory doesn't match artifactid, and parent
331         // is coming from the repository??
332         
333         // FIXME: If there is a hierarchy of three projects, with the url specified at the top, 
334         // and the top two projects are referenced from copies that are in the repository, the
335         // middle-level POM doesn't have a File associated with it (or the file's directory is
336         // of an unexpected name), and module path adjustments fail.
337         String module = moduleProject.getArtifactId();
338         
339         File moduleFile = moduleProject.getFile();
340         
341         if ( moduleFile != null )
342         {
343             File moduleDir = moduleFile.getCanonicalFile().getParentFile();
344             
345             module = moduleDir.getName();
346         }
347         
348         if ( moduleAdjustments == null )
349         {
350             moduleAdjustments = new HashMap();
351             
352             List modules = getModules();
353             if ( modules != null )
354             {
355                 for ( Iterator it = modules.iterator(); it.hasNext(); )
356                 {
357                     String modulePath = (String) it.next();
358                     String moduleName = modulePath;
359                     
360                     if ( moduleName.endsWith( "/" ) || moduleName.endsWith( "\\" ) )
361                     {
362                         moduleName = moduleName.substring( 0, moduleName.length() - 1 );
363                     }
364                     
365                     int lastSlash = moduleName.lastIndexOf( '/' );
366                     
367                     if ( lastSlash < 0 )
368                     {
369                         lastSlash = moduleName.lastIndexOf( '\\' );
370                     }
371                     
372                     String adjustment = null;
373                     
374                     if ( lastSlash > -1 )
375                     {
376                         moduleName = moduleName.substring( lastSlash + 1 );
377                         adjustment = modulePath.substring( 0, lastSlash );
378                     }
379 
380                     moduleAdjustments.put( moduleName, adjustment );
381                 }
382             }
383         }
384         
385         return (String) moduleAdjustments.get( module );
386     }
387 
388     // ----------------------------------------------------------------------
389     // Accessors
390     // ----------------------------------------------------------------------
391 
392     public Artifact getArtifact()
393     {
394         return artifact;
395     }
396 
397     public void setArtifact( Artifact artifact )
398     {
399         this.artifact = artifact;
400     }
401 
402     //@todo I would like to get rid of this. jvz.
403     public Model getModel()
404     {
405         return model;
406     }
407 
408     public MavenProject getParent()
409     {
410         return parent;
411     }
412 
413     public void setParent( MavenProject parent )
414     {
415         this.parent = parent;
416     }
417 
418     public void setRemoteArtifactRepositories( List remoteArtifactRepositories )
419     {
420         this.remoteArtifactRepositories = remoteArtifactRepositories;
421     }
422 
423     public List getRemoteArtifactRepositories()
424     {
425         return remoteArtifactRepositories;
426     }
427 
428     public boolean hasParent()
429     {
430         return getParent() != null;
431     }
432 
433     public File getFile()
434     {
435         return file;
436     }
437 
438     public void setFile( File file )
439     {
440         if ( file == null )
441         {
442             return;
443         }
444         
445         if ( basedir == null )
446         {
447             basedir = file.getParentFile();
448         }
449         
450         this.file = file;
451     }
452     
453     public void setBasedir( File basedir )
454     {
455         this.basedir = basedir;
456     }
457 
458     public File getBasedir()
459     {
460         return basedir;
461     }
462 
463     public void setDependencies( List dependencies )
464     {
465         getModel().setDependencies( dependencies );
466     }
467 
468     public List getDependencies()
469     {
470         return getModel().getDependencies();
471     }
472 
473     public DependencyManagement getDependencyManagement()
474     {
475         return getModel().getDependencyManagement();
476     }
477 
478     // ----------------------------------------------------------------------
479     // Test and compile sourceroots.
480     // ----------------------------------------------------------------------
481 
482     public void addCompileSourceRoot( String path )
483     {
484         if ( path != null )
485         {
486             path = path.trim();
487             if ( path.length() != 0 )
488             {
489                 if ( !getCompileSourceRoots().contains( path ) )
490                 {
491                     getCompileSourceRoots().add( path );
492                 }
493             }
494         }
495     }
496 
497     public void addScriptSourceRoot( String path )
498     {
499         if ( path != null )
500         {
501             path = path.trim();
502             if ( path.length() != 0 )
503             {
504                 if ( !getScriptSourceRoots().contains( path ) )
505                 {
506                     getScriptSourceRoots().add( path );
507                 }
508             }
509         }
510     }
511 
512     public void addTestCompileSourceRoot( String path )
513     {
514         if ( path != null )
515         {
516             path = path.trim();
517             if ( path.length() != 0 )
518             {
519                 if ( !getTestCompileSourceRoots().contains( path ) )
520                 {
521                     getTestCompileSourceRoots().add( path );
522                 }
523             }
524         }
525     }
526 
527     public List getCompileSourceRoots()
528     {
529         return compileSourceRoots;
530     }
531 
532     public List getScriptSourceRoots()
533     {
534         return scriptSourceRoots;
535     }
536 
537     public List getTestCompileSourceRoots()
538     {
539         return testCompileSourceRoots;
540     }
541 
542     public List getCompileClasspathElements()
543         throws DependencyResolutionRequiredException
544     {
545         List list = new ArrayList( getArtifacts().size() );
546 
547         list.add( getBuild().getOutputDirectory() );
548 
549         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
550         {
551             Artifact a = (Artifact) i.next();
552 
553             if ( a.getArtifactHandler().isAddedToClasspath() )
554             {
555                 // TODO: let the scope handler deal with this
556                 if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) ||
557                     Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
558                 {
559                     addArtifactPath( a, list );
560                 }
561             }
562         }
563         return list;
564     }
565 
566     public List getCompileArtifacts()
567     {
568         List list = new ArrayList( getArtifacts().size() );
569 
570         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
571         {
572             Artifact a = (Artifact) i.next();
573 
574             // TODO: classpath check doesn't belong here - that's the other method
575             if ( a.getArtifactHandler().isAddedToClasspath() )
576             {
577                 // TODO: let the scope handler deal with this
578                 if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) ||
579                     Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
580                 {
581                     list.add( a );
582                 }
583             }
584         }
585         return list;
586     }
587 
588     public List getCompileDependencies()
589     {
590         Set artifacts = getArtifacts();
591 
592         if ( artifacts == null || artifacts.isEmpty() )
593         {
594             return Collections.EMPTY_LIST;
595         }
596 
597         List list = new ArrayList( artifacts.size() );
598 
599         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
600         {
601             Artifact a = (Artifact) i.next();
602 
603             // TODO: let the scope handler deal with this
604             if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) ||
605                 Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
606             {
607                 Dependency dependency = new Dependency();
608 
609                 dependency.setArtifactId( a.getArtifactId() );
610                 dependency.setGroupId( a.getGroupId() );
611                 dependency.setVersion( a.getVersion() );
612                 dependency.setScope( a.getScope() );
613                 dependency.setType( a.getType() );
614                 dependency.setClassifier( a.getClassifier() );
615 
616                 list.add( dependency );
617             }
618         }
619         return list;
620     }
621 
622     public List getTestClasspathElements()
623         throws DependencyResolutionRequiredException
624     {
625         List list = new ArrayList( getArtifacts().size() + 1 );
626 
627         list.add( getBuild().getTestOutputDirectory() );
628 
629         list.add( getBuild().getOutputDirectory() );
630         
631         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
632         {
633             Artifact a = (Artifact) i.next();
634 
635             if ( a.getArtifactHandler().isAddedToClasspath() )
636             {
637                 // TODO: let the scope handler deal with this
638                 // NOTE: [jc] scope == 'test' is the widest possible scope, so we don't really need to perform
639                 // this check...
640                 // if ( Artifact.SCOPE_TEST.equals( a.getScope() ) || Artifact.SCOPE_COMPILE.equals( a.getScope() ) ||
641                 //     Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
642                 // {
643                 // }
644                 File file = a.getFile();
645                 if ( file == null )
646                 {
647                     throw new DependencyResolutionRequiredException( a );
648                 }
649                 list.add( file.getPath() );
650             }
651         }
652         return list;
653     }
654 
655     public List getTestArtifacts()
656     {
657         List list = new ArrayList( getArtifacts().size() );
658 
659         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
660         {
661             Artifact a = (Artifact) i.next();
662 
663             // TODO: classpath check doesn't belong here - that's the other method
664             if ( a.getArtifactHandler().isAddedToClasspath() )
665             {
666                 // TODO: let the scope handler deal with this
667                 // NOTE: [jc] scope == 'test' is the widest possible scope, so we don't really need to perform
668                 // this check...
669                 // if ( Artifact.SCOPE_TEST.equals( a.getScope() ) || Artifact.SCOPE_COMPILE.equals( a.getScope() ) ||
670                 //      Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
671                 // {
672                 //     list.add( a );
673                 // }
674 
675                 list.add( a );
676             }
677         }
678         return list;
679     }
680 
681     public List getTestDependencies()
682     {
683         Set artifacts = getArtifacts();
684 
685         if ( artifacts == null || artifacts.isEmpty() )
686         {
687             return Collections.EMPTY_LIST;
688         }
689 
690         List list = new ArrayList( artifacts.size() );
691 
692         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
693         {
694             Artifact a = (Artifact) i.next();
695 
696             // TODO: let the scope handler deal with this
697             // NOTE: [jc] scope == 'test' is the widest possible scope, so we don't really need to perform
698             // this check...
699             // if ( Artifact.SCOPE_TEST.equals( a.getScope() ) || Artifact.SCOPE_COMPILE.equals( a.getScope() ) ||
700             //     Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
701             // {
702             // }
703 
704             Dependency dependency = new Dependency();
705 
706             dependency.setArtifactId( a.getArtifactId() );
707             dependency.setGroupId( a.getGroupId() );
708             dependency.setVersion( a.getVersion() );
709             dependency.setScope( a.getScope() );
710             dependency.setType( a.getType() );
711             dependency.setClassifier( a.getClassifier() );
712 
713             list.add( dependency );
714         }
715         return list;
716     }
717 
718     public List getRuntimeClasspathElements()
719         throws DependencyResolutionRequiredException
720     {
721         List list = new ArrayList( getArtifacts().size() + 1 );
722 
723         list.add( getBuild().getOutputDirectory() );
724 
725         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
726         {
727             Artifact a = (Artifact) i.next();
728 
729             if ( a.getArtifactHandler().isAddedToClasspath() )
730             {
731                 // TODO: let the scope handler deal with this
732                 if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
733                 {
734                     File file = a.getFile();
735                     if ( file == null )
736                     {
737                         throw new DependencyResolutionRequiredException( a );
738                     }
739                     list.add( file.getPath() );
740                 }
741             }
742         }
743         return list;
744     }
745 
746     public List getRuntimeArtifacts()
747     {
748         List list = new ArrayList( getArtifacts().size() );
749 
750         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
751         {
752             Artifact a = (Artifact) i.next();
753 
754             // TODO: classpath check doesn't belong here - that's the other method
755             if ( a.getArtifactHandler().isAddedToClasspath() )
756             {
757                 // TODO: let the scope handler deal with this
758                 if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
759                 {
760                     list.add( a );
761                 }
762             }
763         }
764         return list;
765     }
766 
767     public List getRuntimeDependencies()
768     {
769         Set artifacts = getArtifacts();
770 
771         if ( artifacts == null || artifacts.isEmpty() )
772         {
773             return Collections.EMPTY_LIST;
774         }
775 
776         List list = new ArrayList( artifacts.size() );
777 
778         for ( Iterator i = artifacts.iterator(); i.hasNext(); )
779         {
780             Artifact a = (Artifact) i.next();
781 
782             // TODO: let the scope handler deal with this
783             if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
784             {
785                 Dependency dependency = new Dependency();
786 
787                 dependency.setArtifactId( a.getArtifactId() );
788                 dependency.setGroupId( a.getGroupId() );
789                 dependency.setVersion( a.getVersion() );
790                 dependency.setScope( a.getScope() );
791                 dependency.setType( a.getType() );
792                 dependency.setClassifier( a.getClassifier() );
793 
794                 list.add( dependency );
795             }
796         }
797         return list;
798     }
799 
800     public List getSystemClasspathElements()
801         throws DependencyResolutionRequiredException
802     {
803         List list = new ArrayList( getArtifacts().size() );
804 
805         list.add( getBuild().getOutputDirectory() );
806 
807         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
808         {
809             Artifact a = (Artifact) i.next();
810 
811             if ( a.getArtifactHandler().isAddedToClasspath() )
812             {
813                 // TODO: let the scope handler deal with this
814                 if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
815                 {
816                     addArtifactPath( a, list );
817                 }
818             }
819         }
820         return list;
821     }
822 
823     public List getSystemArtifacts()
824     {
825         List list = new ArrayList( getArtifacts().size() );
826 
827         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
828         {
829             Artifact a = (Artifact) i.next();
830 
831             // TODO: classpath check doesn't belong here - that's the other method
832             if ( a.getArtifactHandler().isAddedToClasspath() )
833             {
834                 // TODO: let the scope handler deal with this
835                 if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
836                 {
837                     list.add( a );
838                 }
839             }
840         }
841         return list;
842     }
843 
844     public List getSystemDependencies()
845     {
846         Set artifacts = getArtifacts();
847 
848         if ( artifacts == null || artifacts.isEmpty() )
849         {
850             return Collections.EMPTY_LIST;
851         }
852 
853         List list = new ArrayList( artifacts.size() );
854 
855         for ( Iterator i = getArtifacts().iterator(); i.hasNext(); )
856         {
857             Artifact a = (Artifact) i.next();
858 
859             // TODO: let the scope handler deal with this
860             if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
861             {
862                 Dependency dependency = new Dependency();
863 
864                 dependency.setArtifactId( a.getArtifactId() );
865                 dependency.setGroupId( a.getGroupId() );
866                 dependency.setVersion( a.getVersion() );
867                 dependency.setScope( a.getScope() );
868                 dependency.setType( a.getType() );
869                 dependency.setClassifier( a.getClassifier() );
870 
871                 list.add( dependency );
872             }
873         }
874         return list;
875     }
876 
877     // ----------------------------------------------------------------------
878     // Delegate to the model
879     // ----------------------------------------------------------------------
880 
881     public void setModelVersion( String pomVersion )
882     {
883         getModel().setModelVersion( pomVersion );
884     }
885 
886     public String getModelVersion()
887     {
888         return getModel().getModelVersion();
889     }
890 
891     public String getId()
892     {
893         return getModel().getId();
894     }
895 
896     public void setGroupId( String groupId )
897     {
898         getModel().setGroupId( groupId );
899     }
900 
901     public String getGroupId()
902     {
903         String groupId = getModel().getGroupId();
904 
905         if ( ( groupId == null ) && ( getModel().getParent() != null ) )
906         {
907             groupId = getModel().getParent().getGroupId();
908         }
909         
910         return groupId;
911     }
912 
913     public void setArtifactId( String artifactId )
914     {
915         getModel().setArtifactId( artifactId );
916     }
917 
918     public String getArtifactId()
919     {
920         return getModel().getArtifactId();
921     }
922 
923     public void setName( String name )
924     {
925         getModel().setName( name );
926     }
927 
928     public String getName()
929     {
930         // TODO: this should not be allowed to be null.
931         if ( getModel().getName() != null )
932         {
933             return getModel().getName();
934         }
935         else
936         {
937             return "Unnamed - " + getId();
938         }
939     }
940 
941     public void setVersion( String version )
942     {
943         getModel().setVersion( version );
944     }
945 
946     public String getVersion()
947     {
948         String version = getModel().getVersion();
949 
950         if ( ( version == null ) && ( getModel().getParent() != null ) )
951         {
952             version = getModel().getParent().getVersion();
953         }
954         
955         return version;
956     }
957 
958     public String getPackaging()
959     {
960         return getModel().getPackaging();
961     }
962 
963     public void setPackaging( String packaging )
964     {
965         getModel().setPackaging( packaging );
966     }
967 
968     public void setInceptionYear( String inceptionYear )
969     {
970         getModel().setInceptionYear( inceptionYear );
971     }
972 
973     public String getInceptionYear()
974     {
975         return getModel().getInceptionYear();
976     }
977 
978     public void setUrl( String url )
979     {
980         getModel().setUrl( url );
981     }
982 
983     public String getUrl()
984     {
985         return getModel().getUrl();
986     }
987 
988     public Prerequisites getPrerequisites()
989     {
990         return getModel().getPrerequisites();
991     }
992 
993     public void setIssueManagement( IssueManagement issueManagement )
994     {
995         getModel().setIssueManagement( issueManagement );
996     }
997 
998     public CiManagement getCiManagement()
999     {
1000         return getModel().getCiManagement();
1001     }
1002 
1003     public void setCiManagement( CiManagement ciManagement )
1004     {
1005         getModel().setCiManagement( ciManagement );
1006     }
1007 
1008     public IssueManagement getIssueManagement()
1009     {
1010         return getModel().getIssueManagement();
1011     }
1012 
1013     public void setDistributionManagement( DistributionManagement distributionManagement )
1014     {
1015         getModel().setDistributionManagement( distributionManagement );
1016     }
1017 
1018     public DistributionManagement getDistributionManagement()
1019     {
1020         return getModel().getDistributionManagement();
1021     }
1022 
1023     public void setDescription( String description )
1024     {
1025         getModel().setDescription( description );
1026     }
1027 
1028     public String getDescription()
1029     {
1030         return getModel().getDescription();
1031     }
1032 
1033     public void setOrganization( Organization organization )
1034     {
1035         getModel().setOrganization( organization );
1036     }
1037 
1038     public Organization getOrganization()
1039     {
1040         return getModel().getOrganization();
1041     }
1042 
1043     public void setScm( Scm scm )
1044     {
1045         getModel().setScm( scm );
1046     }
1047 
1048     public Scm getScm()
1049     {
1050         return getModel().getScm();
1051     }
1052 
1053     public void setMailingLists( List mailingLists )
1054     {
1055         getModel().setMailingLists( mailingLists );
1056     }
1057 
1058     public List getMailingLists()
1059     {
1060         return getModel().getMailingLists();
1061     }
1062 
1063     public void addMailingList( MailingList mailingList )
1064     {
1065         getModel().addMailingList( mailingList );
1066     }
1067 
1068     public void setDevelopers( List developers )
1069     {
1070         getModel().setDevelopers( developers );
1071     }
1072 
1073     public List getDevelopers()
1074     {
1075         return getModel().getDevelopers();
1076     }
1077 
1078     public void addDeveloper( Developer developer )
1079     {
1080         getModel().addDeveloper( developer );
1081     }
1082 
1083     public void setContributors( List contributors )
1084     {
1085         getModel().setContributors( contributors );
1086     }
1087 
1088     public List getContributors()
1089     {
1090         return getModel().getContributors();
1091     }
1092 
1093     public void addContributor( Contributor contributor )
1094     {
1095         getModel().addContributor( contributor );
1096     }
1097 
1098     public void setBuild( Build build )
1099     {
1100         getModel().setBuild( build );
1101     }
1102 
1103     public Build getBuild()
1104     {
1105         return getModelBuild();
1106     }
1107 
1108     public List getResources()
1109     {
1110         return getBuild().getResources();
1111     }
1112 
1113     public List getTestResources()
1114     {
1115         return getBuild().getTestResources();
1116     }
1117 
1118     public void addResource( Resource resource )
1119     {
1120         getBuild().addResource( resource );
1121     }
1122 
1123     public void addTestResource( Resource testResource )
1124     {
1125         getBuild().addTestResource( testResource );
1126     }
1127 
1128     public void setReporting( Reporting reporting )
1129     {
1130         getModel().setReporting( reporting );
1131     }
1132 
1133     public Reporting getReporting()
1134     {
1135         return getModel().getReporting();
1136     }
1137 
1138     public void setLicenses( List licenses )
1139     {
1140         getModel().setLicenses( licenses );
1141     }
1142 
1143     public List getLicenses()
1144     {
1145         return getModel().getLicenses();
1146     }
1147 
1148     public void addLicense( License license )
1149     {
1150         getModel().addLicense( license );
1151     }
1152 
1153     public void setArtifacts( Set artifacts )
1154     {
1155         this.artifacts = artifacts;
1156 
1157         // flush the calculated artifactMap
1158         this.artifactMap = null;
1159     }
1160 
1161     /**
1162      * All dependencies that this project has, including transitive ones.
1163      * Contents are lazily populated, so depending on what phases have run dependencies in some scopes won't be included.
1164      * eg. if only compile phase has run, dependencies with scope test won't be included. 
1165      * @return {@link Set} &lt; {@link Artifact} >
1166      * @see #getDependencyArtifacts() to get only direct dependencies
1167      */
1168     public Set getArtifacts()
1169     {
1170         return artifacts == null ? Collections.EMPTY_SET : artifacts;
1171     }
1172 
1173     public Map getArtifactMap()
1174     {
1175         if ( artifactMap == null )
1176         {
1177             artifactMap = ArtifactUtils.artifactMapByVersionlessId( getArtifacts() );
1178         }
1179 
1180         return artifactMap;
1181     }
1182 
1183     public void setPluginArtifacts( Set pluginArtifacts )
1184     {
1185         this.pluginArtifacts = pluginArtifacts;
1186 
1187         this.pluginArtifactMap = null;
1188     }
1189 
1190     public Set getPluginArtifacts()
1191     {
1192         return pluginArtifacts;
1193     }
1194 
1195     public Map getPluginArtifactMap()
1196     {
1197         if ( pluginArtifactMap == null )
1198         {
1199             pluginArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getPluginArtifacts() );
1200         }
1201 
1202         return pluginArtifactMap;
1203     }
1204 
1205     public void setReportArtifacts( Set reportArtifacts )
1206     {
1207         this.reportArtifacts = reportArtifacts;
1208 
1209         this.reportArtifactMap = null;
1210     }
1211 
1212     public Set getReportArtifacts()
1213     {
1214         return reportArtifacts;
1215     }
1216 
1217     public Map getReportArtifactMap()
1218     {
1219         if ( reportArtifactMap == null )
1220         {
1221             reportArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getReportArtifacts() );
1222         }
1223 
1224         return reportArtifactMap;
1225     }
1226 
1227     public void setExtensionArtifacts( Set extensionArtifacts )
1228     {
1229         this.extensionArtifacts = extensionArtifacts;
1230 
1231         this.extensionArtifactMap = null;
1232     }
1233 
1234     public Set getExtensionArtifacts()
1235     {
1236         return this.extensionArtifacts;
1237     }
1238 
1239     public Map getExtensionArtifactMap()
1240     {
1241         if ( extensionArtifactMap == null )
1242         {
1243             extensionArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getExtensionArtifacts() );
1244         }
1245 
1246         return extensionArtifactMap;
1247     }
1248 
1249     public void setParentArtifact( Artifact parentArtifact )
1250     {
1251         this.parentArtifact = parentArtifact;
1252     }
1253 
1254     public Artifact getParentArtifact()
1255     {
1256         return parentArtifact;
1257     }
1258 
1259     public List getRepositories()
1260     {
1261         return getModel().getRepositories();
1262     }
1263 
1264     // ----------------------------------------------------------------------
1265     // Plugins
1266     // ----------------------------------------------------------------------
1267 
1268     public List getReportPlugins()
1269     {
1270         if ( getModel().getReporting() == null )
1271         {
1272             return null;
1273         }
1274         return getModel().getReporting().getPlugins();
1275 
1276     }
1277 
1278     public List getBuildPlugins()
1279     {
1280         if ( getModel().getBuild() == null )
1281         {
1282             return null;
1283         }
1284         return getModel().getBuild().getPlugins();
1285     }
1286 
1287     public List getModules()
1288     {
1289         return getModel().getModules();
1290     }
1291 
1292     public PluginManagement getPluginManagement()
1293     {
1294         PluginManagement pluginMgmt = null;
1295 
1296         Build build = getModel().getBuild();
1297         if ( build != null )
1298         {
1299             pluginMgmt = build.getPluginManagement();
1300         }
1301 
1302         return pluginMgmt;
1303     }
1304     
1305     private Build getModelBuild()
1306     {
1307         Build build = getModel().getBuild();
1308 
1309         if ( build == null )
1310         {
1311             build = new Build();
1312 
1313             getModel().setBuild( build );
1314         }
1315         
1316         return build;
1317     }
1318 
1319     public void addPlugin( Plugin plugin )
1320     {
1321         Build build = getModelBuild();
1322 
1323         if ( !build.getPluginsAsMap().containsKey( plugin.getKey() ) )
1324         {
1325             injectPluginManagementInfo( plugin );
1326 
1327             build.addPlugin( plugin );
1328             build.flushPluginMap();
1329         }
1330     }
1331     
1332     public void injectPluginManagementInfo( Plugin plugin )
1333     {
1334         PluginManagement pm = getModelBuild().getPluginManagement();
1335 
1336         if ( pm != null )
1337         {
1338             Map pmByKey = pm.getPluginsAsMap();
1339 
1340             String pluginKey = plugin.getKey();
1341 
1342             if ( pmByKey != null && pmByKey.containsKey( pluginKey ) )
1343             {
1344                 Plugin pmPlugin = (Plugin) pmByKey.get( pluginKey );
1345 
1346                 ModelUtils.mergePluginDefinitions( plugin, pmPlugin, false );
1347             }
1348         }
1349     }
1350 
1351     public List getCollectedProjects()
1352     {
1353         return collectedProjects;
1354     }
1355 
1356     public void setCollectedProjects( List collectedProjects )
1357     {
1358         this.collectedProjects = collectedProjects;
1359     }
1360 
1361     public void setPluginArtifactRepositories( List pluginArtifactRepositories )
1362     {
1363         this.pluginArtifactRepositories = pluginArtifactRepositories;
1364     }
1365 
1366     /**
1367      * @return a list of ArtifactRepository objects constructed
1368      *         from the Repository objects returned by getPluginRepositories.
1369      */
1370     public List getPluginArtifactRepositories()
1371     {
1372         return pluginArtifactRepositories;
1373     }
1374 
1375     public ArtifactRepository getDistributionManagementArtifactRepository()
1376     {
1377         return getArtifact().isSnapshot() && ( getSnapshotArtifactRepository() != null ) ? getSnapshotArtifactRepository()
1378             : getReleaseArtifactRepository();
1379     }
1380 
1381     public List getPluginRepositories()
1382     {
1383         return getModel().getPluginRepositories();
1384     }
1385 
1386     public void setActiveProfiles( List activeProfiles )
1387     {
1388         this.activeProfiles.addAll( activeProfiles );
1389     }
1390 
1391     public List getActiveProfiles()
1392     {
1393         return activeProfiles;
1394     }
1395 
1396     public void addAttachedArtifact( Artifact artifact )
1397     {
1398         getAttachedArtifacts().add( artifact );
1399     }
1400 
1401     public List getAttachedArtifacts()
1402     {
1403         if ( attachedArtifacts == null )
1404         {
1405             attachedArtifacts = new ArrayList();
1406         }
1407         return attachedArtifacts;
1408     }
1409 
1410     public Xpp3Dom getGoalConfiguration( String pluginGroupId, String pluginArtifactId, String executionId,
1411                                          String goalId )
1412     {
1413         Xpp3Dom dom = null;
1414 
1415         // ----------------------------------------------------------------------
1416         // I would like to be able to lookup the Mojo object using a key but
1417         // we have a limitation in modello that will be remedied shortly. So
1418         // for now I have to iterate through and see what we have.
1419         // ----------------------------------------------------------------------
1420 
1421         if ( getBuildPlugins() != null )
1422         {
1423             for ( Iterator iterator = getBuildPlugins().iterator(); iterator.hasNext(); )
1424             {
1425                 Plugin plugin = (Plugin) iterator.next();
1426 
1427                 if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
1428                 {
1429                     dom = (Xpp3Dom) plugin.getConfiguration();
1430 
1431                     if ( executionId != null )
1432                     {
1433                         PluginExecution execution = (PluginExecution) plugin.getExecutionsAsMap().get( executionId );
1434                         if ( execution != null )
1435                         {
1436                             Xpp3Dom executionConfiguration = (Xpp3Dom) execution.getConfiguration();
1437                             if ( executionConfiguration != null )
1438                             {
1439                                 Xpp3Dom newDom = new Xpp3Dom( executionConfiguration );
1440                                 dom = Xpp3Dom.mergeXpp3Dom( newDom, dom );
1441                             }
1442                         }
1443                     }
1444                     break;
1445                 }
1446             }
1447         }
1448         
1449 //        PluginManagement pluginManagement = getBuild().getPluginManagement();
1450 //        if ( pluginManagement != null && pluginManagement.getPlugins() != null )
1451 //        {
1452 //            for ( Iterator iterator = pluginManagement.getPlugins().iterator(); iterator.hasNext(); )
1453 //            {
1454 //                Plugin plugin = (Plugin) iterator.next();
1455 //
1456 //                if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
1457 //                {
1458 //                    Xpp3Dom managedDom = (Xpp3Dom) plugin.getConfiguration();
1459 //
1460 //                    if ( executionId != null )
1461 //                    {
1462 //                        PluginExecution execution = (PluginExecution) plugin.getExecutionsAsMap().get( executionId );
1463 //                        if ( execution != null )
1464 //                        {
1465 //                            Xpp3Dom executionConfiguration = (Xpp3Dom) execution.getConfiguration();
1466 //                            if ( executionConfiguration != null )
1467 //                            {
1468 //                                Xpp3Dom newDom = new Xpp3Dom( executionConfiguration );
1469 //                                managedDom = Xpp3Dom.mergeXpp3Dom( newDom, dom );
1470 //                            }
1471 //                        }
1472 //                    }
1473 //                    
1474 //                    dom = Xpp3Dom.mergeXpp3Dom( dom, managedDom );
1475 //                    break;
1476 //                }
1477 //            }
1478 //        }
1479 
1480         if ( dom != null )
1481         {
1482             // make a copy so the original in the POM doesn't get messed with
1483             dom = new Xpp3Dom( dom );
1484         }
1485 
1486         return dom;
1487     }
1488 
1489     public Xpp3Dom getReportConfiguration( String pluginGroupId, String pluginArtifactId, String reportSetId )
1490     {
1491         Xpp3Dom dom = null;
1492 
1493         // ----------------------------------------------------------------------
1494         // I would like to be able to lookup the Mojo object using a key but
1495         // we have a limitation in modello that will be remedied shortly. So
1496         // for now I have to iterate through and see what we have.
1497         // ----------------------------------------------------------------------
1498 
1499         if ( getReportPlugins() != null )
1500         {
1501             for ( Iterator iterator = getReportPlugins().iterator(); iterator.hasNext(); )
1502             {
1503                 ReportPlugin plugin = (ReportPlugin) iterator.next();
1504 
1505                 if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
1506                 {
1507                     dom = (Xpp3Dom) plugin.getConfiguration();
1508 
1509                     if ( reportSetId != null )
1510                     {
1511                         ReportSet reportSet = (ReportSet) plugin.getReportSetsAsMap().get( reportSetId );
1512                         if ( reportSet != null )
1513                         {
1514                             Xpp3Dom executionConfiguration = (Xpp3Dom) reportSet.getConfiguration();
1515                             if ( executionConfiguration != null )
1516                             {
1517                                 Xpp3Dom newDom = new Xpp3Dom( executionConfiguration );
1518                                 dom = Xpp3Dom.mergeXpp3Dom( newDom, dom );
1519                             }
1520                         }
1521                     }
1522                     break;
1523                 }
1524             }
1525         }
1526 
1527         if ( dom != null )
1528         {
1529             // make a copy so the original in the POM doesn't get messed with
1530             dom = new Xpp3Dom( dom );
1531         }
1532 
1533         return dom;
1534     }
1535 
1536     public MavenProject getExecutionProject()
1537     {
1538         return executionProject;
1539     }
1540 
1541     public void setExecutionProject( MavenProject executionProject )
1542     {
1543         this.executionProject = executionProject;
1544     }
1545 
1546     public void writeModel( Writer writer )
1547         throws IOException
1548     {
1549         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
1550 
1551         pomWriter.write( writer, getModel() );
1552     }
1553 
1554     public void writeOriginalModel( Writer writer )
1555         throws IOException
1556     {
1557         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
1558 
1559         pomWriter.write( writer, getOriginalModel() );
1560     }
1561 
1562     /**
1563      * Direct dependencies that this project has.
1564      * @return {@link Set} &lt; {@link Artifact} >
1565      * @see #getArtifacts() to get all transitive dependencies
1566      */
1567     public Set getDependencyArtifacts()
1568     {
1569         return dependencyArtifacts;
1570     }
1571 
1572     public void setDependencyArtifacts( Set dependencyArtifacts )
1573     {
1574         this.dependencyArtifacts = dependencyArtifacts;
1575     }
1576 
1577     public void setReleaseArtifactRepository( ArtifactRepository releaseArtifactRepository )
1578     {
1579         this.releaseArtifactRepository = releaseArtifactRepository;
1580     }
1581 
1582     public void setSnapshotArtifactRepository( ArtifactRepository snapshotArtifactRepository )
1583     {
1584         this.snapshotArtifactRepository = snapshotArtifactRepository;
1585     }
1586 
1587     public void setOriginalModel( Model originalModel )
1588     {
1589         this.originalModel = originalModel;
1590     }
1591 
1592     public Model getOriginalModel()
1593     {
1594         return originalModel;
1595     }
1596 
1597     public void setManagedVersionMap( Map map )
1598     {
1599         this.managedVersionMap = map;
1600     }
1601 
1602     public Map getManagedVersionMap()
1603     {
1604         return this.managedVersionMap;
1605     }
1606 
1607     public boolean equals( Object other )
1608     {
1609         if ( other == this )
1610         {
1611             return true;
1612         }
1613         else if ( !( other instanceof MavenProject ) )
1614         {
1615             return false;
1616         }
1617         else
1618         {
1619             MavenProject otherProject = (MavenProject) other;
1620 
1621             return getId().equals( otherProject.getId() );
1622         }
1623     }
1624 
1625     public int hashCode()
1626     {
1627         return getId().hashCode();
1628     }
1629 
1630     public List getBuildExtensions()
1631     {
1632         Build build = getBuild();
1633         if ( build == null || build.getExtensions() == null )
1634         {
1635             return Collections.EMPTY_LIST;
1636         }
1637         else
1638         {
1639             return build.getExtensions();
1640         }
1641     }
1642 
1643     /**
1644      * @todo the lazy initialisation of this makes me uneasy.
1645      * @return {@link Set} &lt; {@link Artifact} >
1646      */
1647     public Set createArtifacts( ArtifactFactory artifactFactory, String inheritedScope,
1648                                 ArtifactFilter dependencyFilter )
1649         throws InvalidDependencyVersionException
1650     {
1651         return MavenMetadataSource.createArtifacts( artifactFactory, getDependencies(), inheritedScope,
1652                                                     dependencyFilter, this );
1653     }
1654 
1655     public void addProjectReference( MavenProject project )
1656     {
1657         projectReferences.put( getProjectReferenceId( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project );
1658     }
1659 
1660     public static String getProjectReferenceId( String groupId, String artifactId, String version )
1661     {
1662         return groupId + ":" + artifactId + ":" + version;
1663     }
1664 
1665     /**
1666      * @deprecated Use MavenProjectHelper.attachArtifact(..) instead.
1667      */
1668     public void attachArtifact( String type, String classifier, File file )
1669     {
1670     }
1671 
1672     public Properties getProperties()
1673     {
1674         return getModel().getProperties();
1675     }
1676 
1677     public List getFilters()
1678     {
1679         return getBuild().getFilters();
1680     }
1681 
1682     public Map getProjectReferences()
1683     {
1684         return projectReferences;
1685     }
1686 
1687     public boolean isExecutionRoot()
1688     {
1689         return executionRoot;
1690     }
1691 
1692     public void setExecutionRoot( boolean executionRoot )
1693     {
1694         this.executionRoot = executionRoot;
1695     }
1696 
1697     public String getDefaultGoal()
1698     {
1699         return getBuild() != null ? getBuild().getDefaultGoal() : null;
1700     }
1701 
1702 
1703     protected void setModel( Model model )
1704     {
1705         this.model = model;
1706     }
1707 
1708     protected void setAttachedArtifacts( List attachedArtifacts )
1709     {
1710         this.attachedArtifacts = attachedArtifacts;
1711     }
1712 
1713     protected void setCompileSourceRoots( List compileSourceRoots )
1714     {
1715         this.compileSourceRoots = compileSourceRoots;
1716     }
1717 
1718     protected void setTestCompileSourceRoots( List testCompileSourceRoots )
1719     {
1720         this.testCompileSourceRoots = testCompileSourceRoots;
1721     }
1722 
1723     protected void setScriptSourceRoots( List scriptSourceRoots )
1724     {
1725         this.scriptSourceRoots = scriptSourceRoots;
1726     }
1727 
1728     protected ArtifactRepository getReleaseArtifactRepository()
1729     {
1730         return releaseArtifactRepository;
1731     }
1732 
1733     protected ArtifactRepository getSnapshotArtifactRepository()
1734     {
1735         return snapshotArtifactRepository;
1736     }
1737     
1738     public void resolveActiveArtifacts()
1739     {
1740         Set depArtifacts = getDependencyArtifacts();
1741         if ( depArtifacts == null )
1742         {
1743             return;
1744         }
1745         
1746         Set updated = new LinkedHashSet( depArtifacts.size() );
1747         int updatedCount = 0;
1748         
1749         for ( Iterator it = depArtifacts.iterator(); it.hasNext(); )
1750         {
1751             Artifact depArtifact = (Artifact) it.next();
1752             Artifact replaced = replaceWithActiveArtifact( depArtifact );
1753             
1754             if ( depArtifact != replaced )
1755             {
1756                 updatedCount++;
1757             }
1758             
1759             updated.add( replaced );
1760         }
1761         
1762         if ( updatedCount > 0 )
1763         {
1764             setDependencyArtifacts( updated );
1765         }
1766     }
1767 
1768     public Artifact replaceWithActiveArtifact( Artifact pluginArtifact )
1769     {
1770         if ( getProjectReferences() != null && !getProjectReferences().isEmpty() )
1771         {
1772             String refId = getProjectReferenceId( pluginArtifact.getGroupId(), pluginArtifact.getArtifactId(), pluginArtifact.getVersion() );
1773             MavenProject ref = (MavenProject) getProjectReferences().get( refId );
1774             if ( ref != null )
1775             {
1776                 if ( ref.getArtifact() != null
1777                     && ref.getArtifact().getDependencyConflictId().equals( pluginArtifact.getDependencyConflictId() ) )
1778                 {
1779                     // if the project artifact doesn't exist, don't use it. We haven't built that far.
1780                     if ( ref.getArtifact().getFile() != null && ref.getArtifact().getFile().exists() )
1781                     {
1782                         // FIXME: Why aren't we using project.getArtifact() for the second parameter here??
1783                         Artifact resultArtifact = new ActiveProjectArtifact( ref, pluginArtifact );
1784                         return resultArtifact;
1785                     }
1786                     else
1787                     {
1788                         logMissingSiblingProjectArtifact( pluginArtifact );
1789                     }
1790                 }
1791 
1792                 Artifact attached = findMatchingArtifact( ref.getAttachedArtifacts(), pluginArtifact );
1793                 if ( attached != null )
1794                 {
1795                     if ( attached.getFile() != null && attached.getFile().exists() )
1796                     {
1797                         Artifact resultArtifact = ArtifactUtils.copyArtifact( attached );
1798                         resultArtifact.setScope( pluginArtifact.getScope() );
1799                         return resultArtifact;
1800                     }
1801                     else
1802                     {
1803                         logMissingSiblingProjectArtifact( pluginArtifact );
1804                     }
1805                 }
1806             }
1807         }
1808         return pluginArtifact;
1809     }
1810 
1811     /**
1812      * Tries to resolve the specified artifact from the given collection of attached project artifacts.
1813      * 
1814      * @param artifacts The attached artifacts, may be <code>null</code>.
1815      * @param requestedArtifact The artifact to resolve, must not be <code>null</code>.
1816      * @return The matching artifact or <code>null</code> if not found.
1817      */
1818     private Artifact findMatchingArtifact( List artifacts, Artifact requestedArtifact )
1819     {
1820         if ( artifacts != null && !artifacts.isEmpty() )
1821         {
1822             // first try matching by dependency conflict id
1823             String requestedId = requestedArtifact.getDependencyConflictId();
1824             for ( Iterator it = artifacts.iterator(); it.hasNext(); )
1825             {
1826                 Artifact artifact = (Artifact) it.next();
1827                 if ( requestedId.equals( artifact.getDependencyConflictId() ) )
1828                 {
1829                     return artifact;
1830                 }
1831             }
1832 
1833             // next try matching by repository conflict id
1834             requestedId = getRepositoryConflictId( requestedArtifact );
1835             for ( Iterator it = artifacts.iterator(); it.hasNext(); )
1836             {
1837                 Artifact artifact = (Artifact) it.next();
1838                 if ( requestedId.equals( getRepositoryConflictId( artifact ) ) )
1839                 {
1840                     return artifact;
1841                 }
1842             }
1843         }
1844 
1845         return null;
1846     }
1847 
1848     /**
1849      * Gets the repository conflict id of the specified artifact. Unlike the dependency conflict id, the repository
1850      * conflict id uses the artifact file extension instead of the artifact type. Hence, the repository conflict id more
1851      * closely reflects the identity of artifacts as perceived by a repository.
1852      * 
1853      * @param artifact The artifact, must not be <code>null</code>.
1854      * @return The repository conflict id, never <code>null</code>.
1855      */
1856     private String getRepositoryConflictId( Artifact artifact )
1857     {
1858         StringBuffer buffer = new StringBuffer( 128 );
1859         buffer.append( artifact.getGroupId() );
1860         buffer.append( ':' ).append( artifact.getArtifactId() );
1861         if ( artifact.getArtifactHandler() != null )
1862         {
1863             buffer.append( ':' ).append( artifact.getArtifactHandler().getExtension() );
1864         }
1865         else
1866         {
1867             buffer.append( ':' ).append( artifact.getType() );
1868         }
1869         if ( artifact.hasClassifier() )
1870         {
1871             buffer.append( ':' ).append( artifact.getClassifier() );
1872         }
1873         return buffer.toString();
1874     }
1875 
1876     private void logMissingSiblingProjectArtifact( Artifact artifact )
1877     {
1878         if ( logger == null || !logger.isDebugEnabled() )
1879         {
1880             return;
1881         }
1882         
1883         if ( logger.isDebugEnabled() )
1884         {
1885             StringBuffer message = new StringBuffer();
1886             message.append( "WARNING: A dependency of the current project (or of one the plugins used in its build) was found in the reactor, " );
1887             message.append( "\nbut had not been built at the time it was requested. It will be resolved from the repository instead." );
1888             message.append( "\n\nCurrent Project: " ).append( getName() );
1889             message.append( "\nRequested Dependency: " ).append( artifact.getId() );
1890             message.append( "\n\nNOTE: You may need to run this build to the 'compile' lifecycle phase, or farther, in order to build the dependency artifact." );
1891             message.append( "\n" );
1892             
1893             logger.debug( message.toString() );
1894         }
1895         else
1896         {
1897             logger.warn( "Requested project artifact: " + artifact.getId() + " is not available at this time. Resolving externally." );
1898         }
1899     }
1900 
1901     private void addArtifactPath(Artifact a, List list) throws DependencyResolutionRequiredException
1902     {
1903         File file = a.getFile();
1904         if ( file == null )
1905         {
1906             throw new DependencyResolutionRequiredException( a );
1907         }
1908         list.add( file.getPath() );
1909     }
1910     
1911     /**
1912      * Default toString
1913      */
1914     public String toString()
1915     {
1916         StringBuffer sb = new StringBuffer(30);
1917         sb.append( "MavenProject: " );
1918         sb.append( this.getGroupId() );
1919         sb.append( ":" );
1920         sb.append( this.getArtifactId() );
1921         sb.append( ":" );
1922         sb.append( this.getVersion() );
1923         sb.append( " @ " );
1924         
1925         try 
1926         {
1927             sb.append( this.getFile().getPath() );
1928         }
1929         catch (NullPointerException e)
1930         {
1931             //don't log it.
1932         }
1933         
1934         return sb.toString();        
1935     }
1936     
1937     /**
1938      * @throws CloneNotSupportedException
1939      * @since 2.0.9
1940      */
1941     public Object clone()
1942         throws CloneNotSupportedException
1943     {
1944         MavenProject clone = (MavenProject) super.clone();
1945         clone.deepCopy( this );
1946         return clone;
1947     }
1948 
1949 // ----------------------------------------------------------------------------
1950 // CODE BELOW IS USED TO PRESERVE DYNAMISM IN THE BUILD SECTION OF THE POM.
1951 // ----------------------------------------------------------------------------
1952     
1953     private Build dynamicBuild;
1954 
1955     private Build originalInterpolatedBuild;
1956 
1957     private List dynamicCompileSourceRoots;
1958 
1959     private List originalInterpolatedCompileSourceRoots;
1960 
1961     private List dynamicTestCompileSourceRoots;
1962 
1963     private List originalInterpolatedTestCompileSourceRoots;
1964 
1965     private List dynamicScriptSourceRoots;
1966 
1967     private List originalInterpolatedScriptSourceRoots;
1968 
1969     private boolean isConcrete = false;
1970 
1971     public boolean isConcrete()
1972     {
1973         return isConcrete;
1974     }
1975 
1976     public void setConcrete( boolean concrete )
1977     {
1978         isConcrete = concrete;
1979     }
1980 
1981     public Build getDynamicBuild()
1982     {
1983         return dynamicBuild;
1984     }
1985 
1986     public Build getOriginalInterpolatedBuild()
1987     {
1988         return originalInterpolatedBuild;
1989     }
1990 
1991     public List getDynamicCompileSourceRoots()
1992     {
1993         return dynamicCompileSourceRoots;
1994     }
1995 
1996     public List getOriginalInterpolatedCompileSourceRoots()
1997     {
1998         return originalInterpolatedCompileSourceRoots;
1999     }
2000 
2001     public List getDynamicTestCompileSourceRoots()
2002     {
2003         return dynamicTestCompileSourceRoots;
2004     }
2005 
2006     public List getOriginalInterpolatedTestCompileSourceRoots()
2007     {
2008         return originalInterpolatedTestCompileSourceRoots;
2009     }
2010 
2011     public List getDynamicScriptSourceRoots()
2012     {
2013         return dynamicScriptSourceRoots;
2014     }
2015 
2016     public List getOriginalInterpolatedScriptSourceRoots()
2017     {
2018         return originalInterpolatedScriptSourceRoots;
2019     }
2020 
2021     public void clearRestorableRoots()
2022     {
2023         dynamicCompileSourceRoots = null;
2024         dynamicTestCompileSourceRoots = null;
2025         dynamicScriptSourceRoots = null;
2026         originalInterpolatedCompileSourceRoots = null;
2027         originalInterpolatedScriptSourceRoots = null;
2028         originalInterpolatedTestCompileSourceRoots = null;
2029     }
2030 
2031     public void clearRestorableBuild()
2032     {
2033         dynamicBuild = null;
2034         originalInterpolatedBuild = null;
2035     }
2036 
2037     public void preserveCompileSourceRoots( List originalInterpolatedCompileSourceRoots )
2038     {
2039         dynamicCompileSourceRoots = getCompileSourceRoots();
2040         this.originalInterpolatedCompileSourceRoots = originalInterpolatedCompileSourceRoots;
2041     }
2042 
2043     public void preserveTestCompileSourceRoots( List originalInterpolatedTestCompileSourceRoots )
2044     {
2045         dynamicTestCompileSourceRoots = getTestCompileSourceRoots();
2046         this.originalInterpolatedTestCompileSourceRoots = originalInterpolatedTestCompileSourceRoots;
2047     }
2048 
2049     public void preserveScriptSourceRoots( List originalInterpolatedScriptSourceRoots )
2050     {
2051         dynamicScriptSourceRoots = getScriptSourceRoots();
2052         this.originalInterpolatedScriptSourceRoots = originalInterpolatedScriptSourceRoots;
2053     }
2054 
2055     public void preserveBuild( Build originalInterpolatedBuild )
2056     {
2057         dynamicBuild = getBuild();
2058         this.originalInterpolatedBuild = originalInterpolatedBuild;
2059 
2060         this.originalInterpolatedBuild.setPluginManagement( null );
2061         this.originalInterpolatedBuild.setPlugins( null );
2062     }
2063 
2064     protected void setDynamicBuild( Build dynamicBuild )
2065     {
2066         this.dynamicBuild = dynamicBuild;
2067     }
2068 
2069     protected void setOriginalInterpolatedBuild( Build originalInterpolatedBuild )
2070     {
2071         this.originalInterpolatedBuild = originalInterpolatedBuild;
2072     }
2073 
2074     protected void setDynamicCompileSourceRoots( List dynamicCompileSourceRoots )
2075     {
2076         this.dynamicCompileSourceRoots = dynamicCompileSourceRoots;
2077     }
2078 
2079     protected void setOriginalInterpolatedCompileSourceRoots( List originalInterpolatedCompileSourceRoots )
2080     {
2081         this.originalInterpolatedCompileSourceRoots = originalInterpolatedCompileSourceRoots;
2082     }
2083 
2084     protected void setDynamicTestCompileSourceRoots( List dynamicTestCompileSourceRoots )
2085     {
2086         this.dynamicTestCompileSourceRoots = dynamicTestCompileSourceRoots;
2087     }
2088 
2089     protected void setOriginalInterpolatedTestCompileSourceRoots( List originalInterpolatedTestCompileSourceRoots )
2090     {
2091         this.originalInterpolatedTestCompileSourceRoots = originalInterpolatedTestCompileSourceRoots;
2092     }
2093 
2094     protected void setDynamicScriptSourceRoots( List dynamicScriptSourceRoots )
2095     {
2096         this.dynamicScriptSourceRoots = dynamicScriptSourceRoots;
2097     }
2098 
2099     protected void setOriginalInterpolatedScriptSourceRoots( List originalInterpolatedScriptSourceRoots )
2100     {
2101         this.originalInterpolatedScriptSourceRoots = originalInterpolatedScriptSourceRoots;
2102     }
2103     
2104     private Properties preservedProperties;
2105     
2106     public Properties getPreservedProperties()
2107     {
2108         return preservedProperties;
2109     }
2110 
2111     public void preserveProperties()
2112     {
2113         Properties p = getProperties();
2114         if ( p != null )
2115         {
2116             preservedProperties = new Properties();
2117             for( Enumeration e = p.propertyNames(); e.hasMoreElements(); )
2118             {
2119                 String key = (String) e.nextElement();
2120                 preservedProperties.setProperty( key, p.getProperty( key ) );
2121             }
2122         }
2123     }
2124     
2125     private File preservedBasedir;
2126     
2127     public File getPreservedBasedir()
2128     {
2129         return preservedBasedir;
2130     }
2131 
2132     public void preserveBasedir()
2133     {
2134         this.preservedBasedir = getBasedir();
2135     }
2136 
2137     public void setLogger( Logger logger )
2138     {
2139         this.logger = logger;
2140     }
2141 
2142     /**
2143      * Retrieve the {@link ProjectBuilderConfiguration} instance used to construct this MavenProject instance.
2144      */
2145     public ProjectBuilderConfiguration getProjectBuilderConfiguration()
2146     {
2147         return projectBuilderConfiguration;
2148     }
2149 
2150     /**
2151      * Set the {@link ProjectBuilderConfiguration} instance used to construct this MavenProject instance.
2152      * @param projectBuilderConfiguration
2153      */
2154     public void setProjectBuilderConfiguration( ProjectBuilderConfiguration projectBuilderConfiguration )
2155     {
2156         this.projectBuilderConfiguration = projectBuilderConfiguration;
2157     }
2158 
2159 }