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