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