6565 * shared configuration can be created, via constructors.
6666 *
6767 * @author Victor Cordis ( cordis.victor at gmail.com)
68- * @version 1.6.0
68+ * @version 1.7.2
6969 * @see XMLWriter
7070 * @since 1.0
7171 */
@@ -353,8 +353,8 @@ public final Object read() {
353353 /**
354354 * Reads from the current position, recursively.
355355 *
356- * @param componentType array componentType, if the expected result is
357- * an array with no class attribute, null otherwise
356+ * @param componentType array componentType, if the expected result is an array with no class attribute,
357+ * null otherwise
358358 * @return the read object
359359 */
360360 @ Override
@@ -391,6 +391,14 @@ public S put(String key, S value) {
391391 }
392392 }
393393
394+ @ FunctionalInterface
395+ interface AliasingReflectionCacheSupplier {
396+
397+ AliasingReflectionCacheSupplier DEFAULT = HashMap ::new ;
398+
399+ Map <String , Object > get ();
400+ }
401+
394402 private static final char FIELD_FQN_SEPARATOR = '#' ;
395403 private Driver driver ;
396404 private boolean beforeRoot ;
@@ -405,21 +413,47 @@ public S put(String key, S value) {
405413 /* default*/ SecurityPolicy securityPolicy ;
406414
407415 /**
408- * Creates a new configuration prototype instance, to be used by
409- * {@linkplain EasyML} only.
416+ * Creates a new configuration prototype instance.
417+ * To be used by {@linkplain EasyML} only.
410418 */
411- XMLReader (Map < String , Object > aliasFieldCache ) {
419+ XMLReader (AliasingReflectionCacheSupplier getAliasingReflectionCache ) {
412420 this .driver = null ;
413- this .init (aliasFieldCache );
421+ this .init (getAliasingReflectionCache );
422+ }
423+
424+ private void init (AliasingReflectionCacheSupplier getAliasingReflectionCache ) {
425+ this .beforeRoot = true ;
426+ this .rootTag = DTD .ELEMENT_EASYML ;
427+ this .decoded = new HashMap <>();
428+ this .sharedConfiguration = false ;
429+ this .context = new UnmarshalContextImpl ();
430+ this .cachedAliasingReflection = getAliasingReflectionCache .get ();
431+ this .simpleStrategies = new StrategyHashMap <>();
432+ this .compositeStrategies = new StrategyHashMap <>();
433+ this .dateFormat = new SimpleDateFormat (DTD .FORMAT_DATE );
434+ this .securityPolicy = null ; // lazy.
435+ // add DTD strategies by default:
436+ this .simpleStrategies .put (DTD .TYPE_BASE64 , Base64Strategy .INSTANCE );
437+ this .simpleStrategies .put (DTD .TYPE_BOOLEAN , BooleanStrategy .INSTANCE );
438+ this .simpleStrategies .put (DTD .TYPE_DATE , DateStrategy .INSTANCE );
439+ this .simpleStrategies .put (DTD .TYPE_DOUBLE , DoubleStrategy .INSTANCE );
440+ this .simpleStrategies .put (DTD .TYPE_INT , IntStrategy .INSTANCE );
441+ this .simpleStrategies .put (DTD .TYPE_STRING , StringStrategy .INSTANCE );
442+ // add NON-DTD strategies for primitives, since we need to support the primitive API:
443+ this .simpleStrategies .put (ByteStrategy .NAME , ByteStrategy .INSTANCE );
444+ this .simpleStrategies .put (CharacterStrategy .NAME , CharacterStrategy .INSTANCE );
445+ this .simpleStrategies .put (FloatStrategy .NAME , FloatStrategy .INSTANCE );
446+ this .simpleStrategies .put (LongStrategy .NAME , LongStrategy .INSTANCE );
447+ this .simpleStrategies .put (ShortStrategy .NAME , ShortStrategy .INSTANCE );
414448 }
415449
416450 /**
417- * Creates a new shared-configuration instance, to be used by
418- * {@linkplain EasyML} only.
451+ * Creates a new shared-configuration instance.
452+ * To be used by {@linkplain EasyML} only.
419453 */
420- XMLReader (XMLReader configured ) {
454+ XMLReader (XMLReader prototype ) {
421455 this .driver = null ;
422- this .initIdentically (configured );
456+ this .initIdentically (prototype );
423457 }
424458
425459 private void initIdentically (XMLReader other ) {
@@ -444,37 +478,7 @@ private void initIdentically(XMLReader other) {
444478 */
445479 public XMLReader (Reader reader ) {
446480 this .driver = new XMLReaderTextDriver (this , reader );
447- this .init ();
448- }
449-
450- private void init () {
451- this .init (new HashMap <>());
452- }
453-
454- private void init (Map <String , Object > aliasReflectCache ) {
455- this .beforeRoot = true ;
456- this .rootTag = DTD .ELEMENT_EASYML ;
457- this .decoded = new HashMap <>();
458- this .sharedConfiguration = false ;
459- this .context = new UnmarshalContextImpl ();
460- this .cachedAliasingReflection = aliasReflectCache ;
461- this .simpleStrategies = new StrategyHashMap <>();
462- this .compositeStrategies = new StrategyHashMap <>();
463- this .dateFormat = new SimpleDateFormat (DTD .FORMAT_DATE );
464- this .securityPolicy = null ; // lazy.
465- // add DTD strategies by default:
466- this .simpleStrategies .put (DTD .TYPE_BASE64 , Base64Strategy .INSTANCE );
467- this .simpleStrategies .put (DTD .TYPE_BOOLEAN , BooleanStrategy .INSTANCE );
468- this .simpleStrategies .put (DTD .TYPE_DATE , DateStrategy .INSTANCE );
469- this .simpleStrategies .put (DTD .TYPE_DOUBLE , DoubleStrategy .INSTANCE );
470- this .simpleStrategies .put (DTD .TYPE_INT , IntStrategy .INSTANCE );
471- this .simpleStrategies .put (DTD .TYPE_STRING , StringStrategy .INSTANCE );
472- // add NON-DTD strategies for primitives, since we need to support the primitive API:
473- this .simpleStrategies .put (ByteStrategy .NAME , ByteStrategy .INSTANCE );
474- this .simpleStrategies .put (CharacterStrategy .NAME , CharacterStrategy .INSTANCE );
475- this .simpleStrategies .put (FloatStrategy .NAME , FloatStrategy .INSTANCE );
476- this .simpleStrategies .put (LongStrategy .NAME , LongStrategy .INSTANCE );
477- this .simpleStrategies .put (ShortStrategy .NAME , ShortStrategy .INSTANCE );
481+ this .init (AliasingReflectionCacheSupplier .DEFAULT );
478482 }
479483
480484 /**
@@ -485,8 +489,7 @@ private void init(Map<String, Object> aliasReflectCache) {
485489 * @param in stream from which to read
486490 */
487491 public XMLReader (InputStream in ) {
488- this .driver = new XMLReaderTextDriver (this , new InputStreamReader (in ));
489- this .init ();
492+ this (new InputStreamReader (in ));
490493 }
491494
492495 /**
@@ -499,7 +502,7 @@ public XMLReader(InputStream in) {
499502 */
500503 public XMLReader (Reader reader , XmlPullParser parser ) {
501504 this .driver = new XMLReaderTextDriver (this , reader , parser );
502- this .init ();
505+ this .init (AliasingReflectionCacheSupplier . DEFAULT );
503506 }
504507
505508 /**
@@ -511,8 +514,7 @@ public XMLReader(Reader reader, XmlPullParser parser) {
511514 * @param parser to process the in XML with
512515 */
513516 public XMLReader (InputStream in , XmlPullParser parser ) {
514- this .driver = new XMLReaderTextDriver (this , new InputStreamReader (in ), parser );
515- this .init ();
517+ this (new InputStreamReader (in ), parser );
516518 }
517519
518520 /**
@@ -523,7 +525,21 @@ public XMLReader(InputStream in, XmlPullParser parser) {
523525 */
524526 public XMLReader (Document in ) {
525527 this .driver = new XMLReaderDOMDriver (this , in );
526- this .init ();
528+ this .init (AliasingReflectionCacheSupplier .DEFAULT );
529+ }
530+
531+ /**
532+ * Creates a new instance with the given <code>driver</code>.
533+ * For generic formats, other than XML.
534+ *
535+ * @param driver for generic formats
536+ */
537+ public XMLReader (XMLReader .Driver driver ) {
538+ if (driver == null ) {
539+ throw new IllegalArgumentException ("driver: null" );
540+ }
541+ this .driver = driver ;
542+ this .init (AliasingReflectionCacheSupplier .DEFAULT );
527543 }
528544
529545 /**
@@ -1045,20 +1061,17 @@ private boolean isRootEnd() {
10451061 * @param parser to use, null if default
10461062 */
10471063 public void reset (Reader reader , XmlPullParser parser ) {
1048- if (isReusableXMLReaderTextDriver () ) {
1064+ if (this . driver != null && this . driver . getClass () == XMLReaderTextDriver . class ) {
10491065 ((XMLReaderTextDriver ) this .driver ).reset (reader , parser );
10501066 } else {
1051- this .driver = parser != null ? new XMLReaderTextDriver (this , reader , parser )
1052- : new XMLReaderTextDriver (this , reader );
1067+ this .driver = parser != null ?
1068+ new XMLReaderTextDriver (this , reader , parser ) :
1069+ new XMLReaderTextDriver (this , reader );
10531070 }
10541071 this .decoded .clear ();
10551072 this .beforeRoot = true ;
10561073 }
10571074
1058- private boolean isReusableXMLReaderTextDriver () {
1059- return this .driver != null && this .driver .getClass () == XMLReaderTextDriver .class ;
1060- }
1061-
10621075 /**
10631076 * Resets this instance, setting it to the new <code>in</code> stream.
10641077 *
0 commit comments