1
2
3
4
5
6
7
8 package org.codehaus.plexus.security.user.jdo.v0_9_0.io.stax;
9
10
11
12
13
14 import java.io.ByteArrayInputStream;
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.InputStreamReader;
19 import java.io.Reader;
20 import java.io.StringReader;
21 import java.io.StringWriter;
22 import java.text.DateFormat;
23 import java.text.ParsePosition;
24 import java.util.Locale;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27 import javax.xml.stream.*;
28 import org.codehaus.plexus.security.user.jdo.v0_9_0.JdoUser;
29 import org.codehaus.plexus.security.user.jdo.v0_9_0.UserDatabase;
30 import org.codehaus.plexus.util.xml.Xpp3Dom;
31
32
33
34
35
36
37 public class UserManagementStaxReader
38 {
39
40
41
42
43
44
45
46
47
48
49
50
51 private Xpp3Dom buildDom( XMLStreamReader xmlStreamReader )
52 throws XMLStreamException
53 {
54 java.util.List elements = new java.util.ArrayList();
55 java.util.List values = new java.util.ArrayList();
56 int eventType = xmlStreamReader.getEventType();
57 while ( xmlStreamReader.hasNext() )
58 {
59 if ( eventType == XMLStreamConstants.START_ELEMENT )
60 {
61 String rawName = xmlStreamReader.getLocalName();
62 Xpp3Dom childConfiguration = new Xpp3Dom( rawName );
63 int depth = elements.size();
64 if ( depth > 0 )
65 {
66 Xpp3Dom parent = (Xpp3Dom) elements.get( depth - 1 );
67 parent.addChild( childConfiguration );
68 }
69 elements.add( childConfiguration );
70 if ( xmlStreamReader.isEndElement() )
71 {
72 values.add( null );
73 }
74 else
75 {
76 values.add( new StringBuffer() );
77 }
78 int attributesSize = xmlStreamReader.getAttributeCount();
79 for ( int i = 0; i < attributesSize; i++ )
80 {
81 String name = xmlStreamReader.getAttributeLocalName( i );
82 String value = xmlStreamReader.getAttributeValue( i );
83 childConfiguration.setAttribute( name, value );
84 }
85 }
86 else if ( eventType == XMLStreamConstants.CHARACTERS )
87 {
88 int depth = values.size() - 1;
89 StringBuffer valueBuffer = (StringBuffer) values.get( depth );
90 String text = xmlStreamReader.getText();
91 text = text.trim();
92 valueBuffer.append( text );
93 }
94 else if ( eventType == XMLStreamConstants.END_ELEMENT )
95 {
96 int depth = elements.size() - 1;
97 Xpp3Dom finishedConfiguration = (Xpp3Dom) elements.remove( depth );
98
99 Object accumulatedValue = values.remove( depth );
100 if ( finishedConfiguration.getChildCount() == 0 )
101 {
102 if ( accumulatedValue == null )
103 {
104 finishedConfiguration.setValue( null );
105 }
106 else
107 {
108 finishedConfiguration.setValue( accumulatedValue.toString() );
109 }
110 }
111 if ( depth == 0 )
112 {
113 return finishedConfiguration;
114 }
115 }
116 eventType = xmlStreamReader.next();
117 }
118 throw new IllegalStateException( "End of document found before returning to 0 depth" );
119 }
120
121
122
123
124
125
126
127
128
129
130
131 private boolean checkFieldWithDuplicate( XMLStreamReader xmlStreamReader, String tagName, String alias, java.util.Set parsed )
132 throws XMLStreamException
133 {
134 if ( !( xmlStreamReader.getLocalName().equals( tagName ) || xmlStreamReader.getLocalName().equals( alias ) ) )
135 {
136 return false;
137 }
138 if ( parsed.contains( tagName ) )
139 {
140 throw new XMLStreamException( "Duplicated tag: '" + tagName + "'", xmlStreamReader.getLocation() );
141 }
142 parsed.add( tagName );
143 return true;
144 }
145
146
147
148
149
150
151
152
153
154
155 private boolean getBooleanValue( String s, String attribute, XMLStreamReader xmlStreamReader )
156 throws XMLStreamException
157 {
158 if ( s != null )
159 {
160 return Boolean.valueOf( s ).booleanValue();
161 }
162 return false;
163 }
164
165
166
167
168
169
170
171
172
173
174
175 private byte getByteValue( String s, String attribute, XMLStreamReader xmlStreamReader, boolean strict )
176 throws XMLStreamException
177 {
178 if ( s != null )
179 {
180 try
181 {
182 return Byte.valueOf( s ).byteValue();
183 }
184 catch ( NumberFormatException e )
185 {
186 if ( strict )
187 {
188 throw new XMLStreamException( "Unable to parse element '" + attribute + "', must be a byte but was '" + s + "'", xmlStreamReader.getLocation() );
189 }
190 }
191 }
192 return 0;
193 }
194
195
196
197
198
199
200
201
202
203
204 private char getCharacterValue( String s, String attribute, XMLStreamReader xmlStreamReader )
205 throws XMLStreamException
206 {
207 if ( s != null )
208 {
209 return s.charAt( 0 );
210 }
211 return 0;
212 }
213
214
215
216
217
218
219
220
221
222
223
224 private java.util.Date getDateValue( String s, String attribute, String dateFormat, XMLStreamReader xmlStreamReader )
225 throws XMLStreamException
226 {
227 if ( s != null )
228 {
229 String effectiveDateFormat = dateFormat;
230 if ( dateFormat == null )
231 {
232 effectiveDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS";
233 }
234 if ( "long".equals( effectiveDateFormat ) )
235 {
236 try
237 {
238 return new java.util.Date( Long.parseLong( s ) );
239 }
240 catch ( NumberFormatException e )
241 {
242 throw new XMLStreamException( e.getMessage() );
243 }
244 }
245 else
246 {
247 try
248 {
249 DateFormat dateParser = new java.text.SimpleDateFormat( effectiveDateFormat, Locale.US );
250 return dateParser.parse( s );
251 }
252 catch ( java.text.ParseException e )
253 {
254 throw new XMLStreamException( e.getMessage() );
255 }
256 }
257 }
258 return null;
259 }
260
261
262
263
264
265
266
267
268 private String getDefaultValue( String s, String v )
269 {
270 if ( s == null )
271 {
272 s = v;
273 }
274 return s;
275 }
276
277
278
279
280
281
282
283
284
285
286
287 private double getDoubleValue( String s, String attribute, XMLStreamReader xmlStreamReader, boolean strict )
288 throws XMLStreamException
289 {
290 if ( s != null )
291 {
292 try
293 {
294 return Double.valueOf( s ).doubleValue();
295 }
296 catch ( NumberFormatException e )
297 {
298 if ( strict )
299 {
300 throw new XMLStreamException( "Unable to parse element '" + attribute + "', must be a floating point number but was '" + s + "'", xmlStreamReader.getLocation() );
301 }
302 }
303 }
304 return 0;
305 }
306
307
308
309
310
311
312
313
314
315
316
317 private float getFloatValue( String s, String attribute, XMLStreamReader xmlStreamReader, boolean strict )
318 throws XMLStreamException
319 {
320 if ( s != null )
321 {
322 try
323 {
324 return Float.valueOf( s ).floatValue();
325 }
326 catch ( NumberFormatException e )
327 {
328 if ( strict )
329 {
330 throw new XMLStreamException( "Unable to parse element '" + attribute + "', must be a floating point number but was '" + s + "'", xmlStreamReader.getLocation() );
331 }
332 }
333 }
334 return 0;
335 }
336
337
338
339
340
341
342
343
344
345
346
347 private int getIntegerValue( String s, String attribute, XMLStreamReader xmlStreamReader, boolean strict )
348 throws XMLStreamException
349 {
350 if ( s != null )
351 {
352 try
353 {
354 return Integer.valueOf( s ).intValue();
355 }
356 catch ( NumberFormatException e )
357 {
358 if ( strict )
359 {
360 throw new XMLStreamException( "Unable to parse element '" + attribute + "', must be an integer but was '" + s + "'", xmlStreamReader.getLocation() );
361 }
362 }
363 }
364 return 0;
365 }
366
367
368
369
370
371
372
373
374
375
376
377 private long getLongValue( String s, String attribute, XMLStreamReader xmlStreamReader, boolean strict )
378 throws XMLStreamException
379 {
380 if ( s != null )
381 {
382 try
383 {
384 return Long.valueOf( s ).longValue();
385 }
386 catch ( NumberFormatException e )
387 {
388 if ( strict )
389 {
390 throw new XMLStreamException( "Unable to parse element '" + attribute + "', must be a long integer but was '" + s + "'", xmlStreamReader.getLocation() );
391 }
392 }
393 }
394 return 0;
395 }
396
397
398
399
400
401
402
403
404
405
406
407 private String getRequiredAttributeValue( String s, String attribute, XMLStreamReader xmlStreamReader, boolean strict )
408 throws XMLStreamException
409 {
410 if ( s == null )
411 {
412 if ( strict )
413 {
414 throw new XMLStreamException( "Missing required value for attribute '" + attribute + "'", xmlStreamReader.getLocation() );
415 }
416 }
417 return s;
418 }
419
420
421
422
423
424
425
426
427
428
429
430 private short getShortValue( String s, String attribute, XMLStreamReader xmlStreamReader, boolean strict )
431 throws XMLStreamException
432 {
433 if ( s != null )
434 {
435 try
436 {
437 return Short.valueOf( s ).shortValue();
438 }
439 catch ( NumberFormatException e )
440 {
441 if ( strict )
442 {
443 throw new XMLStreamException( "Unable to parse element '" + attribute + "', must be a short integer but was '" + s + "'", xmlStreamReader.getLocation() );
444 }
445 }
446 }
447 return 0;
448 }
449
450
451
452
453
454
455
456 private String getTrimmedValue( String s )
457 {
458 if ( s != null )
459 {
460 s = s.trim();
461 }
462 return s;
463 }
464
465
466
467
468
469
470
471
472
473
474
475
476 private JdoUser parseJdoUser( String tagName, XMLStreamReader xmlStreamReader, boolean strict, String encoding )
477 throws IOException, XMLStreamException
478 {
479 JdoUser jdoUser = new JdoUser();
480 java.util.Set parsed = new java.util.HashSet();
481 while ( xmlStreamReader.nextTag() == XMLStreamConstants.START_ELEMENT )
482 {
483 if ( checkFieldWithDuplicate( xmlStreamReader, "username", null, parsed ) )
484 {
485 jdoUser.setUsername( getTrimmedValue( xmlStreamReader.getElementText() ) );
486 }
487 else if ( checkFieldWithDuplicate( xmlStreamReader, "password", null, parsed ) )
488 {
489 jdoUser.setPassword( getTrimmedValue( xmlStreamReader.getElementText() ) );
490 }
491 else if ( checkFieldWithDuplicate( xmlStreamReader, "encodedPassword", null, parsed ) )
492 {
493 jdoUser.setEncodedPassword( getTrimmedValue( xmlStreamReader.getElementText() ) );
494 }
495 else if ( checkFieldWithDuplicate( xmlStreamReader, "fullName", null, parsed ) )
496 {
497 jdoUser.setFullName( getTrimmedValue( xmlStreamReader.getElementText() ) );
498 }
499 else if ( checkFieldWithDuplicate( xmlStreamReader, "email", null, parsed ) )
500 {
501 jdoUser.setEmail( getTrimmedValue( xmlStreamReader.getElementText() ) );
502 }
503 else if ( checkFieldWithDuplicate( xmlStreamReader, "lastPasswordChange", null, parsed ) )
504 {
505 String dateFormat = null;
506 jdoUser.setLastPasswordChange( getDateValue( getTrimmedValue( xmlStreamReader.getElementText() ), "lastPasswordChange", dateFormat, xmlStreamReader ) );
507 }
508 else if ( checkFieldWithDuplicate( xmlStreamReader, "lastLoginDate", null, parsed ) )
509 {
510 String dateFormat = null;
511 jdoUser.setLastLoginDate( getDateValue( getTrimmedValue( xmlStreamReader.getElementText() ), "lastLoginDate", dateFormat, xmlStreamReader ) );
512 }
513 else if ( checkFieldWithDuplicate( xmlStreamReader, "countFailedLoginAttempts", null, parsed ) )
514 {
515 jdoUser.setCountFailedLoginAttempts( getIntegerValue( getTrimmedValue( getDefaultValue( xmlStreamReader.getElementText(), "0" ) ), "countFailedLoginAttempts", xmlStreamReader, strict ) );
516 }
517 else if ( checkFieldWithDuplicate( xmlStreamReader, "locked", null, parsed ) )
518 {
519 jdoUser.setLocked( getBooleanValue( getTrimmedValue( getDefaultValue( xmlStreamReader.getElementText(), "false" ) ), "locked", xmlStreamReader ) );
520 }
521 else if ( checkFieldWithDuplicate( xmlStreamReader, "permanent", null, parsed ) )
522 {
523 jdoUser.setPermanent( getBooleanValue( getTrimmedValue( getDefaultValue( xmlStreamReader.getElementText(), "false" ) ), "permanent", xmlStreamReader ) );
524 }
525 else if ( checkFieldWithDuplicate( xmlStreamReader, "validated", null, parsed ) )
526 {
527 jdoUser.setValidated( getBooleanValue( getTrimmedValue( getDefaultValue( xmlStreamReader.getElementText(), "false" ) ), "validated", xmlStreamReader ) );
528 }
529 else if ( checkFieldWithDuplicate( xmlStreamReader, "passwordChangeRequired", null, parsed ) )
530 {
531 jdoUser.setPasswordChangeRequired( getBooleanValue( getTrimmedValue( getDefaultValue( xmlStreamReader.getElementText(), "false" ) ), "passwordChangeRequired", xmlStreamReader ) );
532 }
533 else if ( checkFieldWithDuplicate( xmlStreamReader, "previousEncodedPasswords", null, parsed ) )
534 {
535 java.util.List previousEncodedPasswords = new java.util.ArrayList
536 jdoUser.setPreviousEncodedPasswords( previousEncodedPasswords );
537 while ( xmlStreamReader.nextTag() == XMLStreamConstants.START_ELEMENT )
538 {
539 if ( xmlStreamReader.getLocalName().equals( "previousEncodedPassword" ) )
540 {
541 previousEncodedPasswords.add( getTrimmedValue( getDefaultValue( xmlStreamReader.getElementText(), "new java.util.ArrayList/*<String>*/()" ) ) );
542 }
543 else
544 {
545 throw new XMLStreamException( "Unrecognised tag: '" + xmlStreamReader.getLocalName() + "'", xmlStreamReader.getLocation() );
546 }
547 }
548 }
549 else if ( checkFieldWithDuplicate( xmlStreamReader, "accountCreationDate", null, parsed ) )
550 {
551 String dateFormat = null;
552 jdoUser.setAccountCreationDate( getDateValue( getTrimmedValue( xmlStreamReader.getElementText() ), "accountCreationDate", dateFormat, xmlStreamReader ) );
553 }
554 else
555 {
556 if ( strict )
557 {
558 throw new XMLStreamException( "Unrecognised tag: '" + xmlStreamReader.getLocalName() + "'", xmlStreamReader.getLocation() );
559 }
560 else
561 {
562 int unrecognizedTagCount = 1;
563 while( unrecognizedTagCount != 0 )
564 {
565 xmlStreamReader.next();
566 if ( xmlStreamReader.getEventType() == XMLStreamConstants.START_ELEMENT )
567 {
568 unrecognizedTagCount++;
569 }
570 else if ( xmlStreamReader.getEventType() == XMLStreamConstants.END_ELEMENT )
571 {
572 unrecognizedTagCount--;
573 }
574 }
575 }
576 }
577 }
578 return jdoUser;
579 }
580
581
582
583
584
585
586
587
588
589
590
591
592 private UserDatabase parseUserDatabase( String tagName, XMLStreamReader xmlStreamReader, boolean strict, String encoding )
593 throws IOException, XMLStreamException
594 {
595 UserDatabase userDatabase = new UserDatabase();
596 java.util.Set parsed = new java.util.HashSet();
597 userDatabase.setModelEncoding( encoding );
598 boolean foundRoot = false;
599 while ( xmlStreamReader.hasNext() )
600 {
601 int eventType = xmlStreamReader.next();
602 if ( eventType == XMLStreamConstants.START_ELEMENT )
603 {
604 if ( xmlStreamReader.getLocalName().equals( tagName ) )
605 {
606 foundRoot = true;
607 }
608 else if ( checkFieldWithDuplicate( xmlStreamReader, "users", null, parsed ) )
609 {
610 java.util.List users = new java.util.ArrayList
611 userDatabase.setUsers( users );
612 while ( xmlStreamReader.nextTag() == XMLStreamConstants.START_ELEMENT )
613 {
614 if ( xmlStreamReader.getLocalName().equals( "user" ) )
615 {
616 userDatabase.addUser( parseJdoUser( "user", xmlStreamReader, strict, encoding ) );
617 }
618 else
619 {
620 throw new XMLStreamException( "Unrecognised tag: '" + xmlStreamReader.getLocalName() + "'", xmlStreamReader.getLocation() );
621 }
622 }
623 }
624 else
625 {
626 if ( foundRoot )
627 {
628 if ( strict )
629 {
630 throw new XMLStreamException( "Unrecognised tag: '" + xmlStreamReader.getLocalName() + "'", xmlStreamReader.getLocation() );
631 }
632 }
633 }
634 }
635 }
636 return userDatabase;
637 }
638
639
640
641
642
643
644
645
646
647
648 public UserDatabase read( Reader reader, boolean strict )
649 throws IOException, XMLStreamException
650 {
651 XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader( reader );
652
653 String encoding = xmlStreamReader.getCharacterEncodingScheme();
654 UserDatabase value = parseUserDatabase( "userDatabase", xmlStreamReader, strict, encoding );
655 resolveReferences( value );
656 return value;
657 }
658
659
660
661
662
663
664
665
666
667 public UserDatabase read( Reader reader )
668 throws IOException, XMLStreamException
669 {
670 return read( reader, true );
671 }
672
673
674
675
676
677
678
679
680
681
682 public UserDatabase read( String filePath, boolean strict )
683 throws IOException, XMLStreamException
684 {
685 File file = new File(filePath);
686 XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader( file.toURL().toExternalForm(), new FileInputStream(file) );
687
688 String encoding = xmlStreamReader.getCharacterEncodingScheme();
689 UserDatabase value = parseUserDatabase( "userDatabase", xmlStreamReader, strict, encoding );
690 resolveReferences( value );
691 return value;
692 }
693
694
695
696
697
698
699
700
701
702 public UserDatabase read( String filePath )
703 throws IOException, XMLStreamException
704 {
705 return read( filePath, true );
706 }
707
708
709
710
711
712
713 private void resolveReferences( UserDatabase value )
714 {
715 java.util.Map refs;
716 }
717
718 }