1 package org.apache.maven.plugin.doap;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.Writer;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.text.DateFormat;
28 import java.text.ParseException;
29 import java.text.SimpleDateFormat;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.Comparator;
34 import java.util.Date;
35 import java.util.List;
36 import java.util.Locale;
37 import java.util.Map;
38 import java.util.Map.Entry;
39 import java.util.Set;
40 import java.util.TimeZone;
41
42 import org.apache.maven.artifact.Artifact;
43 import org.apache.maven.artifact.factory.ArtifactFactory;
44 import org.apache.maven.artifact.repository.ArtifactRepository;
45 import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
46 import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
47 import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
48 import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
49 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
50 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
51 import org.apache.maven.artifact.resolver.ArtifactResolver;
52 import org.apache.maven.model.Contributor;
53 import org.apache.maven.model.Developer;
54 import org.apache.maven.model.License;
55 import org.apache.maven.plugin.AbstractMojo;
56 import org.apache.maven.plugin.MojoExecutionException;
57 import org.apache.maven.plugin.doap.options.ASFExtOptions;
58 import org.apache.maven.plugin.doap.options.ASFExtOptionsUtil;
59 import org.apache.maven.plugin.doap.options.DoapArtifact;
60 import org.apache.maven.plugin.doap.options.DoapOptions;
61 import org.apache.maven.plugin.doap.options.ExtOptions;
62 import org.apache.maven.plugin.doap.options.Standard;
63 import org.apache.maven.project.MavenProject;
64 import org.apache.maven.project.MavenProjectBuilder;
65 import org.apache.maven.project.ProjectBuildingException;
66 import org.apache.maven.scm.manager.NoSuchScmProviderException;
67 import org.apache.maven.scm.manager.ScmManager;
68 import org.apache.maven.scm.provider.cvslib.repository.CvsScmProviderRepository;
69 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
70 import org.apache.maven.scm.repository.ScmRepository;
71 import org.apache.maven.scm.repository.ScmRepositoryException;
72 import org.apache.maven.settings.Settings;
73 import org.codehaus.plexus.i18n.I18N;
74 import org.codehaus.plexus.util.FileUtils;
75 import org.codehaus.plexus.util.StringUtils;
76 import org.codehaus.plexus.util.WriterFactory;
77 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
78 import org.codehaus.plexus.util.xml.XMLWriter;
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public class DoapMojo
93 extends AbstractMojo
94 {
95
96 private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
97
98
99 private static final DateFormat REPOSITORY_DATE_FORMAT;
100
101
102 private static final DateFormat DOAP_DATE_FORMAT;
103
104 static
105 {
106 REPOSITORY_DATE_FORMAT = new SimpleDateFormat( "yyyyMMddHHmmss", Locale.ENGLISH );
107 REPOSITORY_DATE_FORMAT.setTimeZone( UTC_TIME_ZONE );
108
109 DOAP_DATE_FORMAT = new SimpleDateFormat( "yyyy-MM-dd", Locale.ENGLISH );
110 DOAP_DATE_FORMAT.setTimeZone( UTC_TIME_ZONE );
111 }
112
113
114
115
116
117
118
119
120
121
122
123 private ScmManager scmManager;
124
125
126
127
128
129
130
131 private ArtifactFactory artifactFactory;
132
133
134
135
136
137
138
139 private RepositoryMetadataManager repositoryMetadataManager;
140
141
142
143
144
145
146
147 private I18N i18n;
148
149
150
151
152
153
154
155
156
157
158
159
160 private MavenProject project;
161
162
163
164
165
166
167
168 private String doapFile;
169
170
171
172
173
174
175
176
177 private String outputDirectory;
178
179
180
181
182
183
184
185
186
187 private ArtifactRepository localRepository;
188
189
190
191
192
193
194
195
196
197 private List<ArtifactRepository> remoteRepositories;
198
199
200
201
202
203
204
205 private ArtifactFactory factory;
206
207
208
209
210
211
212
213 private MavenProjectBuilder mavenProjectBuilder;
214
215
216
217
218
219
220
221 private ArtifactResolver resolver;
222
223
224
225
226
227
228
229
230
231 protected Settings settings;
232
233
234
235
236
237
238
239
240
241
242
243
244 private String category;
245
246
247
248
249
250
251
252
253 private String language;
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 private DoapOptions doapOptions;
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300 private ASFExtOptions asfExtOptions;
301
302
303
304
305
306
307
308
309
310
311
312 private String lang;
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331 private String about;
332
333
334
335
336
337
338
339 private boolean validate;
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359 private DoapArtifact artifact;
360
361
362
363
364
365
366
367 private boolean skip;
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390 private ExtOptions[] extOptions;
391
392
393
394
395
396
397 private UserMessages messages = new UserMessages();
398
399
400
401
402
403
404 public void execute()
405 throws MojoExecutionException
406 {
407 if ( skip )
408 {
409 getLog().info( "Skipping DOAP generation" );
410 return;
411 }
412
413
414 if ( artifact != null )
415 {
416 MavenProject givenProject = getMavenProject( artifact );
417 if ( givenProject != null )
418 {
419 File outDir = new File( outputDirectory );
420 if ( !outDir.isAbsolute() )
421 {
422 outDir = new File( project.getBasedir(), outputDirectory );
423 }
424 File outFile = new File( outDir, artifact.getDoapFileName() );
425 writeDoapFile( givenProject, outFile );
426 return;
427 }
428 }
429
430
431 File outFile = new File( doapFile );
432 if ( !outFile.isAbsolute() )
433 {
434 outFile = new File( project.getBasedir(), doapFile );
435 }
436 if ( !doapFile.replaceAll( "\\\\", "/" ).contains( "/" ) )
437 {
438 File outDir = new File( outputDirectory );
439 if ( !outDir.isAbsolute() )
440 {
441 outDir = new File( project.getBasedir(), outputDirectory );
442 }
443 outFile = new File( outDir, doapFile );
444 }
445 writeDoapFile( project, outFile );
446 }
447
448
449
450
451
452
453
454
455
456
457 private MavenProject getMavenProject( DoapArtifact artifact )
458 {
459 if ( artifact == null )
460 {
461 return null;
462 }
463
464 if ( StringUtils.isEmpty( artifact.getGroupId() ) || StringUtils.isEmpty( artifact.getArtifactId() )
465 || StringUtils.isEmpty( artifact.getVersion() ) )
466 {
467 getLog().warn( "Missing groupId or artifactId or version in <artifact/> parameter, ignored it." );
468 return null;
469 }
470
471 getLog().info( "Using artifact " + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":"
472 + artifact.getVersion() );
473
474 try
475 {
476 Artifact art =
477 factory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
478 Artifact.SCOPE_COMPILE );
479
480 if ( art.getFile() == null )
481 {
482 MavenProject proj = mavenProjectBuilder.buildFromRepository( art, remoteRepositories, localRepository );
483 art = proj.getArtifact();
484
485 resolver.resolve( art, remoteRepositories, localRepository );
486
487 return proj;
488 }
489 }
490 catch ( ArtifactResolutionException e )
491 {
492 getLog().error( "ArtifactResolutionException: " + e.getMessage() + "\nIgnored <artifact/> parameter." );
493 }
494 catch ( ArtifactNotFoundException e )
495 {
496 getLog().error( "ArtifactNotFoundException: " + e.getMessage() + "\nIgnored <artifact/> parameter." );
497 }
498 catch ( ProjectBuildingException e )
499 {
500 getLog().error( "ProjectBuildingException: " + e.getMessage() + "\nIgnored <artifact/> parameter." );
501 }
502
503 return null;
504 }
505
506
507
508
509
510
511
512
513 private void writeDoapFile( MavenProject project, File outputFile )
514 throws MojoExecutionException
515 {
516
517
518
519
520 if ( !asfExtOptions.isIncluded() && ASFExtOptionsUtil.isASFProject( project ) )
521 {
522 getLog().info( "This project is an ASF project, ASF Extensions to DOAP will be added." );
523 asfExtOptions.setIncluded( true );
524 }
525
526
527
528
529
530 Writer w;
531 try
532 {
533 if ( !outputFile.getParentFile().exists() )
534 {
535 FileUtils.mkdir( outputFile.getParentFile().getAbsolutePath() );
536 }
537
538 w = WriterFactory.newXmlWriter( outputFile );
539 }
540 catch ( IOException e )
541 {
542 throw new MojoExecutionException( "Error creating DOAP file " + outputFile.getAbsolutePath(), e );
543 }
544
545 if ( asfExtOptions.isIncluded() )
546 {
547 getLog().info( "Generating an ASF DOAP file " + outputFile.getAbsolutePath() );
548 }
549 else
550 {
551 getLog().info( "Generating a pure DOAP file " + outputFile.getAbsolutePath() );
552 }
553
554 XMLWriter writer = new PrettyPrintXMLWriter( w, project.getModel().getModelEncoding(), null );
555
556
557
558
559
560 DoapUtil.writeHeader( writer );
561
562
563 DoapUtil.writeStartElement( writer, "rdf", "RDF" );
564 if ( Arrays.binarySearch( Locale.getISOLanguages(), lang ) < 0 )
565 {
566 messages.addMessage( new String[] { "doapOptions", "lang" }, lang, UserMessages.INVALID_ISO_DATE );
567 throw new MojoExecutionException( messages.getErrorMessages().get( 0 ) );
568 }
569 writer.addAttribute( "xml:lang", lang );
570 if ( StringUtils.isEmpty( doapOptions.getXmlnsNamespaceURI() ) )
571 {
572 messages.addMessage( new String[] { "doapOptions", "xmlnsNamespaceURI" }, null, UserMessages.REQUIRED );
573 throw new MojoExecutionException( messages.getErrorMessages().get( 0 ) );
574 }
575 writer.addAttribute( "xmlns"
576 + ( StringUtils.isEmpty( doapOptions.getXmlnsPrefix() ) ? "" : ":"
577 + doapOptions.getXmlnsPrefix() ), doapOptions.getXmlnsNamespaceURI() );
578 writer.addAttribute( "xmlns:rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#" );
579 writer.addAttribute( "xmlns:foaf", "http://xmlns.com/foaf/0.1/" );
580 if ( asfExtOptions.isIncluded() )
581 {
582 if ( StringUtils.isEmpty( asfExtOptions.getXmlnsPrefix() ) )
583 {
584 messages.addMessage( new String[] { "doapOptions", "xmlnsPrefix" }, null, UserMessages.REQUIRED );
585 throw new MojoExecutionException( messages.getErrorMessages().get( 0 ) );
586 }
587 if ( StringUtils.isEmpty( asfExtOptions.getXmlnsNamespaceURI() ) )
588 {
589 messages.addMessage( new String[] { "doapOptions", "xmlnsNamespaceURI" }, null, UserMessages.REQUIRED );
590 }
591 writer.addAttribute( "xmlns"
592 + ( StringUtils.isEmpty( asfExtOptions.getXmlnsPrefix() ) ? "" : ":"
593 + asfExtOptions.getXmlnsPrefix() ), asfExtOptions.getXmlnsNamespaceURI() );
594 }
595 if ( extOptions != null && extOptions.length > 0 && !extOptions[0].getExtensions().isEmpty() )
596 {
597 for ( ExtOptions extOption : extOptions )
598 {
599 if ( StringUtils.isEmpty( extOption.getXmlnsPrefix() ) )
600 {
601 messages.addMessage( new String[] { "extOptions", "extOption", "xmlnsPrefix" }, null,
602 UserMessages.REQUIRED );
603 throw new MojoExecutionException( messages.getErrorMessages().get( 0 ) );
604 }
605 if ( StringUtils.isEmpty( extOption.getXmlnsNamespaceURI() ) )
606 {
607 messages.addMessage( new String[] { "extOptions", "extOption", "xmlnsNamespaceURI" }, null,
608 UserMessages.REQUIRED );
609 throw new MojoExecutionException( messages.getErrorMessages().get( 0 ) );
610 }
611 writer.addAttribute( "xmlns"
612 + ( StringUtils.isEmpty( extOption.getXmlnsPrefix() ) ? "" : ":"
613 + extOption.getXmlnsPrefix() ),
614 extOption.getXmlnsNamespaceURI() );
615 }
616 }
617
618
619 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "Project" );
620 boolean added = false;
621 if ( artifact != null )
622 {
623 String about_ = project.getUrl();
624
625 if ( StringUtils.isNotEmpty( about_ ) )
626 {
627 try
628 {
629 new URL( about_ );
630
631 writer.addAttribute( "rdf:about", about_ );
632 added = true;
633 }
634 catch ( MalformedURLException e )
635 {
636 }
637 }
638
639 if ( !added )
640 {
641 messages.getWarnMessages().add( "The project's url defined from " + artifact.toConfiguration()
642 + " is empty or not a valid URL, using <about/> parameter." );
643 }
644 }
645
646 if ( !added )
647 {
648 if ( StringUtils.isNotEmpty( about ) )
649 {
650 try
651 {
652 new URL( about );
653
654 writer.addAttribute( "rdf:about", about );
655 }
656 catch ( MalformedURLException e )
657 {
658 messages.addMessage( new String[] { "about" }, about, UserMessages.INVALID_URL );
659 }
660 added = true;
661 }
662 }
663
664 if ( !added )
665 {
666 messages.addMessage( new String[] { "about" }, null, UserMessages.RECOMMENDED );
667 }
668
669
670 writeName( writer, project );
671
672
673 writeDescription( writer, project );
674
675
676 writeImplements( writer );
677
678
679 writeAudience( writer );
680
681
682 writeVendor( writer, project );
683
684
685 writeCreated( writer, project );
686
687
688 writeHomepage( writer, project );
689
690
691 writeBlog( writer );
692
693
694 writeLicenses( writer, project );
695
696
697 writeProgrammingLanguage( writer, project );
698
699
700 writeCategory( writer, project );
701
702
703 writeOS( writer, project );
704
705
706 writePlateform( writer );
707
708
709 writeLanguage( writer );
710
711
712 writeSourceRepositories( writer, project );
713
714
715 writeBugDatabase( writer, project );
716
717
718 writeMailingList( writer, project );
719
720
721 writeDownloadPage( writer, project );
722
723
724 writeScreenshots( writer, project );
725
726
727 writeServiceEndpoint( writer );
728
729
730 writeWiki( writer, project );
731
732
733 writeReleases( writer, project );
734
735
736 @SuppressWarnings( "unchecked" )
737 List<Contributor> developers = project.getDevelopers();
738 writeContributors( writer, developers );
739
740
741 @SuppressWarnings( "unchecked" )
742 List<Contributor> contributors = project.getContributors();
743 writeContributors( writer, contributors );
744
745
746 @SuppressWarnings( "unchecked" )
747 Map<String, String> map = doapOptions.getExtra();
748 writeExtra( writer, project, "Extra DOAP vocabulary.", map, doapOptions.getXmlnsPrefix() );
749
750
751 writeASFext( writer, project );
752
753
754 writeExtensions( writer );
755
756 writer.endElement();
757
758 writeOrganizations( writer );
759
760 writer.endElement();
761
762 try
763 {
764 w.close();
765 }
766 catch ( IOException e )
767 {
768 throw new MojoExecutionException( "Error when closing the writer.", e );
769 }
770
771 if ( !messages.getWarnMessages().isEmpty() )
772 {
773 for ( String warn : messages.getWarnMessages() )
774 {
775 getLog().warn( warn );
776 }
777 }
778
779 if ( !messages.getErrorMessages().isEmpty() )
780 {
781 getLog().error( "" );
782 for ( String error : messages.getErrorMessages() )
783 {
784 getLog().error( error );
785 }
786 getLog().error( "" );
787
788 if ( ASFExtOptionsUtil.isASFProject( project ) )
789 {
790 getLog().error( "For more information about the errors and possible solutions, please read the plugin documentation:" );
791 getLog().error( "http://maven.apache.org/plugins/maven-doap-plugin/usage.html#DOAP_ASF_Configuration" );
792 throw new MojoExecutionException( "The generated DOAP doesn't respect ASF rules, see above." );
793 }
794 }
795
796 if ( validate )
797 {
798 List<String> errors = DoapUtil.validate( outputFile );
799 if ( !errors.isEmpty() )
800 {
801 getLog().error( "" );
802 for ( String error : errors )
803 {
804 getLog().error( error );
805 }
806 getLog().error( "" );
807
808 throw new MojoExecutionException( "Error parsing the generated DOAP file, see above." );
809 }
810 }
811 }
812
813
814
815
816
817
818
819
820 private void writeName( XMLWriter writer, MavenProject project )
821 {
822 String name = DoapUtil.interpolate( doapOptions.getName(), project, settings );
823 if ( StringUtils.isEmpty( name ) )
824 {
825 messages.addMessage( new String[] { "doapOptions", "name" }, null,
826 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
827 return;
828 }
829
830 DoapUtil.writeComment( writer, "A name of something." );
831 if ( ASFExtOptionsUtil.isASFProject( project ) && !name.toLowerCase( Locale.ENGLISH ).startsWith( "apache" ) )
832 {
833 name = "Apache " + name;
834 }
835 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "name", name );
836 }
837
838
839
840
841
842
843
844
845
846 private void writeDescription( XMLWriter writer, MavenProject project )
847 {
848 boolean addComment = false;
849 String description = DoapUtil.interpolate( doapOptions.getDescription(), project, settings );
850 if ( StringUtils.isEmpty( description ) )
851 {
852 messages.addMessage( new String[] { "doapOptions", "description" }, null,
853 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
854 }
855 else
856 {
857 DoapUtil.writeComment( writer, "Plain text description of a project, of 2-4 sentences in length." );
858 addComment = true;
859 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "description", description, lang );
860 }
861
862 String comment = "Short plain text description of a project.";
863 String shortdesc = DoapUtil.interpolate( doapOptions.getShortdesc(), project, settings );
864 if ( StringUtils.isEmpty( shortdesc ) )
865 {
866 messages.addMessage( new String[] { "doapOptions", "shortdesc" }, null,
867 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
868 return;
869 }
870 if ( description.equals( shortdesc ) )
871 {
872
873 String sentence = StringUtils.split( shortdesc, "." )[0];
874 if ( StringUtils.split( sentence, " " ).length > 10 )
875 {
876 messages.addMessage( new String[] { "doapOptions", "shortdesc" }, null,
877 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
878 return;
879 }
880 if ( !addComment )
881 {
882 DoapUtil.writeComment( writer, comment );
883 }
884 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "shortdesc", sentence, lang );
885 return;
886 }
887 if ( !addComment )
888 {
889 DoapUtil.writeComment( writer, comment );
890 }
891 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "shortdesc", shortdesc, lang );
892 }
893
894
895
896
897
898
899
900
901 private void writeCreated( XMLWriter writer, MavenProject project )
902 {
903 String created = DoapUtil.interpolate( doapOptions.getCreated(), project, settings );
904 if ( StringUtils.isEmpty( created ) )
905 {
906 messages.addMessage( new String[] { "doapOptions", "created" }, null,
907 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
908 return;
909 }
910
911 try
912 {
913 DOAP_DATE_FORMAT.parse( created );
914 }
915 catch ( ParseException e )
916 {
917 messages.addMessage( new String[] { "doapOptions", "created" }, null, UserMessages.INVALID_DATE );
918 return;
919 }
920
921 DoapUtil.writeComment( writer, "Date when something was created, in YYYY-MM-DD form. e.g. 2004-04-05" );
922 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "created", created );
923 }
924
925
926
927
928
929
930
931
932
933 private void writeHomepage( XMLWriter writer, MavenProject project )
934 {
935 String homepage = DoapUtil.interpolate( doapOptions.getHomepage(), project, settings );
936 if ( StringUtils.isEmpty( homepage ) )
937 {
938 messages.addMessage( new String[] { "doapOptions", "homepage" }, null,
939 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
940 }
941 else
942 {
943 try
944 {
945 new URL( homepage );
946
947 DoapUtil.writeComment( writer, "URL of a project's homepage, associated with exactly one project." );
948 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "homepage", homepage );
949 }
950 catch ( MalformedURLException e )
951 {
952 messages.addMessage( new String[] { "doapOptions", "homepage" }, homepage, UserMessages.INVALID_URL );
953 }
954 }
955
956 if ( StringUtils.isNotEmpty( doapOptions.getOldHomepage() ) )
957 {
958 String oldHomepage = DoapUtil.interpolate( doapOptions.getOldHomepage(), project, settings );
959 if ( StringUtils.isEmpty( oldHomepage ) )
960 {
961 return;
962 }
963
964 try
965 {
966 new URL( oldHomepage );
967
968 DoapUtil.writeComment( writer, "URL of a project's past homepage, associated with exactly one project." );
969 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "old-homepage", oldHomepage );
970 }
971 catch ( MalformedURLException e )
972 {
973 messages.addMessage( new String[] { "doapOptions", "oldHomepage" }, oldHomepage,
974 UserMessages.INVALID_URL );
975 }
976 }
977 }
978
979
980
981
982
983
984
985
986
987 private void writeProgrammingLanguage( XMLWriter writer, MavenProject project )
988 {
989 if ( StringUtils.isEmpty( doapOptions.getProgrammingLanguage() ) && StringUtils.isEmpty( language ) )
990 {
991 messages.addMessage( new String[] { "doapOptions", "programmingLanguage" }, null,
992 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
993 return;
994 }
995
996 boolean addComment = false;
997 String comment = "Programming language.";
998 if ( StringUtils.isNotEmpty( language ) )
999 {
1000 getLog().warn( "The <language/> parameter is deprecated, please use "
1001 + messages.toConfiguration( new String[] { "doapOptions", "programmingLanguage" }, null )
1002 + " parameter instead of." );
1003
1004 language = language.trim();
1005
1006 if ( asfExtOptions.isIncluded() )
1007 {
1008 String asfLanguage = ASFExtOptionsUtil.getProgrammingLanguageSupportedByASF( language );
1009 if ( asfLanguage == null )
1010 {
1011 messages.getErrorMessages().add( "The deprecated "
1012 + messages.toConfiguration( new String[] { "language" },
1013 language )
1014 + " parameter is not supported by ASF. Should be one of "
1015 + Arrays.toString( ASFExtOptionsUtil.PROGRAMMING_LANGUAGES ) );
1016 }
1017 else
1018 {
1019 DoapUtil.writeComment( writer, comment );
1020 addComment = true;
1021 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "programming-language",
1022 asfLanguage.trim() );
1023 }
1024 }
1025 else
1026 {
1027 DoapUtil.writeComment( writer, comment );
1028 addComment = true;
1029 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "programming-language", language.trim() );
1030 }
1031 }
1032
1033 if ( StringUtils.isNotEmpty( doapOptions.getProgrammingLanguage() ) )
1034 {
1035 String[] languages = StringUtils.split( doapOptions.getProgrammingLanguage(), "," );
1036 for ( String language : languages )
1037 {
1038 language = language.trim();
1039
1040 if ( asfExtOptions.isIncluded() )
1041 {
1042 String asfLanguage = ASFExtOptionsUtil.getProgrammingLanguageSupportedByASF( language );
1043 if ( asfLanguage == null )
1044 {
1045 messages.getErrorMessages().add( "The "
1046 + messages.toConfiguration( new String[] { "doapOptions",
1047 "programmingLanguage" }, language )
1048 + " parameter is not supported by ASF. "
1049 + "Should be one of "
1050 + Arrays.toString( ASFExtOptionsUtil.PROGRAMMING_LANGUAGES ) );
1051 }
1052 else
1053 {
1054 if ( !addComment )
1055 {
1056 DoapUtil.writeComment( writer, comment );
1057 addComment = true;
1058 }
1059 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "programming-language",
1060 asfLanguage );
1061 }
1062 }
1063 else
1064 {
1065 if ( !addComment )
1066 {
1067 DoapUtil.writeComment( writer, comment );
1068 addComment = true;
1069 }
1070 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "programming-language", language );
1071 }
1072 }
1073 }
1074 }
1075
1076
1077
1078
1079
1080
1081
1082
1083 private void writeCategory( XMLWriter writer, MavenProject project )
1084 {
1085 if ( StringUtils.isEmpty( doapOptions.getCategory() ) && StringUtils.isEmpty( category ) )
1086 {
1087 messages.addMessage( new String[] { "doapOptions", "category" }, null,
1088 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
1089 return;
1090 }
1091
1092
1093 boolean addComment = false;
1094 String comment = "A category of project.";
1095 if ( StringUtils.isNotEmpty( category ) )
1096 {
1097 getLog().warn( "The <category/> parameter is deprecated, please use "
1098 + messages.toConfiguration( new String[] { "doapOptions", "category" }, null )
1099 + " parameter instead of." );
1100
1101 category = category.trim();
1102
1103 if ( asfExtOptions.isIncluded() )
1104 {
1105 String asfCategory = ASFExtOptionsUtil.getCategorySupportedByASF( category );
1106 if ( asfCategory == null )
1107 {
1108 messages.getErrorMessages().add( "The deprecated "
1109 + messages.toConfiguration( new String[] { "category" },
1110 category )
1111 + " parameter is not supported by ASF. Should be one of "
1112 + Arrays.toString( ASFExtOptionsUtil.CATEGORIES ) );
1113 }
1114 else
1115 {
1116 DoapUtil.writeComment( writer, comment );
1117 addComment = true;
1118 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "category",
1119 ASFExtOptionsUtil.CATEGORY_RESOURCE + asfCategory );
1120 }
1121 }
1122 else
1123 {
1124 DoapUtil.writeComment( writer, comment );
1125 addComment = true;
1126 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "category", category );
1127 }
1128 }
1129
1130 if ( StringUtils.isNotEmpty( doapOptions.getCategory() ) )
1131 {
1132 String[] categories = StringUtils.split( doapOptions.getCategory(), "," );
1133 for ( String category : categories )
1134 {
1135 category = category.trim();
1136
1137 if ( asfExtOptions.isIncluded() )
1138 {
1139 String asfCategory = ASFExtOptionsUtil.getCategorySupportedByASF( category );
1140 if ( asfCategory == null )
1141 {
1142 messages.getErrorMessages().add( "The "
1143 + messages.toConfiguration( new String[] { "doapOptions",
1144 "category" }, category )
1145 + " parameter is not supported by ASF. Should be one of "
1146 + Arrays.toString( ASFExtOptionsUtil.CATEGORIES ) );
1147 }
1148 else
1149 {
1150 if ( !addComment )
1151 {
1152 DoapUtil.writeComment( writer, comment );
1153 addComment = true;
1154 }
1155 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "category",
1156 ASFExtOptionsUtil.CATEGORY_RESOURCE + asfCategory );
1157 }
1158 }
1159 else
1160 {
1161 if ( !addComment )
1162 {
1163 DoapUtil.writeComment( writer, comment );
1164 addComment = true;
1165 }
1166 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "category", category );
1167 }
1168 }
1169 }
1170 }
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180 private void writeDownloadPage( XMLWriter writer, MavenProject project )
1181 {
1182 String downloadPage = DoapUtil.interpolate( doapOptions.getDownloadPage(), project, settings );
1183 if ( StringUtils.isEmpty( downloadPage ) )
1184 {
1185 messages.addMessage( new String[] { "doapOptions", "downloadPage" }, null,
1186 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
1187 return;
1188 }
1189
1190 try
1191 {
1192 new URL( downloadPage );
1193
1194 DoapUtil.writeComment( writer, "Download page." );
1195 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "download-page", downloadPage );
1196 }
1197 catch ( MalformedURLException e )
1198 {
1199 messages.addMessage( new String[] { "doapOptions", "downloadPage" }, downloadPage, UserMessages.INVALID_URL );
1200 }
1201
1202 if ( StringUtils.isNotEmpty( doapOptions.getDownloadMirror() ) )
1203 {
1204 boolean addComment = false;
1205 String[] downloadMirrors = StringUtils.split( doapOptions.getDownloadMirror(), "," );
1206 for ( String downloadMirror : downloadMirrors )
1207 {
1208 downloadMirror = downloadMirror.trim();
1209
1210 try
1211 {
1212 new URL( downloadMirror );
1213
1214 if ( !addComment )
1215 {
1216 DoapUtil.writeComment( writer, "Mirror of software download web page." );
1217 addComment = true;
1218 }
1219 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "download-mirror",
1220 downloadMirror );
1221 }
1222 catch ( MalformedURLException e )
1223 {
1224 messages.addMessage( new String[] { "doapOptions", "downloadMirror" }, downloadMirror,
1225 UserMessages.INVALID_URL );
1226 }
1227 }
1228 }
1229 }
1230
1231
1232
1233
1234
1235
1236
1237
1238 private void writeOS( XMLWriter writer, MavenProject project )
1239 {
1240 String os = DoapUtil.interpolate( doapOptions.getOs(), project, settings );
1241 if ( StringUtils.isEmpty( os ) )
1242 {
1243 return;
1244 }
1245
1246 DoapUtil.writeComment( writer, "Operating system that a project is limited to." );
1247 String[] oses = StringUtils.split( os, "," );
1248 for ( String os_ : oses )
1249 {
1250 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "os", os_.trim() );
1251 }
1252 }
1253
1254
1255
1256
1257
1258
1259
1260
1261 private void writeScreenshots( XMLWriter writer, MavenProject project )
1262 {
1263 String screenshots = DoapUtil.interpolate( doapOptions.getScreenshots(), project, settings );
1264 if ( StringUtils.isEmpty( screenshots ) )
1265 {
1266 return;
1267 }
1268
1269 screenshots = screenshots.trim();
1270 try
1271 {
1272 new URL( screenshots );
1273 }
1274 catch ( MalformedURLException e )
1275 {
1276 messages.addMessage( new String[] { "doapOptions", "screenshots" }, screenshots, UserMessages.INVALID_URL );
1277 return;
1278 }
1279
1280 DoapUtil.writeComment( writer, "Web page with screenshots of project." );
1281 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "screenshots", screenshots );
1282 }
1283
1284
1285
1286
1287
1288
1289
1290
1291 private void writeWiki( XMLWriter writer, MavenProject project )
1292 {
1293 String wiki = DoapUtil.interpolate( doapOptions.getWiki(), project, settings );
1294 if ( StringUtils.isEmpty( wiki ) )
1295 {
1296 return;
1297 }
1298
1299 wiki = wiki.trim();
1300 try
1301 {
1302 new URL( wiki );
1303 }
1304 catch ( MalformedURLException e )
1305 {
1306 messages.addMessage( new String[] { "doapOptions", "wiki" }, wiki, UserMessages.INVALID_URL );
1307 return;
1308 }
1309
1310 DoapUtil.writeComment( writer, "URL of Wiki for collaborative discussion of project." );
1311 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "wiki", wiki );
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321 private void writeLicenses( XMLWriter writer, MavenProject project )
1322 {
1323 String license = DoapUtil.interpolate( doapOptions.getLicense(), project, settings );
1324 if ( StringUtils.isEmpty( license ) )
1325 {
1326 boolean added = false;
1327 @SuppressWarnings( "unchecked" )
1328 List<License> licenses = project.getLicenses();
1329 if ( licenses.size() > 1 )
1330 {
1331 for ( int i = 1; i < licenses.size(); i++ )
1332 {
1333 if ( StringUtils.isEmpty( licenses.get( i ).getUrl() ) )
1334 {
1335 continue;
1336 }
1337
1338 String licenseUrl = licenses.get( i ).getUrl().trim();
1339 try
1340 {
1341 new URL( licenseUrl );
1342
1343 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "license", licenseUrl );
1344 added = true;
1345 }
1346 catch ( MalformedURLException e )
1347 {
1348 messages.addMessage( new String[] { "project", "licenses", "license", "url" }, licenseUrl,
1349 UserMessages.INVALID_URL );
1350 }
1351 }
1352 }
1353
1354 if ( !added )
1355 {
1356 messages.addMessage( new String[] { "doapOptions", "license" }, null,
1357 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
1358 }
1359 return;
1360 }
1361
1362 try
1363 {
1364 new URL( license );
1365
1366 DoapUtil.writeComment( writer, "The URI of the license the software is distributed under." );
1367 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "license", license );
1368 }
1369 catch ( MalformedURLException e )
1370 {
1371 messages.addMessage( new String[] { "doapOptions", "license" }, license, UserMessages.INVALID_URL );
1372 }
1373 }
1374
1375
1376
1377
1378
1379
1380
1381
1382 private void writeBugDatabase( XMLWriter writer, MavenProject project )
1383 {
1384 String bugDatabase = DoapUtil.interpolate( doapOptions.getBugDatabase(), project, settings );
1385 if ( StringUtils.isEmpty( bugDatabase ) )
1386 {
1387 messages.addMessage( new String[] { "doapOptions", "bugDatabase" }, null,
1388 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
1389 return;
1390 }
1391
1392 try
1393 {
1394 new URL( bugDatabase );
1395
1396 DoapUtil.writeComment( writer, "Bug database." );
1397 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "bug-database", bugDatabase );
1398 }
1399 catch ( MalformedURLException e )
1400 {
1401 messages.addMessage( new String[] { "doapOptions", "bugDatabase" }, bugDatabase, UserMessages.INVALID_URL );
1402 }
1403 }
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413 private void writeMailingList( XMLWriter writer, MavenProject project )
1414 {
1415 String ml = DoapUtil.interpolate( doapOptions.getMailingList(), project, settings );
1416 if ( StringUtils.isEmpty( ml ) )
1417 {
1418 messages.addMessage( new String[] { "doapOptions", "mailingList" }, null,
1419 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
1420 return;
1421 }
1422
1423 try
1424 {
1425 new URL( ml );
1426
1427 DoapUtil.writeComment( writer, "Mailing lists." );
1428 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "mailing-list", ml );
1429 }
1430 catch ( MalformedURLException e )
1431 {
1432 messages.addMessage( new String[] { "doapOptions", "mailingList" }, ml, UserMessages.INVALID_URL );
1433 }
1434 }
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445 private void writeReleases( XMLWriter writer, MavenProject project )
1446 throws MojoExecutionException
1447 {
1448 Artifact artifact =
1449 artifactFactory.createArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), null,
1450 project.getPackaging() );
1451 RepositoryMetadata metadata = new ArtifactRepositoryMetadata( artifact );
1452
1453 for ( ArtifactRepository repo : remoteRepositories )
1454 {
1455 if ( repo.isBlacklisted() )
1456 {
1457 continue;
1458 }
1459 if ( repo.getSnapshots().isEnabled() )
1460 {
1461 continue;
1462 }
1463 if ( repo.getReleases().isEnabled() )
1464 {
1465 try
1466 {
1467 repositoryMetadataManager.resolveAlways( metadata, localRepository, repo );
1468 break;
1469 }
1470 catch ( RepositoryMetadataResolutionException e )
1471 {
1472 throw new MojoExecutionException( metadata.extendedToString()
1473 + " could not be retrieved from repositories due to an error: " + e.getMessage(), e );
1474 }
1475 }
1476 }
1477
1478 if ( metadata.getMetadata().getVersioning() == null )
1479 {
1480 messages.getWarnMessages().add( "No versioning was found for " + artifact.getGroupId() + ":"
1481 + artifact.getArtifactId() + ". Ignored DOAP <release/> tag." );
1482 return;
1483 }
1484
1485 List<String> versions = metadata.getMetadata().getVersioning().getVersions();
1486
1487
1488 Collections.reverse( versions );
1489 boolean addComment = false;
1490 int i = 0;
1491 for ( String version : versions )
1492 {
1493 if ( !addComment )
1494 {
1495 DoapUtil.writeComment( writer, "Project releases." );
1496 addComment = true;
1497 }
1498
1499 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "release" );
1500 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "Version" );
1501
1502 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "name" );
1503 if ( version.equals( metadata.getMetadata().getVersioning().getRelease() ) )
1504 {
1505 writer.writeText( "Latest stable release" );
1506 }
1507 else
1508 {
1509 writer.writeText( project.getName() + " - " + version );
1510 }
1511 writer.endElement();
1512
1513 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "revision", version );
1514
1515
1516 for ( ArtifactRepository repo : remoteRepositories )
1517 {
1518 Artifact artifactRelease =
1519 artifactFactory.createArtifact( project.getGroupId(), project.getArtifactId(), version, null,
1520 project.getPackaging() );
1521
1522 if ( artifactRelease == null )
1523 {
1524 continue;
1525 }
1526
1527 String fileRelease = repo.getUrl() + "/" + repo.pathOf( artifactRelease );
1528 try
1529 {
1530 DoapUtil.fetchURL( settings, new URL( fileRelease ) );
1531 }
1532 catch ( IOException e )
1533 {
1534 getLog().debug( "IOException :" + e.getMessage() );
1535 continue;
1536 }
1537 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "file-release", fileRelease );
1538
1539 Date releaseDate = null;
1540 try
1541 {
1542 releaseDate =
1543 REPOSITORY_DATE_FORMAT.parse( metadata.getMetadata().getVersioning().getLastUpdated() );
1544 }
1545 catch ( ParseException e )
1546 {
1547 getLog().error( "Unable to parse date '" + metadata.getMetadata().getVersioning().getLastUpdated()
1548 + "'" );
1549 continue;
1550 }
1551
1552
1553 if ( i == 0 )
1554 {
1555 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "created",
1556 DOAP_DATE_FORMAT.format( releaseDate ) );
1557 }
1558 }
1559
1560 writer.endElement();
1561 writer.endElement();
1562
1563 i++;
1564 }
1565 }
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576 private void writeSourceRepositories( XMLWriter writer, MavenProject project )
1577 {
1578 String anonymousConnection = DoapUtil.interpolate( doapOptions.getScmAnonymous(), project, settings );
1579 if ( StringUtils.isEmpty( anonymousConnection ) )
1580 {
1581 messages.addMessage( new String[] { "doapOptions", "scmAnonymousConnection" }, null,
1582 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
1583 }
1584 else
1585 {
1586 DoapUtil.writeComment( writer, "Anonymous Source Repository." );
1587
1588 try
1589 {
1590 new URL( anonymousConnection );
1591
1592 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "repository" );
1593 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "Repository" );
1594 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "location", anonymousConnection );
1595 writer.endElement();
1596 writer.endElement();
1597 }
1598 catch ( MalformedURLException e )
1599 {
1600 writeSourceRepository( writer, project, anonymousConnection );
1601 }
1602 }
1603
1604 String devConnection = DoapUtil.interpolate( doapOptions.getScmDeveloper(), project, settings );
1605 if ( StringUtils.isEmpty( devConnection ) )
1606 {
1607 messages.addMessage( new String[] { "doapOptions", "scmDeveloperConnection" }, null,
1608 UserMessages.REQUIRED_BY_ASF_OR_RECOMMENDED );
1609 }
1610 else
1611 {
1612 DoapUtil.writeComment( writer, "Developer Source Repository." );
1613
1614 try
1615 {
1616 new URL( devConnection );
1617
1618 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "repository" );
1619 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "Repository" );
1620 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "location", devConnection );
1621 writer.endElement();
1622 writer.endElement();
1623 }
1624 catch ( MalformedURLException e )
1625 {
1626 writeSourceRepository( writer, project, devConnection );
1627 }
1628 }
1629 }
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650 private void writeSourceRepository( XMLWriter writer, MavenProject project, String connection )
1651 {
1652 ScmRepository repository = getScmRepository( connection );
1653
1654 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "repository" );
1655
1656 if ( isScmSystem( repository, "cvs" ) )
1657 {
1658 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "CVSRepository" );
1659
1660 CvsScmProviderRepository cvsRepo = (CvsScmProviderRepository) repository.getProviderRepository();
1661
1662 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "anon-root", cvsRepo.getCvsRoot() );
1663 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "module", cvsRepo.getModule() );
1664 }
1665 else if ( isScmSystem( repository, "svn" ) )
1666 {
1667 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "SVNRepository" );
1668
1669 SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) repository.getProviderRepository();
1670
1671 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "location", svnRepo.getUrl() );
1672 }
1673 else
1674 {
1675
1676
1677
1678
1679
1680 DoapUtil.writeStartElement( writer, doapOptions.getXmlnsPrefix(), "Repository" );
1681
1682 if ( connection.length() < 4 )
1683 {
1684 throw new IllegalArgumentException( "The source repository connection is too short." );
1685 }
1686
1687 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "location",
1688 connection.substring( 4 ) );
1689 }
1690
1691 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "browse", project.getScm().getUrl() );
1692
1693 writer.endElement();
1694 writer.endElement();
1695 }
1696
1697
1698
1699
1700
1701
1702
1703 private void writeContributors( XMLWriter writer, List<Contributor> contributors )
1704 {
1705 if ( contributors == null || contributors.isEmpty() )
1706 {
1707 return;
1708 }
1709
1710 boolean isDeveloper = Developer.class.isAssignableFrom( contributors.get( 0 ).getClass() );
1711 if ( isDeveloper )
1712 {
1713 DoapUtil.writeComment( writer, "Main committers." );
1714 }
1715 else
1716 {
1717 DoapUtil.writeComment( writer, "Contributed persons." );
1718 }
1719
1720 List<Contributor> maintainers = DoapUtil.getContributorsWithMaintainerRole( i18n, contributors );
1721 List<Contributor> developers = DoapUtil.getContributorsWithDeveloperRole( i18n, contributors );
1722 List<Contributor> documenters = DoapUtil.getContributorsWithDocumenterRole( i18n, contributors );
1723 List<Contributor> translators = DoapUtil.getContributorsWithTranslatorRole( i18n, contributors );
1724 List<Contributor> testers = DoapUtil.getContributorsWithTesterRole( i18n, contributors );
1725 List<Contributor> helpers = DoapUtil.getContributorsWithHelperRole( i18n, contributors );
1726 List<Contributor> unknowns = DoapUtil.getContributorsWithUnknownRole( i18n, contributors );
1727
1728
1729 if ( isDeveloper )
1730 {
1731 maintainers.addAll( unknowns );
1732 }
1733 else
1734 {
1735 helpers.addAll( unknowns );
1736 }
1737
1738
1739 if ( developers.size() != 0 )
1740 {
1741 writeContributor( writer, developers, "developer" );
1742 }
1743 if ( documenters.size() != 0 )
1744 {
1745 writeContributor( writer, documenters, "documenter" );
1746 }
1747 if ( helpers.size() != 0 )
1748 {
1749 writeContributor( writer, helpers, "helper" );
1750 }
1751 if ( maintainers.size() != 0 )
1752 {
1753 writeContributor( writer, maintainers, "maintainer" );
1754 }
1755 if ( testers.size() != 0 )
1756 {
1757 writeContributor( writer, testers, "tester" );
1758 }
1759 if ( translators.size() != 0 )
1760 {
1761 writeContributor( writer, translators, "translator" );
1762 }
1763 }
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782 private void writeContributor( XMLWriter writer, List<Contributor> developersOrContributors, String doapType )
1783 {
1784 if ( developersOrContributors == null || developersOrContributors.isEmpty() )
1785 {
1786 return;
1787 }
1788
1789 sortContributors( developersOrContributors );
1790
1791 for ( Contributor developersOrContributor : developersOrContributors )
1792 {
1793 writeContributor( writer, developersOrContributor, doapOptions.getXmlnsPrefix(), doapType );
1794 }
1795 }
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816 private void writeContributor( XMLWriter writer, Contributor developerOrContributor, String xmlsPrefix,
1817 String doapType )
1818 {
1819 if ( developerOrContributor == null )
1820 {
1821 return;
1822 }
1823
1824 if ( StringUtils.isEmpty( doapType ) )
1825 {
1826 throw new IllegalArgumentException( "doapType is required." );
1827 }
1828
1829 String name = developerOrContributor.getName();
1830 String email = developerOrContributor.getEmail();
1831 String organization = developerOrContributor.getOrganization();
1832 String organizationUrl = developerOrContributor.getOrganizationUrl();
1833 String homepage = developerOrContributor.getUrl();
1834 String nodeId = null;
1835
1836
1837 if ( StringUtils.isEmpty( name ) )
1838 {
1839 messages.addMessage( new String[] { "project", "developers|contributors", "developer|contributor", "name" },
1840 null, UserMessages.REQUIRED );
1841 return;
1842 }
1843
1844 if ( !StringUtils.isEmpty( organization ) || !StringUtils.isEmpty( organizationUrl ) )
1845 {
1846 DoapUtil.Organization doapOrganization = DoapUtil.addOrganization( organization, organizationUrl );
1847 nodeId = DoapUtil.getNodeId();
1848 doapOrganization.addMember( nodeId );
1849 }
1850
1851 DoapUtil.writeStartElement( writer, xmlsPrefix, doapType );
1852 DoapUtil.writeStartElement( writer, "foaf", "Person" );
1853 if ( StringUtils.isNotEmpty( nodeId ) )
1854 {
1855 writer.addAttribute( "rdf:nodeID", nodeId );
1856 }
1857 DoapUtil.writeStartElement( writer, "foaf", "name" );
1858 writer.writeText( name );
1859 writer.endElement();
1860 if ( StringUtils.isNotEmpty( email ) )
1861 {
1862 if ( DoapUtil.isValidEmail( email ) )
1863 {
1864 DoapUtil.writeRdfResourceElement( writer, "foaf", "mbox", "mailto:" + email );
1865 }
1866 else
1867 {
1868 messages.addMessage( new String[] { "project", "developers|contributors", "developer|contributor",
1869 "email" }, null, UserMessages.INVALID_EMAIL );
1870 }
1871 }
1872 if ( StringUtils.isNotEmpty( organization ) && StringUtils.isNotEmpty( organizationUrl ) )
1873 {
1874 try
1875 {
1876 new URL( organizationUrl );
1877
1878 DoapUtil.addOrganization( organization, organizationUrl );
1879 }
1880 catch ( MalformedURLException e )
1881 {
1882 messages.addMessage( new String[] { "project", "developers|contributors", "developer|contributor",
1883 "organizationUrl" }, organizationUrl, UserMessages.INVALID_URL );
1884 }
1885 }
1886 if ( StringUtils.isNotEmpty( homepage ) )
1887 {
1888 try
1889 {
1890 new URL( homepage );
1891
1892 DoapUtil.writeRdfResourceElement( writer, "foaf", "homepage", homepage );
1893 }
1894 catch ( MalformedURLException e )
1895 {
1896 messages.addMessage( new String[] { "project", "developers|contributors", "developer|contributor",
1897 "homepage" }, homepage, UserMessages.INVALID_URL );
1898 }
1899 }
1900 writer.endElement();
1901 writer.endElement();
1902 }
1903
1904
1905
1906
1907
1908
1909
1910 private ScmRepository getScmRepository( String scmUrl )
1911 {
1912 ScmRepository repo = null;
1913 if ( !StringUtils.isEmpty( scmUrl ) )
1914 {
1915 try
1916 {
1917 repo = scmManager.makeScmRepository( scmUrl );
1918 }
1919 catch ( NoSuchScmProviderException e )
1920 {
1921 if ( getLog().isDebugEnabled() )
1922 {
1923 getLog().debug( e.getMessage(), e );
1924 }
1925 }
1926 catch ( ScmRepositoryException e )
1927 {
1928 if ( getLog().isDebugEnabled() )
1929 {
1930 getLog().debug( e.getMessage(), e );
1931 }
1932 }
1933 }
1934
1935 return repo;
1936 }
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947 private void writeASFext( XMLWriter writer, MavenProject project )
1948 {
1949 if ( !asfExtOptions.isIncluded() )
1950 {
1951 return;
1952 }
1953
1954 DoapUtil.writeComment( writer, "ASF extension." );
1955
1956
1957 String pmc = DoapUtil.interpolate( asfExtOptions.getPmc(), project, settings );
1958 if ( StringUtils.isNotEmpty( pmc ) )
1959 {
1960 DoapUtil.writeRdfResourceElement( writer, asfExtOptions.getXmlnsPrefix(), "pmc", pmc );
1961 }
1962 else
1963 {
1964 messages.addMessage( new String[] { "asfExtOptions", "pmc" }, null, UserMessages.REQUIRED_BY_ASF );
1965 }
1966
1967
1968 String name = DoapUtil.interpolate( asfExtOptions.getName(), project, settings );
1969 if ( StringUtils.isNotEmpty( name ) )
1970 {
1971 if ( !name.toLowerCase( Locale.ENGLISH ).trim().startsWith( "apache" ) )
1972 {
1973 name = "Apache " + name;
1974 }
1975 DoapUtil.writeElement( writer, asfExtOptions.getXmlnsPrefix(), "name", name );
1976 }
1977 else
1978 {
1979 messages.addMessage( new String[] { "asfExtOptions", "name" }, null, UserMessages.REQUIRED_BY_ASF );
1980 }
1981
1982 String homepage = DoapUtil.interpolate( doapOptions.getHomepage(), project, settings );
1983 if ( StringUtils.isNotEmpty( homepage ) )
1984 {
1985 try
1986 {
1987 new URL( homepage );
1988
1989 DoapUtil.writeRdfResourceElement( writer, "foaf", "homepage", homepage );
1990 }
1991 catch ( MalformedURLException e )
1992 {
1993 messages.addMessage( new String[] { "doapOptions", "homepage" }, homepage, UserMessages.INVALID_URL );
1994 }
1995 }
1996
1997
1998 if ( StringUtils.isEmpty( asfExtOptions.getCharter() ) )
1999 {
2000 messages.addMessage( new String[] { "asfExtOptions", "charter" }, null, UserMessages.REQUIRED_BY_ASF );
2001 }
2002 else
2003 {
2004 DoapUtil.writeElement( writer, asfExtOptions.getXmlnsPrefix(), "charter", asfExtOptions.getCharter() );
2005 }
2006
2007
2008 @SuppressWarnings( "unchecked" )
2009 List<Developer> developers = new ArrayList<Developer>( project.getDevelopers() );
2010 sortContributors( developers );
2011
2012 if ( StringUtils.isNotEmpty( asfExtOptions.getChair() ) )
2013 {
2014 DoapUtil.writeStartElement( writer, asfExtOptions.getXmlnsPrefix(), "chair" );
2015 DoapUtil.writeStartElement( writer, "foaf", "Person" );
2016 DoapUtil.writeStartElement( writer, "foaf", "name" );
2017 writer.writeText( asfExtOptions.getChair() );
2018 writer.endElement();
2019 writer.endElement();
2020 writer.endElement();
2021 }
2022 else
2023 {
2024 Developer chair = ASFExtOptionsUtil.findChair( developers );
2025 if ( chair != null )
2026 {
2027 writeContributor( writer, chair, asfExtOptions.getXmlnsPrefix(), "chair" );
2028 developers.remove( chair );
2029 }
2030 else
2031 {
2032 messages.addMessage( new String[] { "asfExtOptions", "chair" }, null, UserMessages.REQUIRED_BY_ASF );
2033 }
2034 }
2035
2036
2037 if ( developers != null && developers.size() > 0 )
2038 {
2039 List<Developer> pmcMembers = ASFExtOptionsUtil.findPMCMembers( developers );
2040 for ( Developer pmcMember : pmcMembers )
2041 {
2042 writeContributor( writer, pmcMember, asfExtOptions.getXmlnsPrefix(), "member" );
2043 }
2044 }
2045
2046 writeASFImplements( writer );
2047
2048 @SuppressWarnings( "unchecked" )
2049 Map<String, String> map = asfExtOptions.getExtra();
2050 writeExtra( writer, project, "Extra ASFExt vocabulary.", map, asfExtOptions.getXmlnsPrefix() );
2051 }
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061 private void writeASFImplements( XMLWriter writer )
2062 {
2063 if ( asfExtOptions.getStandards() == null || asfExtOptions.getStandards().isEmpty() )
2064 {
2065 return;
2066 }
2067
2068 for ( Standard standard : asfExtOptions.getStandards() )
2069 {
2070 DoapUtil.writeStartElement( writer, asfExtOptions.getXmlnsPrefix(), "implements" );
2071 DoapUtil.writeStartElement( writer, asfExtOptions.getXmlnsPrefix(), "Standard" );
2072
2073 if ( StringUtils.isEmpty( standard.getTitle() ) )
2074 {
2075 messages.addMessage( new String[] { "asfExtOptions", "standards", "title" }, null,
2076 UserMessages.REQUIRED_BY_ASF );
2077 }
2078 else
2079 {
2080 DoapUtil.writeElement( writer, asfExtOptions.getXmlnsPrefix(), "title", standard.getTitle().trim() );
2081 }
2082
2083 if ( StringUtils.isEmpty( standard.getBody() ) )
2084 {
2085 messages.addMessage( new String[] { "asfExtOptions", "standards", "body" }, null,
2086 UserMessages.REQUIRED_BY_ASF );
2087 }
2088 else
2089 {
2090 DoapUtil.writeElement( writer, asfExtOptions.getXmlnsPrefix(), "body", standard.getBody().trim() );
2091 }
2092
2093 if ( StringUtils.isEmpty( standard.getId() ) )
2094 {
2095 messages.addMessage( new String[] { "asfExtOptions", "standards", "id" }, null,
2096 UserMessages.REQUIRED_BY_ASF );
2097 }
2098 else
2099 {
2100 DoapUtil.writeElement( writer, asfExtOptions.getXmlnsPrefix(), "id", standard.getId().trim() );
2101 }
2102
2103 if ( StringUtils.isNotEmpty( standard.getUrl() ) )
2104 {
2105 String standardUrl = standard.getUrl().trim();
2106 try
2107 {
2108 new URL( standardUrl );
2109
2110 DoapUtil.writeElement( writer, asfExtOptions.getXmlnsPrefix(), "url", standardUrl );
2111 }
2112 catch ( MalformedURLException e )
2113 {
2114 messages.addMessage( new String[] { "asfExtOptions", "standards", "url" }, standardUrl,
2115 UserMessages.INVALID_URL );
2116 }
2117 }
2118
2119 writer.endElement();
2120 writer.endElement();
2121 }
2122 }
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140 private void writeOrganizations( XMLWriter writer )
2141 {
2142 Set<Entry<String, DoapUtil.Organization>> organizations = DoapUtil.getOrganizations();
2143
2144 for ( Entry<String, DoapUtil.Organization> organizationEntry : organizations )
2145 {
2146 DoapUtil.Organization organization = organizationEntry.getValue();
2147
2148 DoapUtil.writeStartElement( writer, "foaf", "Organization" );
2149 if ( !StringUtils.isEmpty( organization.getName() ) )
2150 {
2151 DoapUtil.writeElement( writer, "foaf", "name", organization.getName() );
2152 }
2153 if ( !StringUtils.isEmpty( organization.getUrl() ) )
2154 {
2155 try
2156 {
2157 new URL( organization.getUrl() );
2158
2159 DoapUtil.writeRdfResourceElement( writer, "foaf", "homepage", organization.getUrl() );
2160 }
2161 catch ( MalformedURLException e )
2162 {
2163 messages.errorMessages.add( "The organization URL " + organization.getUrl()
2164 + " is not a valid URL." );
2165 }
2166 }
2167 List<String> members = organization.getMembers();
2168 for ( String member : members )
2169 {
2170 DoapUtil.writeRdfNodeIdElement( writer, "foaf", "member", member );
2171 }
2172 writer.endElement();
2173 }
2174 }
2175
2176
2177
2178
2179
2180
2181
2182
2183 private void writeAudience( XMLWriter writer )
2184 {
2185 String audience = DoapUtil.interpolate( doapOptions.getAudience(), project, settings );
2186 if ( StringUtils.isEmpty( audience ) )
2187 {
2188 return;
2189 }
2190
2191 DoapUtil.writeComment( writer, "Audience." );
2192 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "audience", audience );
2193 }
2194
2195
2196
2197
2198
2199
2200
2201
2202 private void writeBlog( XMLWriter writer )
2203 {
2204 String blog = DoapUtil.interpolate( doapOptions.getBlog(), project, settings );
2205 if ( StringUtils.isEmpty( doapOptions.getBlog() ) )
2206 {
2207 return;
2208 }
2209
2210 blog = blog.trim();
2211 try
2212 {
2213 new URL( blog );
2214 }
2215 catch ( MalformedURLException e )
2216 {
2217 messages.addMessage( new String[] { "doapOptions", "blog" }, blog, UserMessages.INVALID_URL );
2218 return;
2219 }
2220
2221 DoapUtil.writeComment( writer, "Blog page." );
2222 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "blog", blog );
2223 }
2224
2225
2226
2227
2228
2229
2230
2231
2232 private void writePlateform( XMLWriter writer )
2233 {
2234 if ( StringUtils.isEmpty( doapOptions.getPlatform() ) )
2235 {
2236 return;
2237 }
2238
2239 DoapUtil.writeComment( writer, "Platform." );
2240 String[] platforms = StringUtils.split( doapOptions.getPlatform(), "," );
2241 for ( String platform : platforms )
2242 {
2243 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "platform", platform.trim() );
2244 }
2245 }
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255 private void writeVendor( XMLWriter writer, MavenProject project )
2256 {
2257 String vendor = DoapUtil.interpolate( doapOptions.getVendor(), project, settings );
2258 if ( StringUtils.isEmpty( vendor ) )
2259 {
2260 return;
2261 }
2262
2263 DoapUtil.writeComment( writer, "Vendor." );
2264 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "vendor", vendor );
2265 }
2266
2267
2268
2269
2270
2271
2272
2273
2274 private void writeLanguage( XMLWriter writer )
2275 {
2276 if ( StringUtils.isEmpty( doapOptions.getLanguage() ) )
2277 {
2278 return;
2279 }
2280
2281 boolean addComment = false;
2282 String[] languages = StringUtils.split( doapOptions.getLanguage(), "," );
2283 for ( String language : languages )
2284 {
2285 language = language.trim();
2286
2287 if ( Arrays.binarySearch( Locale.getISOLanguages(), language ) < 0 )
2288 {
2289 messages.addMessage( new String[] { "doapOptions", "languages" }, language,
2290 UserMessages.INVALID_ISO_DATE );
2291 continue;
2292 }
2293
2294 if ( !addComment )
2295 {
2296 DoapUtil.writeComment( writer, "Language." );
2297 addComment = true;
2298 }
2299 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "language", language );
2300 }
2301 }
2302
2303
2304
2305
2306
2307
2308
2309
2310 private void writeServiceEndpoint( XMLWriter writer )
2311 {
2312 String serviceEndpoint = DoapUtil.interpolate( doapOptions.getServiceEndpoint(), project, settings );
2313 if ( StringUtils.isEmpty( serviceEndpoint ) )
2314 {
2315 return;
2316 }
2317
2318 serviceEndpoint = serviceEndpoint.trim();
2319 try
2320 {
2321 new URL( serviceEndpoint );
2322 }
2323 catch ( MalformedURLException e )
2324 {
2325 messages.addMessage( new String[] { "doapOptions", "serviceEndpoint" }, serviceEndpoint,
2326 UserMessages.INVALID_URL );
2327 return;
2328 }
2329
2330 DoapUtil.writeComment( writer, "Service endpoint." );
2331 DoapUtil.writeRdfResourceElement( writer, doapOptions.getXmlnsPrefix(), "service-endpoint", serviceEndpoint );
2332 }
2333
2334
2335
2336
2337
2338
2339
2340
2341 private void writeImplements( XMLWriter writer )
2342 {
2343 if ( StringUtils.isEmpty( doapOptions.getImplementations() ) )
2344 {
2345 return;
2346 }
2347
2348 DoapUtil.writeComment( writer, "Implements." );
2349 String[] implementations = StringUtils.split( doapOptions.getImplementations(), "," );
2350 for ( String implementation : implementations )
2351 {
2352 DoapUtil.writeElement( writer, doapOptions.getXmlnsPrefix(), "implements", implementation.trim() );
2353 }
2354 }
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366 private void writeExtra( XMLWriter writer, MavenProject project, String comment, Map<String, String> map,
2367 String xmlnsPrefix )
2368 {
2369 if ( map == null || map.isEmpty() )
2370 {
2371 return;
2372 }
2373
2374 boolean addComment = false;
2375 for ( Map.Entry<String, String> entry : map.entrySet() )
2376 {
2377 String key = entry.getKey();
2378 String value = entry.getValue();
2379
2380 if ( value == null )
2381 {
2382 continue;
2383 }
2384
2385 String interpolatedValue = DoapUtil.interpolate( value, project, settings );
2386 if ( interpolatedValue == null )
2387 {
2388 continue;
2389 }
2390
2391 if ( !addComment )
2392 {
2393 DoapUtil.writeComment( writer, comment );
2394 addComment = true;
2395 }
2396
2397 try
2398 {
2399 new URL( interpolatedValue );
2400
2401 DoapUtil.writeRdfResourceElement( writer, xmlnsPrefix, key, interpolatedValue );
2402 }
2403 catch ( MalformedURLException e )
2404 {
2405 DoapUtil.writeElement( writer, xmlnsPrefix, key, interpolatedValue );
2406 }
2407 }
2408 }
2409
2410
2411
2412
2413
2414
2415
2416 private void writeExtensions( XMLWriter writer )
2417 {
2418 if ( !( extOptions != null && extOptions.length > 0 && !extOptions[0].getExtensions().isEmpty() ) )
2419 {
2420 return;
2421 }
2422
2423 for ( ExtOptions extOption : extOptions )
2424 {
2425 @SuppressWarnings( "unchecked" )
2426 Map<String, String> map = extOption.getExtensions();
2427 writeExtra( writer, project, "Other extension vocabulary.", map, extOption.getXmlnsPrefix() );
2428 }
2429 }
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446 private static boolean isScmSystem( ScmRepository scmRepository, String scmProvider )
2447 {
2448 if ( StringUtils.isEmpty( scmProvider ) )
2449 {
2450 return false;
2451 }
2452
2453 if ( scmRepository != null && scmProvider.equalsIgnoreCase( scmRepository.getProvider() ) )
2454 {
2455 return true;
2456 }
2457
2458 return false;
2459 }
2460
2461
2462
2463
2464
2465
2466
2467 @SuppressWarnings( { "unchecked", "rawtypes" } )
2468 private static void sortContributors( List contributors )
2469 {
2470 Collections.sort( contributors, new Comparator<Contributor>()
2471 {
2472 public int compare( Contributor contributor1, Contributor contributor2 )
2473 {
2474 if ( contributor1 == contributor2 )
2475 {
2476 return 0;
2477 }
2478
2479 if ( contributor1 == null && contributor2 != null )
2480 {
2481 return -1;
2482 }
2483 if ( contributor1 != null && contributor2 == null )
2484 {
2485 return +1;
2486 }
2487
2488 if ( Developer.class.isAssignableFrom( contributor1.getClass() )
2489 && Developer.class.isAssignableFrom( contributor2.getClass() ) )
2490 {
2491 Developer developer1 = (Developer) contributor1;
2492 Developer developer2 = (Developer) contributor2;
2493
2494 if ( developer1.getId() == null && developer2.getId() != null )
2495 {
2496 return -1;
2497 }
2498 if ( developer1.getId() != null && developer2.getId() == null )
2499 {
2500 return +1;
2501 }
2502
2503 return developer1.getId().compareTo( developer2.getId() );
2504 }
2505
2506 if ( contributor1.getName() == null && contributor2.getName() != null )
2507 {
2508 return -1;
2509 }
2510 if ( contributor1.getName() != null && contributor2.getName() == null )
2511 {
2512 return +1;
2513 }
2514 return contributor1.getName().compareTo( contributor2.getName() );
2515 }
2516 } );
2517 }
2518
2519
2520
2521
2522
2523
2524 private class UserMessages
2525 {
2526 public static final int REQUIRED = 10;
2527
2528 public static final int REQUIRED_BY_ASF_OR_RECOMMENDED = 11;
2529
2530 public static final int REQUIRED_BY_ASF = 12;
2531
2532 public static final int RECOMMENDED = 20;
2533
2534 public static final int INVALID_URL = 30;
2535
2536 public static final int INVALID_DATE = 31;
2537
2538 public static final int INVALID_ISO_DATE = 32;
2539
2540 public static final int INVALID_EMAIL = 33;
2541
2542 private List<String> errorMessages = new ArrayList<String>();
2543
2544 private List<String> warnMessages = new ArrayList<String>();
2545
2546
2547
2548
2549 public List<String> getErrorMessages()
2550 {
2551 return errorMessages;
2552 }
2553
2554
2555
2556
2557 public List<String> getWarnMessages()
2558 {
2559 return warnMessages;
2560 }
2561
2562
2563
2564
2565
2566
2567 protected void addMessage( String[] tags, String value, int errorId )
2568 {
2569 if ( tags == null )
2570 {
2571 throw new IllegalArgumentException( "tags is required" );
2572 }
2573
2574 boolean isPom = false;
2575 if ( tags[0].equalsIgnoreCase( "project" ) )
2576 {
2577 isPom = true;
2578 }
2579 switch ( errorId )
2580 {
2581 case REQUIRED:
2582 errorMessages.add( "A " + toConfiguration( tags, null ) + " parameter is required." );
2583 break;
2584 case REQUIRED_BY_ASF_OR_RECOMMENDED:
2585 if ( isPom )
2586 {
2587 if ( asfExtOptions.isIncluded() )
2588 {
2589 errorMessages.add( "A POM " + toConfiguration( tags, null ) + " value is required by ASF." );
2590 }
2591 else
2592 {
2593 warnMessages.add( "No POM " + toConfiguration( tags, null )
2594 + " value is defined, it is highly recommended to have one." );
2595 }
2596 }
2597 else
2598 {
2599 if ( asfExtOptions.isIncluded() )
2600 {
2601 errorMessages.add( "A " + toConfiguration( tags, null ) + " parameter is required by ASF." );
2602 }
2603 else
2604 {
2605 warnMessages.add( "No " + toConfiguration( tags, null )
2606 + " parameter defined, it is highly recommended to have one." );
2607 }
2608 }
2609 break;
2610 case REQUIRED_BY_ASF:
2611 if ( isPom )
2612 {
2613 errorMessages.add( "A POM " + toConfiguration( tags, null ) + " value is required by ASF." );
2614 }
2615 else
2616 {
2617 errorMessages.add( "A " + toConfiguration( tags, null ) + " parameter is required by ASF." );
2618 }
2619 break;
2620 case RECOMMENDED:
2621 warnMessages.add( "No " + toConfiguration( tags, null )
2622 + " parameter defined, it is highly recommended to have one." );
2623 break;
2624 case INVALID_URL:
2625 if ( isPom )
2626 {
2627 errorMessages.add( "The POM " + toConfiguration( tags, value ) + " value is not a valid URL." );
2628 }
2629 else
2630 {
2631 errorMessages.add( "The " + toConfiguration( tags, value ) + " parameter is not a valid URL." );
2632 }
2633 break;
2634 case INVALID_DATE:
2635 errorMessages.add( "The " + toConfiguration( tags, value ) + " parameter should be in YYYY-MM-DD." );
2636 break;
2637 case INVALID_EMAIL:
2638 errorMessages.add( "The POM " + toConfiguration( tags, value ) + " value is not a valid email." );
2639 break;
2640 case INVALID_ISO_DATE:
2641 errorMessages.add( "The " + toConfiguration( tags, value )
2642 + " parameter is not a valid ISO language." );
2643 break;
2644 default:
2645 throw new IllegalArgumentException( "Unknown errorId=" + errorId );
2646 }
2647 }
2648
2649
2650
2651
2652
2653
2654 protected String toConfiguration( String[] tags, String value )
2655 {
2656 if ( tags == null )
2657 {
2658 throw new IllegalArgumentException( "tags is required" );
2659 }
2660
2661 StringBuffer sb = new StringBuffer();
2662 for ( int i = 0; i < tags.length; i++ )
2663 {
2664 if ( i == tags.length - 1 && StringUtils.isEmpty( value ) )
2665 {
2666 sb.append( "<" ).append( tags[i] ).append( "/>" );
2667 }
2668 else
2669 {
2670 sb.append( "<" ).append( tags[i] ).append( ">" );
2671 }
2672 }
2673 if ( StringUtils.isNotEmpty( value ) )
2674 {
2675 sb.append( value );
2676 }
2677 for ( int i = tags.length - 1; i >= 0; i-- )
2678 {
2679 if ( !( i == tags.length - 1 && StringUtils.isEmpty( value ) ) )
2680 {
2681 sb.append( "</" ).append( tags[i] ).append( ">" );
2682 }
2683 }
2684
2685 return sb.toString();
2686 }
2687 }
2688 }