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