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