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