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 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.maven.ArtifactListBuilder;
24 import org.apache.maven.DependencyClasspathBuilder;
25 import org.apache.maven.MavenConstants;
26 import org.apache.maven.MavenUtils;
27 import org.apache.maven.jelly.MavenJellyContext;
28 import org.apache.maven.plugin.PluginManager;
29 import org.apache.maven.plugin.UnknownPluginException;
30 import org.apache.maven.project.io.stax.MavenStaxReader;
31 import org.apache.maven.project.io.stax.MavenStaxWriter;
32 import org.apache.maven.verifier.ChecksumVerificationException;
33 import org.apache.maven.verifier.DependencyVerifier;
34 import org.apache.maven.verifier.RepoConfigException;
35 import org.apache.maven.verifier.UnsatisfiedDependencyException;
36
37 import java.io.ByteArrayOutputStream;
38 import java.io.File;
39 import java.io.IOException;
40 import java.io.OutputStreamWriter;
41 import java.io.Reader;
42 import java.net.URL;
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Properties;
49 import java.util.Set;
50 import java.util.TreeSet;
51
52 /**
53 * @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
54 * @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
55 * @author <a href="mailto:glennm@apache.org">Glenn McAllister</a>
56 * @version $Id: Project.java 517014 2007-03-11 21:15:50Z ltheussl $
57 * @todo Change the file reference for the source POM to an URL.
58 */
59 public class Project
60 {
61 /**
62 * LOGGER for debug and output
63 */
64 private static final Log LOGGER = LogFactory.getLog( Project.class );
65
66 /**
67 * Distributions map that associates the distribution ids
68 * with the distribution objects.
69 */
70 private HashMap versionMap;
71
72 /**
73 * Parent project.
74 */
75 private Project parent;
76
77 /**
78 * File that this POM object was derived from.
79 */
80 private File file;
81
82 /**
83 * Map of dependency ids to their real paths in the system.
84 */
85 private Map dependencyPaths = new HashMap();
86
87 /**
88 * Dependencies Map so that an individual dependency can
89 * be retrieved by id.
90 */
91 private Map dependencyMap = new HashMap();
92
93 /**
94 * Artifact list.
95 */
96 private List artifactList;
97
98 /**
99 * This project's Jelly context.
100 */
101 private MavenJellyContext context;
102
103 /**
104 * TODO: use commons-collections.
105 */
106 private List contextStack = new ArrayList();
107
108 /**
109 * the maven.xml file for this project
110 */
111 private File mavenXml;
112
113 private final Model model;
114
115 private String originalGroupId;
116
117 /**
118 * Default constructor.
119 */
120 public Project()
121 {
122 model = new Model();
123 }
124
125 /**
126 * Constructor with prebuilt model.
127 *
128 * @param in the input reader
129 * @throws Exception an error occured reading the file
130 * @todo should not have to throw Exception
131 */
132 public Project( Reader in )
133 throws Exception
134 {
135 MavenStaxReader reader = new MavenStaxReader();
136 model = reader.read( in );
137 resolveDependencies();
138 resolveVersions();
139 }
140
141 /**
142 * Constructor with prebuilt model.
143 *
144 * @param url the input url
145 * @throws Exception an error occured reading the file
146 * @todo should not have to throw Exception
147 */
148 public Project( URL url )
149 throws Exception
150 {
151 MavenStaxReader reader = new MavenStaxReader();
152 model = reader.read( url.getFile() );
153 resolveDependencies();
154 resolveVersions();
155 }
156
157 /**
158 * Constructor with prebuilt model.
159 *
160 * @param path the input path
161 * @throws Exception an error occured reading the file
162 * @todo should not have to throw Exception
163 */
164 public Project( String path )
165 throws Exception
166 {
167 MavenStaxReader reader = new MavenStaxReader();
168 model = reader.read( path );
169 resolveDependencies();
170 resolveVersions();
171 }
172
173 /**
174 * @return the maven.xml file
175 */
176 public File getMavenXml()
177 {
178
179 if ( ( mavenXml == null ) && ( getFile() != null ) )
180 {
181 mavenXml = new File( getFile().getParentFile(), MavenConstants.BUILD_FILE_NAME );
182 }
183 return mavenXml;
184 }
185
186 /**
187 * @return true if the maven.xml file for the project exists
188 */
189 public boolean hasMavenXml()
190 {
191 File mavenXml = getMavenXml();
192 if ( mavenXml != null )
193 {
194 return mavenXml.exists();
195 }
196 else
197 {
198 return false;
199 }
200 }
201
202
203
204
205
206
207 /**
208 * @return the id of the project
209 */
210 public String getId()
211 {
212
213 if ( ( model.getId() != null ) && ( model.getId().indexOf( ":" ) > 0 ) )
214 {
215 return model.getId();
216 }
217 return getGroupId() + ":" + getArtifactId();
218 }
219
220 public void setId( String id )
221 {
222 int i = id.indexOf( "+" );
223 int j = id.indexOf( ":" );
224
225 if ( i > 0 )
226 {
227 setGroupId( id.substring( 0, i ) );
228 setArtifactId( id.replace( '+', '-' ) );
229 }
230 else if ( j > 0 )
231 {
232 setGroupId( id.substring( 0, j ) );
233 setArtifactId( id.substring( j + 1 ) );
234 }
235 else
236 {
237 setGroupId( id );
238 setArtifactId( id );
239 }
240 }
241
242 /**
243 * Get the artifact id.
244 *
245 * @return The artifactId
246 */
247 public String getArtifactId()
248 {
249 return model.getArtifactId();
250 }
251
252 /**
253 * Get the plugin context using the plugin name.
254 *
255 * @param pluginId Plugin name.
256 * @return The plugin context create for the named plugin when it was loaded for
257 * this project.
258 * @throws UnknownPluginException if the plugin could not be found
259 * @todo [1.0] - when we are caching plugins, this should load on demand, also move to plugin manager
260 * @deprecated use the tag instead
261 */
262 public MavenJellyContext getPluginContext( String pluginId )
263 throws Exception
264 {
265 PluginManager pluginManager = context.getMavenSession().getPluginManager();
266 return pluginManager.getPluginContext( pluginId );
267 }
268
269 /**
270 * Set the context attribute.
271 *
272 * @param context the context to use
273 */
274 public void setContext( MavenJellyContext context )
275 {
276 if ( contextStack.size() > 0 )
277 {
278 LOGGER.warn( "replacing a context when the stack is not empty" );
279 }
280 this.context = context;
281 }
282
283 /**
284 * Push a new context onto the stack.
285 *
286 * @param context
287 */
288 public void pushContext( MavenJellyContext context )
289 {
290 LOGGER.debug( "pushing on " + context + " over " + this.context + " in " + getId() );
291 contextStack.add( this.context );
292 this.context = context;
293 }
294
295 public void popContext()
296 {
297 MavenJellyContext context = (MavenJellyContext) contextStack.get( contextStack.size() - 1 );
298 contextStack.remove( contextStack.size() - 1 );
299 LOGGER.debug( "popping off " + this.context + " for " + context + " in " + getId() );
300 this.context = context;
301 }
302
303 /**
304 * Get the context attribute.
305 *
306 * @return The
307 */
308 public MavenJellyContext getContext()
309 {
310 return context;
311 }
312
313 /**
314 * Set the artifactList attribute.
315 *
316 * @param artifactList list of artifacts for the project
317 */
318 public void setArtifacts( List artifactList )
319 {
320 this.artifactList = artifactList;
321 }
322
323 /**
324 * Get the atrifact attribute.
325 *
326 * @return The list of artifacts for the project
327 */
328 public List getArtifacts()
329 {
330 return artifactList;
331 }
332
333 /**
334 * Set the file that this POM was derived from.
335 *
336 * @param file POM file
337 */
338 public void setFile( File file )
339 {
340 this.file = file;
341 }
342
343 /**
344 * Get the file this POM was derived from
345 *
346 * @return POM file
347 */
348 public File getFile()
349 {
350 return file;
351 }
352
353 /**
354 * @return the project that this one extends, if any
355 */
356 public Project getParent()
357 {
358 return parent;
359 }
360
361 /**
362 * Determine whether this project has a parent.
363 *
364 * @return State of ancestry.
365 */
366 public boolean hasParent()
367 {
368 return getParent() != null;
369 }
370
371 /**
372 * Set the project that this one extends
373 *
374 * @param parent the parent project
375 */
376 public void setParent( Project parent )
377 {
378 this.parent = parent;
379 }
380
381 /**
382 * Get the parent's basedir.
383 *
384 * @return Parent's basedir.
385 */
386 public File parentBasedir()
387 {
388 return new File( getExtend() ).getParentFile();
389 }
390
391 /**
392 * Get parent maven.xml file.
393 *
394 * @return Parent's maven.xml file.
395 */
396 public File parentMavenXml()
397 {
398 return new File( parentBasedir(), MavenConstants.BUILD_FILE_NAME );
399 }
400
401 /**
402 * @return the directory name for this proejct's artifacts
403 */
404 public String getArtifactDirectory()
405 {
406 if ( getGroupId() != null )
407 {
408 return getGroupId();
409 }
410
411
412
413
414 return standardToLegacyId( getId() );
415 }
416
417 /**
418 * Add a unique dependency for this project.
419 *
420 * @param dependency Dependency for this project.
421 */
422 public void addDependency( Dependency dependency )
423 {
424 if ( !getDependencies().contains( dependency ) )
425 {
426 model.addDependency( dependency );
427 dependencyMap.put( dependency.getKey(), dependency );
428 }
429 }
430
431 /**
432 * @param srcList source list to add items from
433 * @param targetList target list to add unique items to
434 * @todo eventually, just use sets instead.
435 */
436 static void mergeLists( List srcList, List targetList )
437 {
438 if ( srcList != null )
439 {
440 for ( Iterator i = srcList.iterator(); i.hasNext(); )
441 {
442 Object o = i.next();
443 if ( !targetList.contains( o ) )
444 {
445 targetList.add( o );
446 }
447 }
448 }
449 }
450
451 /**
452 * @param dependencies parent dependencies
453 * @todo eventually, just use the map
454 */
455 private void addParentDependencies( List dependencies )
456 {
457 for ( Iterator i = dependencies.iterator(); i.hasNext(); )
458 {
459 addDependency( (Dependency) i.next() );
460 }
461 }
462
463 /**
464 * Get the list of dependent projects ids.
465 *
466 * @return the set of all dependencies' project ids
467 */
468 public Set getDependentProjectIds()
469 {
470 Set projectIds = new TreeSet();
471 List dependencies = getDependencies();
472 Dependency dependency;
473 for ( int i = 0; i < dependencies.size(); i++ )
474 {
475 dependency = (Dependency) dependencies.get( i );
476 projectIds.add( dependency.getId() );
477 }
478 return projectIds;
479 }
480
481 /**
482 * Set an individual dependency's classpath entry.
483 *
484 * @param depId Dependency id.
485 * @param path Classpath for the given dependency.
486 */
487 public void setDependencyPath( String depId, String path )
488 {
489 dependencyPaths.put( depId, path );
490 }
491
492 /**
493 * Get an individual dependencies classpath entry.
494 *
495 * @param depId Dependency id.
496 * @return Classpath for the given dependency.
497 */
498 public String getDependencyPath( String depId )
499 {
500 return (String) dependencyPaths.get( legacyToDependencyKey( depId ) );
501 }
502
503 /**
504 * Get an individual dependency by id.
505 *
506 * @param depId Dependency id.
507 * @return Dependency for the given id.
508 */
509 public Dependency getDependency( String depId )
510 {
511 return (Dependency) dependencyMap.get( legacyToDependencyKey( depId ) );
512 }
513
514 /**
515 * Get flag to indicate the presence of a source repository.
516 *
517 * @return <code>true</code> if the project is part of a repository,
518 * <code>false</code> otherwise
519 */
520 public boolean hasRepository()
521 {
522 return ( getRepository() != null );
523 }
524
525 /**
526 * Indicate whether the POM is of the latest version.
527 *
528 * @return <code>true</code> if the pom version is the same as the
529 * currently running version of maven specified by {@link MavenConstants},
530 * or <code>false</code> otherwise
531 */
532 public boolean isPomCurrent()
533 {
534 return Integer.parseInt( getPomVersion() ) == MavenConstants.POM_VERSION;
535 }
536
537 /**
538 * Return a distribution for this project.
539 *
540 * @param versionId the id of the version to return
541 * @return List of distributions.
542 */
543 public Version getVersionById( String versionId )
544 {
545 return (Version) versionMap.get( versionId );
546 }
547
548
549
550
551
552 /**
553 * Flag to indicate the project has been verified.
554 */
555 private boolean initialized = false;
556
557 /**
558 * Dependency Verifier
559 */
560 private DependencyVerifier dependencyVerifier;
561
562 /**
563 * Dependency classpath used for compilation.
564 */
565 private String dependencyClasspath;
566
567 /**
568 * Initialize the project. This consists of the following stages.
569 * <p/>
570 * 1) Build the Ant project that can be used within plugin.jelly scripts and
571 * other Jelly scripts.
572 * <p/>
573 * 2) Build the artifact list.
574 * <p/>
575 * 3) Build the dependency classpath.
576 * <p/>
577 * 4) Create the dependency verifier.
578 * <p/>
579 * 5) Initialize the driver for this project.
580 *
581 * @throws IOException If an error occurs during project initialization.
582 */
583 public void initialize()
584 throws IOException
585 {
586 if ( initialized )
587 {
588 return;
589 }
590
591 buildArtifactList();
592 dependencyClasspath = DependencyClasspathBuilder.build( this );
593 setDependencyVerifier( new DependencyVerifier( this ) );
594 if ( getBuild() != null )
595 {
596 resolveDirectories( getBuild(), file.getParentFile() );
597 }
598 initialized = true;
599 }
600
601 /**
602 * Verify the dependencies for this project.
603 *
604 * @throws RepoConfigException If an error occurs checking the local settings.
605 * @throws UnsatisfiedDependencyException If an error occurs due to missing exceptions.
606 * @throws ChecksumVerificationException if the downloaded files fail verification
607 */
608 public void verifyDependencies()
609 throws RepoConfigException, UnsatisfiedDependencyException, ChecksumVerificationException
610 {
611 LOGGER.debug( "Verifying dependencies for " + getId() );
612
613
614 if ( ( getFile() != null ) && getFile().exists() && initialized )
615 {
616 getDependencyVerifier().verify();
617 }
618 }
619
620 /**
621 * Set the dependency verifier.
622 *
623 * @param dependencyVerifier Dependency Verifier.
624 */
625 public void setDependencyVerifier( DependencyVerifier dependencyVerifier )
626 {
627 this.dependencyVerifier = dependencyVerifier;
628 }
629
630 /**
631 * Get the dependency verifier for this project. We can probably share a
632 * dependency verifier.
633 *
634 * @return The DependencyVerifier for this project.
635 */
636 public DependencyVerifier getDependencyVerifier()
637 {
638 return dependencyVerifier;
639 }
640
641 /**
642 * Get the dependency classpath.
643 *
644 * @return The dependency classpath.
645 */
646 public String getDependencyClasspath()
647 {
648 return dependencyClasspath;
649 }
650
651 /**
652 * Build the artifact list.
653 */
654 public void buildArtifactList()
655 {
656 artifactList = ArtifactListBuilder.build( this );
657 }
658
659
660
661
662
663 /**
664 * This is to support methods that are using the legacy form of
665 * the project id. Currently the id is <groupId>:<artifactId> but the
666 * following methods assume <groupId>:
667 * <p/>
668 * Project::getDependencyPath( <groupId> )
669 * Project::getDependency( <groupId> )
670 * <p/>
671 * We don't want users to have to alter any usage until we have properly
672 * deprecated the use of the <groupId> form.
673 *
674 * @param id the legacy id to convert
675 * @return the id in standard format
676 */
677 public static String legacyToStandardId( String id )
678 {
679 String newId = id;
680 if ( id.indexOf( "+" ) != -1 )
681 {
682
683
684 int plusPos = id.indexOf( "+" );
685 String groupId = id.substring( 0, plusPos );
686 String partialArtifactId = id.substring( plusPos + 1 );
687 newId = groupId + ":" + groupId + "-" + partialArtifactId;
688 }
689 else if ( id.indexOf( ":" ) == -1 )
690 {
691
692 newId += ":" + id;
693 }
694 return newId;
695 }
696
697 public String legacyToDependencyKey( String id )
698 {
699 String newId = legacyToStandardId( id );
700 int sepIndex = newId.indexOf( ':' );
701
702
703 sepIndex = newId.indexOf( ':', sepIndex + 1 );
704 if ( sepIndex < 0 )
705 {
706 for ( Iterator i = dependencyMap.keySet().iterator(); i.hasNext(); )
707 {
708 String depId = (String) i.next();
709 if ( depId.equals( newId ) )
710 {
711 return depId;
712 }
713 if ( depId.startsWith( newId + ":" ) )
714 {
715 return depId;
716 }
717 }
718 newId += ":jar";
719 }
720 return newId;
721 }
722
723 /**
724 * This method is to support methods are expecting legacy ids. The following
725 * methods expect legacy ids.
726 * <p/>
727 * MavenJellyContext::getMavenJarOverride( <groupId> )
728 * Project::getArtifactDirectory( <groupId> )
729 * <p/>
730 * We don't want users to have to alter any usage until we have properly
731 * deprecated the use of the <groupId> form.
732 *
733 * @param id the standard id to convert
734 * @return the id in legacy format
735 */
736 public static String standardToLegacyId( String id )
737 {
738 int i = id.indexOf( ":" );
739
740 if ( i > 0 )
741 {
742 id = id.substring( i + 1 );
743 }
744
745 return id;
746 }
747
748 /**
749 * Setup inheritance from a parent project.
750 *
751 * @param parent the parent project
752 */
753 public void mergeParent( Project parent )
754 {
755 setParent( parent );
756
757 if ( parent == null )
758 {
759 return;
760 }
761
762 if ( getRepository() == null )
763 {
764 setRepository( parent.getRepository() );
765 }
766
767 if ( getName() == null )
768 {
769 setName( parent.getName() );
770 }
771
772 if ( getUrl() == null )
773 {
774 setUrl( parent.getUrl() );
775 }
776
777 if ( getLogo() == null )
778 {
779 setLogo( parent.getLogo() );
780 }
781
782 if ( getDescription() == null )
783 {
784 setDescription( parent.getDescription() );
785 }
786
787 if ( getIssueTrackingUrl() == null )
788 {
789 setIssueTrackingUrl( parent.getIssueTrackingUrl() );
790 }
791
792 if ( getCurrentVersion() == null )
793 {
794 setCurrentVersion( parent.getCurrentVersion() );
795 }
796
797 if ( getOrganization() == null )
798 {
799 setOrganization( parent.getOrganization() );
800 }
801
802 if ( getInceptionYear() == null )
803 {
804 setInceptionYear( parent.getInceptionYear() );
805 }
806
807 if ( getPackage() == null )
808 {
809 setPackage( parent.getPackage() );
810 }
811
812 if ( getSiteAddress() == null )
813 {
814 setSiteAddress( parent.getSiteAddress() );
815 }
816
817 if ( getSiteDirectory() == null )
818 {
819 setSiteDirectory( parent.getSiteDirectory() );
820 }
821
822 if ( getDistributionSite() == null )
823 {
824 setDistributionSite( parent.getDistributionSite() );
825 }
826
827 if ( getDistributionDirectory() == null )
828 {
829 setDistributionDirectory( parent.getDistributionDirectory() );
830 }
831
832 if ( getPomVersion() == null )
833 {
834 setPomVersion( parent.getPomVersion() );
835 }
836
837 if ( getGumpRepositoryId() == null )
838 {
839 setGumpRepositoryId( parent.getGumpRepositoryId() );
840 }
841
842 if ( getShortDescription() == null )
843 {
844 setShortDescription( parent.getShortDescription() );
845 }
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863 if ( model.getGroupId() == null )
864 {
865 if ( parent.originalGroupId != null )
866 {
867 model.setGroupId( parent.model.getGroupId() );
868 }
869 }
870
871 if ( getBuild() == null )
872 {
873
874 setBuild( new Build() );
875 mergeParent( parent.getBuild(), getBuild() );
876 }
877 else
878 {
879 mergeParent( parent.getBuild(), getBuild() );
880 }
881
882
883 if ( ( getMailingLists() == null ) || getMailingLists().isEmpty() )
884 {
885 setMailingLists( parent.getMailingLists() );
886 }
887 if ( ( getContributors() == null ) || getContributors().isEmpty() )
888 {
889 setContributors( parent.getContributors() );
890 }
891 if ( ( getDevelopers() == null ) || getDevelopers().isEmpty() )
892 {
893 setDevelopers( parent.getDevelopers() );
894 }
895 if ( ( getVersions() == null ) || getVersions().isEmpty() )
896 {
897 model.setVersions( parent.getVersions() );
898 resolveVersions();
899 }
900 if ( ( getLicenses() == null ) || getLicenses().isEmpty() )
901 {
902 setLicenses( parent.getLicenses() );
903 }
904 if ( ( getBranches() == null ) || getBranches().isEmpty() )
905 {
906 setBranches( parent.getBranches() );
907 }
908 if ( ( getReports() == null ) || getReports().isEmpty() )
909 {
910 setReports( parent.getReports() );
911 }
912 if ( ( getPackageGroups() == null ) || getPackageGroups().isEmpty() )
913 {
914 setPackageGroups( parent.getPackageGroups() );
915 }
916
917
918
919
920
921
922
923
924
925
926
927
928 addParentDependencies( parent.getDependencies() );
929 }
930
931 /**
932 * Resolve relative directories against a base directory.
933 *
934 * @param build
935 * @param basedir the base directory
936 * @throws java.io.IOException file resolution error
937 */
938 private static void resolveDirectories( Build build, File basedir )
939 throws IOException
940 {
941 for ( Iterator i = build.getResources().iterator(); i.hasNext(); )
942 {
943 Resource r = (Resource) i.next();
944 resolveDirectory( r, basedir );
945 }
946
947 if ( build.getUnitTest() != null )
948 {
949 for ( Iterator i = build.getUnitTest().getResources().iterator(); i.hasNext(); )
950 {
951 Resource r = (Resource) i.next();
952 resolveDirectory( r, basedir );
953 }
954 }
955
956 if ( ( build.getSourceDirectory() != null ) && ( build.getSourceDirectory().length() > 0 ) )
957 {
958 build.setSourceDirectory( MavenUtils.makeAbsolutePath( basedir, build.getSourceDirectory() ) );
959 }
960
961 if ( ( build.getAspectSourceDirectory() != null ) && ( build.getAspectSourceDirectory().length() > 0 ) )
962 {
963 build.setAspectSourceDirectory( MavenUtils.makeAbsolutePath( basedir, build.getAspectSourceDirectory() ) );
964 }
965
966 if ( ( build.getUnitTestSourceDirectory() != null ) && ( build.getUnitTestSourceDirectory().length() > 0 ) )
967 {
968 build
969 .setUnitTestSourceDirectory( MavenUtils.makeAbsolutePath( basedir, build.getUnitTestSourceDirectory() ) );
970 }
971
972 if ( ( build.getIntegrationUnitTestSourceDirectory() != null )
973 && ( build.getIntegrationUnitTestSourceDirectory().length() > 0 ) )
974 {
975 build.setIntegrationUnitTestSourceDirectory( MavenUtils.makeAbsolutePath( basedir, build
976 .getIntegrationUnitTestSourceDirectory() ) );
977 }
978 }
979
980 /**
981 * Setup inheritance from a parent project build element.
982 *
983 * @param parent the parent build element
984 * @param child
985 */
986 private static void mergeParent( Build parent, Build child )
987 {
988 if ( parent == null )
989 {
990 return;
991 }
992
993 if ( child.getDefaultGoal() == null )
994 {
995 child.setDefaultGoal( parent.getDefaultGoal() );
996 }
997
998 if ( child.getSourceDirectory() == null )
999 {
1000 child.setSourceDirectory( parent.getSourceDirectory() );
1001 }
1002
1003 if ( child.getUnitTestSourceDirectory() == null )
1004 {
1005 child.setUnitTestSourceDirectory( parent.getUnitTestSourceDirectory() );
1006 }
1007
1008 if ( child.getIntegrationUnitTestSourceDirectory() == null )
1009 {
1010 child.setIntegrationUnitTestSourceDirectory( parent.getIntegrationUnitTestSourceDirectory() );
1011 }
1012
1013 if ( child.getAspectSourceDirectory() == null )
1014 {
1015 child.setAspectSourceDirectory( parent.getAspectSourceDirectory() );
1016 }
1017
1018 if ( child.getNagEmailAddress() == null )
1019 {
1020 child.setNagEmailAddress( parent.getNagEmailAddress() );
1021 }
1022
1023 if ( ( child.getResources() == null ) || child.getResources().isEmpty() )
1024 {
1025 child.setResources( parent.getResources() );
1026 }
1027 if ( ( child.getSourceModifications() == null ) || child.getSourceModifications().isEmpty() )
1028 {
1029 child.setSourceModifications( parent.getSourceModifications() );
1030 }
1031
1032 if ( child.getUnitTest() == null )
1033 {
1034 child.setUnitTest( parent.getUnitTest() );
1035 }
1036 else
1037 {
1038 mergeUnitTestParent( parent.getUnitTest(), child.getUnitTest() );
1039 }
1040 }
1041
1042 private static void mergeUnitTestParent( UnitTest parent, UnitTest child )
1043 {
1044 if ( parent == null )
1045 {
1046 return;
1047 }
1048
1049
1050 if ( ( child.getResources() == null ) || child.getResources().isEmpty() )
1051 {
1052 child.setResources( parent.getResources() );
1053 }
1054 if ( ( child.getIncludes() == null ) || child.getIncludes().isEmpty() )
1055 {
1056 child.setIncludes( parent.getIncludes() );
1057 }
1058 if ( ( child.getExcludes() == null ) || child.getExcludes().isEmpty() )
1059 {
1060 child.setExcludes( parent.getExcludes() );
1061 }
1062 }
1063
1064 private static void resolveDirectory( Resource resource, File basedir )
1065 throws IOException
1066 {
1067 if ( resource.getDirectory() != null )
1068 {
1069 resource.setDirectory( MavenUtils.makeAbsolutePath( basedir, resource.getDirectory() ) );
1070 }
1071 else
1072 {
1073 resource.setDirectory( basedir.getCanonicalPath() );
1074 }
1075 }
1076
1077 public void addBranch( Branch branch )
1078 {
1079 model.addBranch( branch );
1080 }
1081
1082 public void addContributor( Contributor contributor )
1083 {
1084 model.addContributor( contributor );
1085 }
1086
1087 public void addDeveloper( Developer developer )
1088 {
1089 model.addDeveloper( developer );
1090 }
1091
1092 public void addLicense( License license )
1093 {
1094 model.addLicense( license );
1095 }
1096
1097 public void addMailingList( MailingList mailingList )
1098 {
1099 model.addMailingList( mailingList );
1100 }
1101
1102 public void addPackageGroup( PackageGroup packageGroup )
1103 {
1104 model.addPackageGroup( packageGroup );
1105 }
1106
1107 public void addProperty( String s, String s1 )
1108 {
1109 model.addProperty( s, s1 );
1110 }
1111
1112 public void addReport( String s )
1113 {
1114 model.addReport( s );
1115 }
1116
1117 public List getBranches()
1118 {
1119 return model.getBranches();
1120 }
1121
1122 public Build getBuild()
1123 {
1124 return model.getBuild();
1125 }
1126
1127 public List getContributors()
1128 {
1129 return model.getContributors();
1130 }
1131
1132 public String getCurrentVersion()
1133 {
1134 return model.getCurrentVersion();
1135 }
1136
1137 public List getDependencies()
1138 {
1139 return model.getDependencies();
1140 }
1141
1142 public String getDescription()
1143 {
1144 return model.getDescription();
1145 }
1146
1147 public List getDevelopers()
1148 {
1149 return model.getDevelopers();
1150 }
1151
1152 public String getDistributionDirectory()
1153 {
1154 return model.getDistributionDirectory();
1155 }
1156
1157 public String getDistributionSite()
1158 {
1159 return model.getDistributionSite();
1160 }
1161
1162 public String getExtend()
1163 {
1164 return model.getExtend();
1165 }
1166
1167 public String getGroupId()
1168 {
1169 return model.getGroupId();
1170 }
1171
1172 public String getGumpRepositoryId()
1173 {
1174 return model.getGumpRepositoryId();
1175 }
1176
1177 public String getInceptionYear()
1178 {
1179 return model.getInceptionYear();
1180 }
1181
1182 public String getIssueTrackingUrl()
1183 {
1184 return model.getIssueTrackingUrl();
1185 }
1186
1187 public List getLicenses()
1188 {
1189 return model.getLicenses();
1190 }
1191
1192 public String getLogo()
1193 {
1194 return model.getLogo();
1195 }
1196
1197 public List getMailingLists()
1198 {
1199 return model.getMailingLists();
1200 }
1201
1202 public String getName()
1203 {
1204 return model.getName();
1205 }
1206
1207 public Organization getOrganization()
1208 {
1209 return model.getOrganization();
1210 }
1211
1212 public String getPackage()
1213 {
1214 return model.getPackage();
1215 }
1216
1217 public List getPackageGroups()
1218 {
1219 return model.getPackageGroups();
1220 }
1221
1222 public String getPomVersion()
1223 {
1224 return model.getPomVersion();
1225 }
1226
1227 public Properties getProperties()
1228 {
1229 return model.getProperties();
1230 }
1231
1232 public List getReports()
1233 {
1234 return model.getReports();
1235 }
1236
1237 public Repository getRepository()
1238 {
1239 return model.getRepository();
1240 }
1241
1242 public String getShortDescription()
1243 {
1244 return model.getShortDescription();
1245 }
1246
1247 public String getSiteAddress()
1248 {
1249 return model.getSiteAddress();
1250 }
1251
1252 public String getSiteDirectory()
1253 {
1254 return model.getSiteDirectory();
1255 }
1256
1257 public String getUrl()
1258 {
1259 return model.getUrl();
1260 }
1261
1262 public List getVersions()
1263 {
1264 return model.getVersions();
1265 }
1266
1267 public void setVersions( List list )
1268 {
1269 model.setVersions( list );
1270 resolveVersions();
1271 }
1272
1273 public void setArtifactId( String s )
1274 {
1275 model.setArtifactId( s );
1276 }
1277
1278 public void setBranches( List list )
1279 {
1280 model.setBranches( list );
1281 }
1282
1283 public void setBuild( Build build )
1284 {
1285 model.setBuild( build );
1286 }
1287
1288 public void setContributors( List list )
1289 {
1290 model.setContributors( list );
1291 }
1292
1293 public void setCurrentVersion( String s )
1294 {
1295 model.setCurrentVersion( s );
1296 }
1297
1298 public void setDependencies( List list )
1299 {
1300 model.setDependencies( list );
1301 dependencyMap.clear();
1302 resolveDependencies();
1303 }
1304
1305 public void setDescription( String s )
1306 {
1307 model.setDescription( s );
1308 }
1309
1310 public void setDevelopers( List list )
1311 {
1312 model.setDevelopers( list );
1313 }
1314
1315 public void setDistributionDirectory( String s )
1316 {
1317 model.setDistributionDirectory( s );
1318 }
1319
1320 public void setDistributionSite( String s )
1321 {
1322 model.setDistributionSite( s );
1323 }
1324
1325 public void setExtend( String s )
1326 {
1327 model.setExtend( s );
1328 }
1329
1330 public void setGroupId( String s )
1331 {
1332 model.setGroupId( s );
1333 }
1334
1335 public void setGumpRepositoryId( String s )
1336 {
1337 model.setGumpRepositoryId( s );
1338 }
1339
1340 public void setInceptionYear( String s )
1341 {
1342 model.setInceptionYear( s );
1343 }
1344
1345 public void setIssueTrackingUrl( String s )
1346 {
1347 model.setIssueTrackingUrl( s );
1348 }
1349
1350 public void setLicenses( List list )
1351 {
1352 model.setLicenses( list );
1353 }
1354
1355 public void setLogo( String s )
1356 {
1357 model.setLogo( s );
1358 }
1359
1360 public void setMailingLists( List list )
1361 {
1362 model.setMailingLists( list );
1363 }
1364
1365 public void setName( String s )
1366 {
1367 model.setName( s );
1368 }
1369
1370 public void setOrganization( Organization organization )
1371 {
1372 model.setOrganization( organization );
1373 }
1374
1375 public void setPackage( String s )
1376 {
1377 model.setPackage( s );
1378 }
1379
1380 public void setPackageGroups( List list )
1381 {
1382 model.setPackageGroups( list );
1383 }
1384
1385 public void setPomVersion( String s )
1386 {
1387 model.setPomVersion( s );
1388 }
1389
1390 public void setProperties( Properties properties )
1391 {
1392 model.setProperties( properties );
1393 }
1394
1395 public void setReports( List list )
1396 {
1397 model.setReports( list );
1398 }
1399
1400 public void setRepository( Repository repository )
1401 {
1402 model.setRepository( repository );
1403 }
1404
1405 public void setShortDescription( String s )
1406 {
1407 model.setShortDescription( s );
1408 }
1409
1410 public void setSiteAddress( String s )
1411 {
1412 model.setSiteAddress( s );
1413 }
1414
1415 public void setSiteDirectory( String s )
1416 {
1417 model.setSiteDirectory( s );
1418 }
1419
1420 public void setUrl( String s )
1421 {
1422 model.setUrl( s );
1423 }
1424
1425 /**
1426 * Add a distribution to this project.
1427 *
1428 * @param version Distribution for this project.
1429 */
1430 public void addVersion( Version version )
1431 {
1432 if ( versionMap != null )
1433 {
1434
1435 versionMap.put( version.getId(), version );
1436 }
1437 model.addVersion( version );
1438 }
1439
1440 /**
1441 * @todo hopefully can be replaced by appropraite getters in modello
1442 */
1443 public void resolveIds()
1444 {
1445 originalGroupId = model.getGroupId();
1446 if ( model.getId() != null )
1447 {
1448 if ( ( model.getGroupId() == null ) && ( model.getArtifactId() == null ) )
1449 {
1450 setId( model.getId() );
1451 }
1452 else
1453 {
1454 String id = model.getId();
1455 if ( model.getGroupId() == null )
1456 {
1457 int j = id.indexOf( ":" );
1458 if ( j > 0 )
1459 {
1460 setGroupId( id.substring( 0, j ) );
1461 }
1462 else
1463 {
1464 setGroupId( id );
1465 }
1466 }
1467 if ( model.getArtifactId() == null )
1468 {
1469 int j = id.indexOf( ":" );
1470 if ( j > 0 )
1471 {
1472 setArtifactId( id.substring( j + 1 ) );
1473 }
1474 else
1475 {
1476 setArtifactId( id );
1477 }
1478 }
1479 }
1480 }
1481 else if ( model.getGroupId() == null )
1482 {
1483 model.setGroupId( model.getArtifactId() );
1484 LOGGER.debug( "No groupId found, setting to: " + model.getArtifactId() );
1485 }
1486 }
1487
1488 private void resolveVersions()
1489 {
1490 versionMap = new HashMap();
1491 for ( Iterator i = getVersions().iterator(); i.hasNext(); )
1492 {
1493 Version version = (Version) i.next();
1494 versionMap.put( version.getId(), version );
1495 }
1496 }
1497
1498 /**
1499 * @todo hopefully can be replaced by appropraite getters in modello
1500 */
1501 private void resolveDependencies()
1502 {
1503 for ( Iterator i = getDependencies().iterator(); i.hasNext(); )
1504 {
1505 Dependency dependency = (Dependency) i.next();
1506 if ( dependency.getId() != null )
1507 {
1508 if ( dependency.getGroupId() == null )
1509 {
1510 String id = dependency.getId();
1511 int k = id.indexOf( "+" );
1512 int j = id.indexOf( ":" );
1513
1514 if ( k > 0 )
1515 {
1516 dependency.setGroupId( id.substring( 0, k ) );
1517 dependency.setArtifactId( id.replace( '+', '-' ) );
1518 }
1519 else if ( j > 0 )
1520 {
1521 dependency.setGroupId( id.substring( 0, j ) );
1522 dependency.setArtifactId( id.substring( j + 1 ) );
1523 }
1524 else
1525 {
1526 dependency.setGroupId( id );
1527 }
1528 }
1529 if ( dependency.getArtifactId() == null )
1530 {
1531 dependency.setArtifactId( dependency.getId() );
1532 }
1533 }
1534 else if ( dependency.getGroupId() == null )
1535 {
1536 dependency.setGroupId( dependency.getArtifactId() );
1537 LOGGER.debug( "Dependency has no groupId, setting to: " + dependency.getArtifactId() );
1538 }
1539 dependency.setId( dependency.getGroupId() + ":" + dependency.getArtifactId() );
1540 dependencyMap.put( dependency.getKey(), dependency );
1541 }
1542 }
1543
1544 /**
1545 * Create an XML string from the project.
1546 *
1547 * @return XML representation of the project
1548 * @throws Exception FIXME
1549 */
1550 public String getProjectAsString()
1551 throws Exception
1552 {
1553 ByteArrayOutputStream projectStream = new ByteArrayOutputStream();
1554 if ( model.getModelEncoding() == null )
1555 model.setModelEncoding( "UTF-8" );
1556 OutputStreamWriter w = new OutputStreamWriter( projectStream, model.getModelEncoding() );
1557 try
1558 {
1559 MavenStaxWriter writer = new MavenStaxWriter();
1560 writer.write( w, model );
1561 }
1562 finally
1563 {
1564 w.close();
1565 }
1566 return projectStream.toString( System.getProperty( "file.encoding" ) );
1567 }
1568
1569 public String toString()
1570 {
1571 return getName() == null ? super.toString() : getName();
1572 }
1573
1574 public boolean equals( Object o )
1575 {
1576 if ( o.equals( this ) )
1577 {
1578 return true;
1579 }
1580
1581 if ( !( o instanceof Project ) )
1582 {
1583 return false;
1584 }
1585
1586 Project project = (Project) o;
1587 return getId().equals( project.getId() );
1588 }
1589
1590 public int hashCode()
1591 {
1592 return getId().hashCode();
1593 }
1594 }