1
2
3
4
5
6 package org.apache.maven.plugin.tools.model.io.xpp3;
7
8
9
10
11
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.io.Reader;
15 import java.text.DateFormat;
16 import org.apache.maven.plugin.tools.model.Component;
17 import org.apache.maven.plugin.tools.model.LifecycleExecution;
18 import org.apache.maven.plugin.tools.model.Mojo;
19 import org.apache.maven.plugin.tools.model.Parameter;
20 import org.apache.maven.plugin.tools.model.PluginMetadata;
21 import org.codehaus.plexus.util.ReaderFactory;
22 import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
23 import org.codehaus.plexus.util.xml.pull.MXParser;
24 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
25 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
26
27
28
29
30
31
32 @SuppressWarnings( "all" )
33 public class PluginMetadataXpp3Reader
34 {
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 private boolean addDefaultEntities = true;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 private boolean checkFieldWithDuplicate( XmlPullParser parser, String tagName, String alias, java.util.Set parsed )
68 throws XmlPullParserException
69 {
70 if ( !( parser.getName().equals( tagName ) || parser.getName().equals( alias ) ) )
71 {
72 return false;
73 }
74 if ( !parsed.add( tagName ) )
75 {
76 throw new XmlPullParserException( "Duplicated tag: '" + tagName + "'", parser, null );
77 }
78 return true;
79 }
80
81
82
83
84
85
86
87
88
89
90
91 private void checkUnknownAttribute( XmlPullParser parser, String attribute, String tagName, boolean strict )
92 throws XmlPullParserException, IOException
93 {
94
95 if ( strict )
96 {
97 throw new XmlPullParserException( "Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser, null );
98 }
99 }
100
101
102
103
104
105
106
107
108
109 private void checkUnknownElement( XmlPullParser parser, boolean strict )
110 throws XmlPullParserException, IOException
111 {
112 if ( strict )
113 {
114 throw new XmlPullParserException( "Unrecognised tag: '" + parser.getName() + "'", parser, null );
115 }
116
117 for ( int unrecognizedTagCount = 1; unrecognizedTagCount > 0; )
118 {
119 int eventType = parser.next();
120 if ( eventType == XmlPullParser.START_TAG )
121 {
122 unrecognizedTagCount++;
123 }
124 else if ( eventType == XmlPullParser.END_TAG )
125 {
126 unrecognizedTagCount--;
127 }
128 }
129 }
130
131
132
133
134
135
136 public boolean getAddDefaultEntities()
137 {
138 return addDefaultEntities;
139 }
140
141
142
143
144
145
146
147
148
149
150 private boolean getBooleanValue( String s, String attribute, XmlPullParser parser )
151 throws XmlPullParserException
152 {
153 return getBooleanValue( s, attribute, parser, null );
154 }
155
156
157
158
159
160
161
162
163
164
165
166 private boolean getBooleanValue( String s, String attribute, XmlPullParser parser, String defaultValue )
167 throws XmlPullParserException
168 {
169 if ( s != null && s.length() != 0 )
170 {
171 return Boolean.valueOf( s ).booleanValue();
172 }
173 if ( defaultValue != null )
174 {
175 return Boolean.valueOf( defaultValue ).booleanValue();
176 }
177 return false;
178 }
179
180
181
182
183
184
185
186
187
188
189
190 private byte getByteValue( String s, String attribute, XmlPullParser parser, boolean strict )
191 throws XmlPullParserException
192 {
193 if ( s != null )
194 {
195 try
196 {
197 return Byte.valueOf( s ).byteValue();
198 }
199 catch ( NumberFormatException nfe )
200 {
201 if ( strict )
202 {
203 throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a byte", parser, nfe );
204 }
205 }
206 }
207 return 0;
208 }
209
210
211
212
213
214
215
216
217
218
219 private char getCharacterValue( String s, String attribute, XmlPullParser parser )
220 throws XmlPullParserException
221 {
222 if ( s != null )
223 {
224 return s.charAt( 0 );
225 }
226 return 0;
227 }
228
229
230
231
232
233
234
235
236
237
238 private java.util.Date getDateValue( String s, String attribute, XmlPullParser parser )
239 throws XmlPullParserException
240 {
241 return getDateValue( s, attribute, null, parser );
242 }
243
244
245
246
247
248
249
250
251
252
253
254 private java.util.Date getDateValue( String s, String attribute, String dateFormat, XmlPullParser parser )
255 throws XmlPullParserException
256 {
257 if ( s != null )
258 {
259 String effectiveDateFormat = dateFormat;
260 if ( dateFormat == null )
261 {
262 effectiveDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS";
263 }
264 if ( "long".equals( effectiveDateFormat ) )
265 {
266 try
267 {
268 return new java.util.Date( Long.parseLong( s ) );
269 }
270 catch ( NumberFormatException e )
271 {
272 throw new XmlPullParserException( e.getMessage(), parser, e );
273 }
274 }
275 else
276 {
277 try
278 {
279 DateFormat dateParser = new java.text.SimpleDateFormat( effectiveDateFormat, java.util.Locale.US );
280 return dateParser.parse( s );
281 }
282 catch ( java.text.ParseException e )
283 {
284 throw new XmlPullParserException( e.getMessage(), parser, e );
285 }
286 }
287 }
288 return null;
289 }
290
291
292
293
294
295
296
297
298
299
300
301 private double getDoubleValue( String s, String attribute, XmlPullParser parser, boolean strict )
302 throws XmlPullParserException
303 {
304 if ( s != null )
305 {
306 try
307 {
308 return Double.valueOf( s ).doubleValue();
309 }
310 catch ( NumberFormatException nfe )
311 {
312 if ( strict )
313 {
314 throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
315 }
316 }
317 }
318 return 0;
319 }
320
321
322
323
324
325
326
327
328
329
330
331 private float getFloatValue( String s, String attribute, XmlPullParser parser, boolean strict )
332 throws XmlPullParserException
333 {
334 if ( s != null )
335 {
336 try
337 {
338 return Float.valueOf( s ).floatValue();
339 }
340 catch ( NumberFormatException nfe )
341 {
342 if ( strict )
343 {
344 throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
345 }
346 }
347 }
348 return 0;
349 }
350
351
352
353
354
355
356
357
358
359
360
361 private int getIntegerValue( String s, String attribute, XmlPullParser parser, boolean strict )
362 throws XmlPullParserException
363 {
364 if ( s != null )
365 {
366 try
367 {
368 return Integer.valueOf( s ).intValue();
369 }
370 catch ( NumberFormatException nfe )
371 {
372 if ( strict )
373 {
374 throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be an integer", parser, nfe );
375 }
376 }
377 }
378 return 0;
379 }
380
381
382
383
384
385
386
387
388
389
390
391 private long getLongValue( String s, String attribute, XmlPullParser parser, boolean strict )
392 throws XmlPullParserException
393 {
394 if ( s != null )
395 {
396 try
397 {
398 return Long.valueOf( s ).longValue();
399 }
400 catch ( NumberFormatException nfe )
401 {
402 if ( strict )
403 {
404 throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a long integer", parser, nfe );
405 }
406 }
407 }
408 return 0;
409 }
410
411
412
413
414
415
416
417
418
419
420
421 private String getRequiredAttributeValue( String s, String attribute, XmlPullParser parser, boolean strict )
422 throws XmlPullParserException
423 {
424 if ( s == null )
425 {
426 if ( strict )
427 {
428 throw new XmlPullParserException( "Missing required value for attribute '" + attribute + "'", parser, null );
429 }
430 }
431 return s;
432 }
433
434
435
436
437
438
439
440
441
442
443
444 private short getShortValue( String s, String attribute, XmlPullParser parser, boolean strict )
445 throws XmlPullParserException
446 {
447 if ( s != null )
448 {
449 try
450 {
451 return Short.valueOf( s ).shortValue();
452 }
453 catch ( NumberFormatException nfe )
454 {
455 if ( strict )
456 {
457 throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a short integer", parser, nfe );
458 }
459 }
460 }
461 return 0;
462 }
463
464
465
466
467
468
469
470 private String getTrimmedValue( String s )
471 {
472 if ( s != null )
473 {
474 s = s.trim();
475 }
476 return s;
477 }
478
479
480
481
482
483
484
485
486
487 private int nextTag( XmlPullParser parser )
488 throws IOException, XmlPullParserException
489 {
490 int eventType = parser.next();
491 if ( eventType == XmlPullParser.TEXT )
492 {
493 eventType = parser.next();
494 }
495 if ( eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_TAG )
496 {
497 throw new XmlPullParserException( "expected START_TAG or END_TAG not " + XmlPullParser.TYPES[eventType], parser, null );
498 }
499 return eventType;
500 }
501
502
503
504
505
506
507
508
509
510
511 public PluginMetadata read( Reader reader, boolean strict )
512 throws IOException, XmlPullParserException
513 {
514 XmlPullParser parser = addDefaultEntities ? new MXParser(EntityReplacementMap.defaultEntityReplacementMap) : new MXParser( );
515
516 parser.setInput( reader );
517
518
519 return read( parser, strict );
520 }
521
522
523
524
525
526
527
528
529
530 public PluginMetadata read( Reader reader )
531 throws IOException, XmlPullParserException
532 {
533 return read( reader, true );
534 }
535
536
537
538
539
540
541
542
543
544
545 public PluginMetadata read( InputStream in, boolean strict )
546 throws IOException, XmlPullParserException
547 {
548 return read( ReaderFactory.newXmlReader( in ), strict );
549 }
550
551
552
553
554
555
556
557
558
559 public PluginMetadata read( InputStream in )
560 throws IOException, XmlPullParserException
561 {
562 return read( ReaderFactory.newXmlReader( in ) );
563 }
564
565
566
567
568
569
570
571
572
573
574 private Component parseComponent( XmlPullParser parser, boolean strict )
575 throws IOException, XmlPullParserException
576 {
577 String tagName = parser.getName();
578 Component component = new Component();
579 for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
580 {
581 String name = parser.getAttributeName( i );
582 String value = parser.getAttributeValue( i );
583
584 if ( name.indexOf( ':' ) >= 0 )
585 {
586
587 }
588 else
589 {
590 checkUnknownAttribute( parser, name, tagName, strict );
591 }
592 }
593 java.util.Set parsed = new java.util.HashSet();
594 while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
595 {
596 if ( checkFieldWithDuplicate( parser, "role", null, parsed ) )
597 {
598 component.setRole( getTrimmedValue( parser.nextText() ) );
599 }
600 else if ( checkFieldWithDuplicate( parser, "hint", null, parsed ) )
601 {
602 component.setHint( getTrimmedValue( parser.nextText() ) );
603 }
604 else
605 {
606 checkUnknownElement( parser, strict );
607 }
608 }
609 return component;
610 }
611
612
613
614
615
616
617
618
619
620
621 private LifecycleExecution parseLifecycleExecution( XmlPullParser parser, boolean strict )
622 throws IOException, XmlPullParserException
623 {
624 String tagName = parser.getName();
625 LifecycleExecution lifecycleExecution = new LifecycleExecution();
626 for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
627 {
628 String name = parser.getAttributeName( i );
629 String value = parser.getAttributeValue( i );
630
631 if ( name.indexOf( ':' ) >= 0 )
632 {
633
634 }
635 else
636 {
637 checkUnknownAttribute( parser, name, tagName, strict );
638 }
639 }
640 java.util.Set parsed = new java.util.HashSet();
641 while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
642 {
643 if ( checkFieldWithDuplicate( parser, "lifecycle", null, parsed ) )
644 {
645 lifecycleExecution.setLifecycle( getTrimmedValue( parser.nextText() ) );
646 }
647 else if ( checkFieldWithDuplicate( parser, "phase", null, parsed ) )
648 {
649 lifecycleExecution.setPhase( getTrimmedValue( parser.nextText() ) );
650 }
651 else if ( checkFieldWithDuplicate( parser, "goal", null, parsed ) )
652 {
653 lifecycleExecution.setGoal( getTrimmedValue( parser.nextText() ) );
654 }
655 else
656 {
657 checkUnknownElement( parser, strict );
658 }
659 }
660 return lifecycleExecution;
661 }
662
663
664
665
666
667
668
669
670
671
672 private Mojo parseMojo( XmlPullParser parser, boolean strict )
673 throws IOException, XmlPullParserException
674 {
675 String tagName = parser.getName();
676 Mojo mojo = new Mojo();
677 for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
678 {
679 String name = parser.getAttributeName( i );
680 String value = parser.getAttributeValue( i );
681
682 if ( name.indexOf( ':' ) >= 0 )
683 {
684
685 }
686 else
687 {
688 checkUnknownAttribute( parser, name, tagName, strict );
689 }
690 }
691 java.util.Set parsed = new java.util.HashSet();
692 while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
693 {
694 if ( checkFieldWithDuplicate( parser, "goal", null, parsed ) )
695 {
696 mojo.setGoal( getTrimmedValue( parser.nextText() ) );
697 }
698 else if ( checkFieldWithDuplicate( parser, "phase", null, parsed ) )
699 {
700 mojo.setPhase( getTrimmedValue( parser.nextText() ) );
701 }
702 else if ( checkFieldWithDuplicate( parser, "aggregator", null, parsed ) )
703 {
704 mojo.setAggregator( getBooleanValue( getTrimmedValue( parser.nextText() ), "aggregator", parser, "false" ) );
705 }
706 else if ( checkFieldWithDuplicate( parser, "requiresDependencyResolution", null, parsed ) )
707 {
708 mojo.setRequiresDependencyResolution( getTrimmedValue( parser.nextText() ) );
709 }
710 else if ( checkFieldWithDuplicate( parser, "requiresProject", null, parsed ) )
711 {
712 mojo.setRequiresProject( getBooleanValue( getTrimmedValue( parser.nextText() ), "requiresProject", parser, "false" ) );
713 }
714 else if ( checkFieldWithDuplicate( parser, "requiresReports", null, parsed ) )
715 {
716 mojo.setRequiresReports( getBooleanValue( getTrimmedValue( parser.nextText() ), "requiresReports", parser, "false" ) );
717 }
718 else if ( checkFieldWithDuplicate( parser, "requiresOnline", null, parsed ) )
719 {
720 mojo.setRequiresOnline( getBooleanValue( getTrimmedValue( parser.nextText() ), "requiresOnline", parser, "false" ) );
721 }
722 else if ( checkFieldWithDuplicate( parser, "inheritByDefault", null, parsed ) )
723 {
724 mojo.setInheritByDefault( getBooleanValue( getTrimmedValue( parser.nextText() ), "inheritByDefault", parser, "false" ) );
725 }
726 else if ( checkFieldWithDuplicate( parser, "requiresDirectInvocation", null, parsed ) )
727 {
728 mojo.setRequiresDirectInvocation( getBooleanValue( getTrimmedValue( parser.nextText() ), "requiresDirectInvocation", parser, "false" ) );
729 }
730 else if ( checkFieldWithDuplicate( parser, "execution", null, parsed ) )
731 {
732 mojo.setExecution( parseLifecycleExecution( parser, strict ) );
733 }
734 else if ( checkFieldWithDuplicate( parser, "components", null, parsed ) )
735 {
736 java.util.List components = new java.util.ArrayList();
737 mojo.setComponents( components );
738 while ( parser.nextTag() == XmlPullParser.START_TAG )
739 {
740 if ( "component".equals( parser.getName() ) )
741 {
742 components.add( parseComponent( parser, strict ) );
743 }
744 else
745 {
746 checkUnknownElement( parser, strict );
747 }
748 }
749 }
750 else if ( checkFieldWithDuplicate( parser, "parameters", null, parsed ) )
751 {
752 java.util.List parameters = new java.util.ArrayList();
753 mojo.setParameters( parameters );
754 while ( parser.nextTag() == XmlPullParser.START_TAG )
755 {
756 if ( "parameter".equals( parser.getName() ) )
757 {
758 parameters.add( parseParameter( parser, strict ) );
759 }
760 else
761 {
762 checkUnknownElement( parser, strict );
763 }
764 }
765 }
766 else if ( checkFieldWithDuplicate( parser, "description", null, parsed ) )
767 {
768 mojo.setDescription( getTrimmedValue( parser.nextText() ) );
769 }
770 else if ( checkFieldWithDuplicate( parser, "deprecated", null, parsed ) )
771 {
772 mojo.setDeprecation( getTrimmedValue( parser.nextText() ) );
773 }
774 else if ( checkFieldWithDuplicate( parser, "since", null, parsed ) )
775 {
776 mojo.setSince( getTrimmedValue( parser.nextText() ) );
777 }
778 else if ( checkFieldWithDuplicate( parser, "call", null, parsed ) )
779 {
780 mojo.setCall( getTrimmedValue( parser.nextText() ) );
781 }
782 else
783 {
784 checkUnknownElement( parser, strict );
785 }
786 }
787 return mojo;
788 }
789
790
791
792
793
794
795
796
797
798
799 private Parameter parseParameter( XmlPullParser parser, boolean strict )
800 throws IOException, XmlPullParserException
801 {
802 String tagName = parser.getName();
803 Parameter parameter = new Parameter();
804 for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
805 {
806 String name = parser.getAttributeName( i );
807 String value = parser.getAttributeValue( i );
808
809 if ( name.indexOf( ':' ) >= 0 )
810 {
811
812 }
813 else
814 {
815 checkUnknownAttribute( parser, name, tagName, strict );
816 }
817 }
818 java.util.Set parsed = new java.util.HashSet();
819 while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
820 {
821 if ( checkFieldWithDuplicate( parser, "name", null, parsed ) )
822 {
823 parameter.setName( getTrimmedValue( parser.nextText() ) );
824 }
825 else if ( checkFieldWithDuplicate( parser, "alias", null, parsed ) )
826 {
827 parameter.setAlias( getTrimmedValue( parser.nextText() ) );
828 }
829 else if ( checkFieldWithDuplicate( parser, "property", null, parsed ) )
830 {
831 parameter.setProperty( getTrimmedValue( parser.nextText() ) );
832 }
833 else if ( checkFieldWithDuplicate( parser, "required", null, parsed ) )
834 {
835 parameter.setRequired( getBooleanValue( getTrimmedValue( parser.nextText() ), "required", parser, "false" ) );
836 }
837 else if ( checkFieldWithDuplicate( parser, "readonly", null, parsed ) )
838 {
839 parameter.setReadonly( getBooleanValue( getTrimmedValue( parser.nextText() ), "readonly", parser, "false" ) );
840 }
841 else if ( checkFieldWithDuplicate( parser, "expression", null, parsed ) )
842 {
843 parameter.setExpression( getTrimmedValue( parser.nextText() ) );
844 }
845 else if ( checkFieldWithDuplicate( parser, "defaultValue", null, parsed ) )
846 {
847 parameter.setDefaultValue( getTrimmedValue( parser.nextText() ) );
848 }
849 else if ( checkFieldWithDuplicate( parser, "type", null, parsed ) )
850 {
851 parameter.setType( getTrimmedValue( parser.nextText() ) );
852 }
853 else if ( checkFieldWithDuplicate( parser, "description", null, parsed ) )
854 {
855 parameter.setDescription( getTrimmedValue( parser.nextText() ) );
856 }
857 else if ( checkFieldWithDuplicate( parser, "deprecated", null, parsed ) )
858 {
859 parameter.setDeprecation( getTrimmedValue( parser.nextText() ) );
860 }
861 else if ( checkFieldWithDuplicate( parser, "since", null, parsed ) )
862 {
863 parameter.setSince( getTrimmedValue( parser.nextText() ) );
864 }
865 else
866 {
867 checkUnknownElement( parser, strict );
868 }
869 }
870 return parameter;
871 }
872
873
874
875
876
877
878
879
880
881
882 private PluginMetadata parsePluginMetadata( XmlPullParser parser, boolean strict )
883 throws IOException, XmlPullParserException
884 {
885 String tagName = parser.getName();
886 PluginMetadata pluginMetadata = new PluginMetadata();
887 for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
888 {
889 String name = parser.getAttributeName( i );
890 String value = parser.getAttributeValue( i );
891
892 if ( name.indexOf( ':' ) >= 0 )
893 {
894
895 }
896 else if ( "xmlns".equals( name ) )
897 {
898
899 }
900 else
901 {
902 checkUnknownAttribute( parser, name, tagName, strict );
903 }
904 }
905 java.util.Set parsed = new java.util.HashSet();
906 while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
907 {
908 if ( checkFieldWithDuplicate( parser, "mojos", null, parsed ) )
909 {
910 java.util.List mojos = new java.util.ArrayList();
911 pluginMetadata.setMojos( mojos );
912 while ( parser.nextTag() == XmlPullParser.START_TAG )
913 {
914 if ( "mojo".equals( parser.getName() ) )
915 {
916 mojos.add( parseMojo( parser, strict ) );
917 }
918 else
919 {
920 checkUnknownElement( parser, strict );
921 }
922 }
923 }
924 else
925 {
926 checkUnknownElement( parser, strict );
927 }
928 }
929 return pluginMetadata;
930 }
931
932
933
934
935
936
937
938
939
940
941 private PluginMetadata read( XmlPullParser parser, boolean strict )
942 throws IOException, XmlPullParserException
943 {
944 int eventType = parser.getEventType();
945 while ( eventType != XmlPullParser.END_DOCUMENT )
946 {
947 if ( eventType == XmlPullParser.START_TAG )
948 {
949 if ( strict && ! "pluginMetadata".equals( parser.getName() ) )
950 {
951 throw new XmlPullParserException( "Expected root element 'pluginMetadata' but found '" + parser.getName() + "'", parser, null );
952 }
953 PluginMetadata pluginMetadata = parsePluginMetadata( parser, strict );
954 pluginMetadata.setModelEncoding( parser.getInputEncoding() );
955 return pluginMetadata;
956 }
957 eventType = parser.next();
958 }
959 throw new XmlPullParserException( "Expected root element 'pluginMetadata' but found no element at all: invalid XML document", parser, null );
960 }
961
962
963
964
965
966
967 public void setAddDefaultEntities( boolean addDefaultEntities )
968 {
969 this.addDefaultEntities = addDefaultEntities;
970 }
971
972 }