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