View Javadoc
1   // =================== DO NOT EDIT THIS FILE ====================
2   // Generated by Modello 1.11,
3   // any modifications will be overwritten.
4   // ==============================================================
5   
6   package org.apache.maven.archetype.model.io.xpp3;
7   
8     //---------------------------------/
9    //- Imported classes and packages -/
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.archetype.model.ArchetypeModel;
17  import org.apache.maven.archetype.model.Resource;
18  import org.apache.maven.archetype.model.Source;
19  import org.codehaus.plexus.util.ReaderFactory;
20  import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
21  import org.codehaus.plexus.util.xml.pull.MXParser;
22  import org.codehaus.plexus.util.xml.pull.XmlPullParser;
23  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
24  
25  /**
26   * Class ArchetypeXpp3Reader.
27   * 
28   * @version $Revision$ $Date$
29   */
30  @SuppressWarnings( "all" )
31  public class ArchetypeXpp3Reader
32  {
33  
34        //--------------------------/
35       //- Class/Member Variables -/
36      //--------------------------/
37  
38      /**
39       * If set the parser will be loaded with all single characters
40       * from the XHTML specification.
41       * The entities used:
42       * <ul>
43       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent</li>;
44       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent</li>;
45       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</li>;
46       * </ul>
47       */
48      private boolean addDefaultEntities = true;
49  
50      /**
51       * Field contentTransformer.
52       */
53      public final ContentTransformer contentTransformer;
54  
55  
56        //----------------/
57       //- Constructors -/
58      //----------------/
59  
60      public ArchetypeXpp3Reader()
61      {
62          this( new ContentTransformer()
63          {
64              public String transform( String source, String fieldName )
65              {
66                  return source;
67              }
68          } );
69      } //-- org.apache.maven.archetype.model.io.xpp3.ArchetypeXpp3Reader()
70  
71      public ArchetypeXpp3Reader(ContentTransformer contentTransformer)
72      {
73          this.contentTransformer = contentTransformer;
74      } //-- org.apache.maven.archetype.model.io.xpp3.ArchetypeXpp3Reader(ContentTransformer)
75  
76  
77        //-----------/
78       //- Methods -/
79      //-----------/
80  
81      /**
82       * Method checkFieldWithDuplicate.
83       * 
84       * @param parser
85       * @param parsed
86       * @param alias
87       * @param tagName
88       * @throws XmlPullParserException
89       * @return boolean
90       */
91      private boolean checkFieldWithDuplicate( XmlPullParser parser, String tagName, String alias, java.util.Set parsed )
92          throws XmlPullParserException
93      {
94          if ( !( parser.getName().equals( tagName ) || parser.getName().equals( alias ) ) )
95          {
96              return false;
97          }
98          if ( !parsed.add( tagName ) )
99          {
100             throw new XmlPullParserException( "Duplicated tag: '" + tagName + "'", parser, null );
101         }
102         return true;
103     } //-- boolean checkFieldWithDuplicate( XmlPullParser, String, String, java.util.Set )
104 
105     /**
106      * Method checkUnknownAttribute.
107      * 
108      * @param parser
109      * @param strict
110      * @param tagName
111      * @param attribute
112      * @throws XmlPullParserException
113      * @throws IOException
114      */
115     private void checkUnknownAttribute( XmlPullParser parser, String attribute, String tagName, boolean strict )
116         throws XmlPullParserException, IOException
117     {
118         // strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
119         if ( strict )
120         {
121             throw new XmlPullParserException( "Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser, null );
122         }
123     } //-- void checkUnknownAttribute( XmlPullParser, String, String, boolean )
124 
125     /**
126      * Method checkUnknownElement.
127      * 
128      * @param parser
129      * @param strict
130      * @throws XmlPullParserException
131      * @throws IOException
132      */
133     private void checkUnknownElement( XmlPullParser parser, boolean strict )
134         throws XmlPullParserException, IOException
135     {
136         if ( strict )
137         {
138             throw new XmlPullParserException( "Unrecognised tag: '" + parser.getName() + "'", parser, null );
139         }
140 
141         for ( int unrecognizedTagCount = 1; unrecognizedTagCount > 0; )
142         {
143             int eventType = parser.next();
144             if ( eventType == XmlPullParser.START_TAG )
145             {
146                 unrecognizedTagCount++;
147             }
148             else if ( eventType == XmlPullParser.END_TAG )
149             {
150                 unrecognizedTagCount--;
151             }
152         }
153     } //-- void checkUnknownElement( XmlPullParser, boolean )
154 
155     /**
156      * Returns the state of the "add default entities" flag.
157      * 
158      * @return boolean
159      */
160     public boolean getAddDefaultEntities()
161     {
162         return addDefaultEntities;
163     } //-- boolean getAddDefaultEntities()
164 
165     /**
166      * Method getBooleanValue.
167      * 
168      * @param s
169      * @param parser
170      * @param attribute
171      * @throws XmlPullParserException
172      * @return boolean
173      */
174     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser )
175         throws XmlPullParserException
176     {
177         return getBooleanValue( s, attribute, parser, null );
178     } //-- boolean getBooleanValue( String, String, XmlPullParser )
179 
180     /**
181      * Method getBooleanValue.
182      * 
183      * @param s
184      * @param defaultValue
185      * @param parser
186      * @param attribute
187      * @throws XmlPullParserException
188      * @return boolean
189      */
190     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser, String defaultValue )
191         throws XmlPullParserException
192     {
193         if ( s != null && s.length() != 0 )
194         {
195             return Boolean.valueOf( s ).booleanValue();
196         }
197         if ( defaultValue != null )
198         {
199             return Boolean.valueOf( defaultValue ).booleanValue();
200         }
201         return false;
202     } //-- boolean getBooleanValue( String, String, XmlPullParser, String )
203 
204     /**
205      * Method getByteValue.
206      * 
207      * @param s
208      * @param strict
209      * @param parser
210      * @param attribute
211      * @throws XmlPullParserException
212      * @return byte
213      */
214     private byte getByteValue( String s, String attribute, XmlPullParser parser, boolean strict )
215         throws XmlPullParserException
216     {
217         if ( s != null )
218         {
219             try
220             {
221                 return Byte.valueOf( s ).byteValue();
222             }
223             catch ( NumberFormatException nfe )
224             {
225                 if ( strict )
226                 {
227                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a byte", parser, nfe );
228                 }
229             }
230         }
231         return 0;
232     } //-- byte getByteValue( String, String, XmlPullParser, boolean )
233 
234     /**
235      * Method getCharacterValue.
236      * 
237      * @param s
238      * @param parser
239      * @param attribute
240      * @throws XmlPullParserException
241      * @return char
242      */
243     private char getCharacterValue( String s, String attribute, XmlPullParser parser )
244         throws XmlPullParserException
245     {
246         if ( s != null )
247         {
248             return s.charAt( 0 );
249         }
250         return 0;
251     } //-- char getCharacterValue( String, String, XmlPullParser )
252 
253     /**
254      * Method getDateValue.
255      * 
256      * @param s
257      * @param parser
258      * @param attribute
259      * @throws XmlPullParserException
260      * @return Date
261      */
262     private java.util.Date getDateValue( String s, String attribute, XmlPullParser parser )
263         throws XmlPullParserException
264     {
265         return getDateValue( s, attribute, null, parser );
266     } //-- java.util.Date getDateValue( String, String, XmlPullParser )
267 
268     /**
269      * Method getDateValue.
270      * 
271      * @param s
272      * @param parser
273      * @param dateFormat
274      * @param attribute
275      * @throws XmlPullParserException
276      * @return Date
277      */
278     private java.util.Date getDateValue( String s, String attribute, String dateFormat, XmlPullParser parser )
279         throws XmlPullParserException
280     {
281         if ( s != null )
282         {
283             String effectiveDateFormat = dateFormat;
284             if ( dateFormat == null )
285             {
286                 effectiveDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS";
287             }
288             if ( "long".equals( effectiveDateFormat ) )
289             {
290                 try
291                 {
292                     return new java.util.Date( Long.parseLong( s ) );
293                 }
294                 catch ( NumberFormatException e )
295                 {
296                     throw new XmlPullParserException( e.getMessage(), parser, e );
297                 }
298             }
299             else
300             {
301                 try
302                 {
303                     DateFormat dateParser = new java.text.SimpleDateFormat( effectiveDateFormat, java.util.Locale.US );
304                     return dateParser.parse( s );
305                 }
306                 catch ( java.text.ParseException e )
307                 {
308                     throw new XmlPullParserException( e.getMessage(), parser, e );
309                 }
310             }
311         }
312         return null;
313     } //-- java.util.Date getDateValue( String, String, String, XmlPullParser )
314 
315     /**
316      * Method getDoubleValue.
317      * 
318      * @param s
319      * @param strict
320      * @param parser
321      * @param attribute
322      * @throws XmlPullParserException
323      * @return double
324      */
325     private double getDoubleValue( String s, String attribute, XmlPullParser parser, boolean strict )
326         throws XmlPullParserException
327     {
328         if ( s != null )
329         {
330             try
331             {
332                 return Double.valueOf( s ).doubleValue();
333             }
334             catch ( NumberFormatException nfe )
335             {
336                 if ( strict )
337                 {
338                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
339                 }
340             }
341         }
342         return 0;
343     } //-- double getDoubleValue( String, String, XmlPullParser, boolean )
344 
345     /**
346      * Method getFloatValue.
347      * 
348      * @param s
349      * @param strict
350      * @param parser
351      * @param attribute
352      * @throws XmlPullParserException
353      * @return float
354      */
355     private float getFloatValue( String s, String attribute, XmlPullParser parser, boolean strict )
356         throws XmlPullParserException
357     {
358         if ( s != null )
359         {
360             try
361             {
362                 return Float.valueOf( s ).floatValue();
363             }
364             catch ( NumberFormatException nfe )
365             {
366                 if ( strict )
367                 {
368                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
369                 }
370             }
371         }
372         return 0;
373     } //-- float getFloatValue( String, String, XmlPullParser, boolean )
374 
375     /**
376      * Method getIntegerValue.
377      * 
378      * @param s
379      * @param strict
380      * @param parser
381      * @param attribute
382      * @throws XmlPullParserException
383      * @return int
384      */
385     private int getIntegerValue( String s, String attribute, XmlPullParser parser, boolean strict )
386         throws XmlPullParserException
387     {
388         if ( s != null )
389         {
390             try
391             {
392                 return Integer.valueOf( s ).intValue();
393             }
394             catch ( NumberFormatException nfe )
395             {
396                 if ( strict )
397                 {
398                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be an integer", parser, nfe );
399                 }
400             }
401         }
402         return 0;
403     } //-- int getIntegerValue( String, String, XmlPullParser, boolean )
404 
405     /**
406      * Method getLongValue.
407      * 
408      * @param s
409      * @param strict
410      * @param parser
411      * @param attribute
412      * @throws XmlPullParserException
413      * @return long
414      */
415     private long getLongValue( String s, String attribute, XmlPullParser parser, boolean strict )
416         throws XmlPullParserException
417     {
418         if ( s != null )
419         {
420             try
421             {
422                 return Long.valueOf( s ).longValue();
423             }
424             catch ( NumberFormatException nfe )
425             {
426                 if ( strict )
427                 {
428                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a long integer", parser, nfe );
429                 }
430             }
431         }
432         return 0;
433     } //-- long getLongValue( String, String, XmlPullParser, boolean )
434 
435     /**
436      * Method getRequiredAttributeValue.
437      * 
438      * @param s
439      * @param strict
440      * @param parser
441      * @param attribute
442      * @throws XmlPullParserException
443      * @return String
444      */
445     private String getRequiredAttributeValue( String s, String attribute, XmlPullParser parser, boolean strict )
446         throws XmlPullParserException
447     {
448         if ( s == null )
449         {
450             if ( strict )
451             {
452                 throw new XmlPullParserException( "Missing required value for attribute '" + attribute + "'", parser, null );
453             }
454         }
455         return s;
456     } //-- String getRequiredAttributeValue( String, String, XmlPullParser, boolean )
457 
458     /**
459      * Method getShortValue.
460      * 
461      * @param s
462      * @param strict
463      * @param parser
464      * @param attribute
465      * @throws XmlPullParserException
466      * @return short
467      */
468     private short getShortValue( String s, String attribute, XmlPullParser parser, boolean strict )
469         throws XmlPullParserException
470     {
471         if ( s != null )
472         {
473             try
474             {
475                 return Short.valueOf( s ).shortValue();
476             }
477             catch ( NumberFormatException nfe )
478             {
479                 if ( strict )
480                 {
481                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a short integer", parser, nfe );
482                 }
483             }
484         }
485         return 0;
486     } //-- short getShortValue( String, String, XmlPullParser, boolean )
487 
488     /**
489      * Method getTrimmedValue.
490      * 
491      * @param s
492      * @return String
493      */
494     private String getTrimmedValue( String s )
495     {
496         if ( s != null )
497         {
498             s = s.trim();
499         }
500         return s;
501     } //-- String getTrimmedValue( String )
502 
503     /**
504      * Method interpolatedTrimmed.
505      * 
506      * @param value
507      * @param context
508      * @return String
509      */
510     private String interpolatedTrimmed( String value, String context )
511     {
512         return getTrimmedValue( contentTransformer.transform( value, context ) );
513     } //-- String interpolatedTrimmed( String, String )
514 
515     /**
516      * Method nextTag.
517      * 
518      * @param parser
519      * @throws IOException
520      * @throws XmlPullParserException
521      * @return int
522      */
523     private int nextTag( XmlPullParser parser )
524         throws IOException, XmlPullParserException
525     {
526         int eventType = parser.next();
527         if ( eventType == XmlPullParser.TEXT )
528         {
529             eventType = parser.next();
530         }
531         if ( eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_TAG )
532         {
533             throw new XmlPullParserException( "expected START_TAG or END_TAG not " + XmlPullParser.TYPES[eventType], parser, null );
534         }
535         return eventType;
536     } //-- int nextTag( XmlPullParser )
537 
538     /**
539      * @see ReaderFactory#newXmlReader
540      * 
541      * @param reader
542      * @param strict
543      * @throws IOException
544      * @throws XmlPullParserException
545      * @return ArchetypeModel
546      */
547     public ArchetypeModel read( Reader reader, boolean strict )
548         throws IOException, XmlPullParserException
549     {
550         XmlPullParser parser = addDefaultEntities ? new MXParser(EntityReplacementMap.defaultEntityReplacementMap) : new MXParser( );
551 
552         parser.setInput( reader );
553 
554 
555         return read( parser, strict );
556     } //-- ArchetypeModel read( Reader, boolean )
557 
558     /**
559      * @see ReaderFactory#newXmlReader
560      * 
561      * @param reader
562      * @throws IOException
563      * @throws XmlPullParserException
564      * @return ArchetypeModel
565      */
566     public ArchetypeModel read( Reader reader )
567         throws IOException, XmlPullParserException
568     {
569         return read( reader, true );
570     } //-- ArchetypeModel read( Reader )
571 
572     /**
573      * Method read.
574      * 
575      * @param in
576      * @param strict
577      * @throws IOException
578      * @throws XmlPullParserException
579      * @return ArchetypeModel
580      */
581     public ArchetypeModel read( InputStream in, boolean strict )
582         throws IOException, XmlPullParserException
583     {
584         return read( ReaderFactory.newXmlReader( in ), strict );
585     } //-- ArchetypeModel read( InputStream, boolean )
586 
587     /**
588      * Method read.
589      * 
590      * @param in
591      * @throws IOException
592      * @throws XmlPullParserException
593      * @return ArchetypeModel
594      */
595     public ArchetypeModel read( InputStream in )
596         throws IOException, XmlPullParserException
597     {
598         return read( ReaderFactory.newXmlReader( in ) );
599     } //-- ArchetypeModel read( InputStream )
600 
601     /**
602      * Method parseArchetypeModel.
603      * 
604      * @param parser
605      * @param strict
606      * @throws IOException
607      * @throws XmlPullParserException
608      * @return ArchetypeModel
609      */
610     private ArchetypeModel parseArchetypeModel( XmlPullParser parser, boolean strict )
611         throws IOException, XmlPullParserException
612     {
613         String tagName = parser.getName();
614         ArchetypeModel archetypeModel = new ArchetypeModel();
615         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
616         {
617             String name = parser.getAttributeName( i );
618             String value = parser.getAttributeValue( i );
619 
620             if ( name.indexOf( ':' ) >= 0 )
621             {
622                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
623             }
624             else if ( "xmlns".equals( name ) )
625             {
626                 // ignore xmlns attribute in root class, which is a reserved attribute name
627             }
628             else
629             {
630                 checkUnknownAttribute( parser, name, tagName, strict );
631             }
632         }
633         java.util.Set parsed = new java.util.HashSet();
634         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
635         {
636             if ( checkFieldWithDuplicate( parser, "id", null, parsed ) )
637             {
638                 archetypeModel.setId( interpolatedTrimmed( parser.nextText(), "id" ) );
639             }
640             else if ( checkFieldWithDuplicate( parser, "allowPartial", null, parsed ) )
641             {
642                 archetypeModel.setAllowPartial( getBooleanValue( interpolatedTrimmed( parser.nextText(), "allowPartial" ), "allowPartial", parser, "false" ) );
643             }
644             else if ( checkFieldWithDuplicate( parser, "sources", null, parsed ) )
645             {
646                 java.util.List<Source> sources = new java.util.ArrayList<Source>();
647                 archetypeModel.setSources( sources );
648                 while ( parser.nextTag() == XmlPullParser.START_TAG )
649                 {
650                     if ( "source".equals( parser.getName() ) )
651                     {
652                         sources.add( parseSource( parser, strict ) );
653                     }
654                     else
655                     {
656                         checkUnknownElement( parser, strict );
657                     }
658                 }
659             }
660             else if ( checkFieldWithDuplicate( parser, "resources", null, parsed ) )
661             {
662                 java.util.List<Resource> resources = new java.util.ArrayList<Resource>();
663                 archetypeModel.setResources( resources );
664                 while ( parser.nextTag() == XmlPullParser.START_TAG )
665                 {
666                     if ( "resource".equals( parser.getName() ) )
667                     {
668                         resources.add( parseResource( parser, strict ) );
669                     }
670                     else
671                     {
672                         checkUnknownElement( parser, strict );
673                     }
674                 }
675             }
676             else if ( checkFieldWithDuplicate( parser, "testSources", null, parsed ) )
677             {
678                 java.util.List<Source> testSources = new java.util.ArrayList<Source>();
679                 archetypeModel.setTestSources( testSources );
680                 while ( parser.nextTag() == XmlPullParser.START_TAG )
681                 {
682                     if ( "source".equals( parser.getName() ) )
683                     {
684                         testSources.add( parseSource( parser, strict ) );
685                     }
686                     else
687                     {
688                         checkUnknownElement( parser, strict );
689                     }
690                 }
691             }
692             else if ( checkFieldWithDuplicate( parser, "testResources", null, parsed ) )
693             {
694                 java.util.List<Resource> testResources = new java.util.ArrayList<Resource>();
695                 archetypeModel.setTestResources( testResources );
696                 while ( parser.nextTag() == XmlPullParser.START_TAG )
697                 {
698                     if ( "resource".equals( parser.getName() ) )
699                     {
700                         testResources.add( parseResource( parser, strict ) );
701                     }
702                     else
703                     {
704                         checkUnknownElement( parser, strict );
705                     }
706                 }
707             }
708             else if ( checkFieldWithDuplicate( parser, "siteResources", null, parsed ) )
709             {
710                 java.util.List<Resource> siteResources = new java.util.ArrayList<Resource>();
711                 archetypeModel.setSiteResources( siteResources );
712                 while ( parser.nextTag() == XmlPullParser.START_TAG )
713                 {
714                     if ( "resource".equals( parser.getName() ) )
715                     {
716                         siteResources.add( parseResource( parser, strict ) );
717                     }
718                     else
719                     {
720                         checkUnknownElement( parser, strict );
721                     }
722                 }
723             }
724             else
725             {
726                 checkUnknownElement( parser, strict );
727             }
728         }
729         return archetypeModel;
730     } //-- ArchetypeModel parseArchetypeModel( XmlPullParser, boolean )
731 
732     /**
733      * Method parseResource.
734      * 
735      * @param parser
736      * @param strict
737      * @throws IOException
738      * @throws XmlPullParserException
739      * @return Resource
740      */
741     private Resource parseResource( XmlPullParser parser, boolean strict )
742         throws IOException, XmlPullParserException
743     {
744         String tagName = parser.getName();
745         Resource resource = new Resource();
746         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
747         {
748             String name = parser.getAttributeName( i );
749             String value = parser.getAttributeValue( i );
750 
751             if ( name.indexOf( ':' ) >= 0 )
752             {
753                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
754             }
755             else if ( "encoding".equals( name ) )
756             {
757                 resource.setEncoding( interpolatedTrimmed( value, "encoding" ) );
758             }
759             else if ( "filtered".equals( name ) )
760             {
761                 resource.setFiltered( getBooleanValue( interpolatedTrimmed( value, "filtered" ), "filtered", parser, "true" ) );
762             }
763             else
764             {
765                 checkUnknownAttribute( parser, name, tagName, strict );
766             }
767         }
768         resource.setFile( interpolatedTrimmed( parser.nextText(), "file" ) );
769         return resource;
770     } //-- Resource parseResource( XmlPullParser, boolean )
771 
772     /**
773      * Method parseSource.
774      * 
775      * @param parser
776      * @param strict
777      * @throws IOException
778      * @throws XmlPullParserException
779      * @return Source
780      */
781     private Source parseSource( XmlPullParser parser, boolean strict )
782         throws IOException, XmlPullParserException
783     {
784         String tagName = parser.getName();
785         Source source = new Source();
786         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
787         {
788             String name = parser.getAttributeName( i );
789             String value = parser.getAttributeValue( i );
790 
791             if ( name.indexOf( ':' ) >= 0 )
792             {
793                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
794             }
795             else if ( "encoding".equals( name ) )
796             {
797                 source.setEncoding( interpolatedTrimmed( value, "encoding" ) );
798             }
799             else
800             {
801                 checkUnknownAttribute( parser, name, tagName, strict );
802             }
803         }
804         source.setFile( interpolatedTrimmed( parser.nextText(), "file" ) );
805         return source;
806     } //-- Source parseSource( XmlPullParser, boolean )
807 
808     /**
809      * Method read.
810      * 
811      * @param parser
812      * @param strict
813      * @throws IOException
814      * @throws XmlPullParserException
815      * @return ArchetypeModel
816      */
817     private ArchetypeModel read( XmlPullParser parser, boolean strict )
818         throws IOException, XmlPullParserException
819     {
820         ArchetypeModel archetypeModel = null;
821         int eventType = parser.getEventType();
822         boolean parsed = false;
823         while ( eventType != XmlPullParser.END_DOCUMENT )
824         {
825             if ( eventType == XmlPullParser.START_TAG )
826             {
827                 if ( strict && ! "archetype".equals( parser.getName() ) )
828                 {
829                     throw new XmlPullParserException( "Expected root element 'archetype' but found '" + parser.getName() + "'", parser, null );
830                 }
831                 else if ( parsed )
832                 {
833                     // fallback, already expected a XmlPullParserException due to invalid XML
834                     throw new XmlPullParserException( "Duplicated tag: 'archetype'", parser, null );
835                 }
836                 archetypeModel = parseArchetypeModel( parser, strict );
837                 archetypeModel.setModelEncoding( parser.getInputEncoding() );
838                 parsed = true;
839             }
840             eventType = parser.next();
841         }
842         if ( parsed )
843         {
844             return archetypeModel;
845         }
846         throw new XmlPullParserException( "Expected root element 'archetype' but found no element at all: invalid XML document", parser, null );
847     } //-- ArchetypeModel read( XmlPullParser, boolean )
848 
849     /**
850      * Sets the state of the "add default entities" flag.
851      * 
852      * @param addDefaultEntities
853      */
854     public void setAddDefaultEntities( boolean addDefaultEntities )
855     {
856         this.addDefaultEntities = addDefaultEntities;
857     } //-- void setAddDefaultEntities( boolean )
858 
859     public static interface ContentTransformer
860 {
861     /**
862      * Interpolate the value read from the xpp3 document
863      * @param source The source value
864      * @param fieldName A description of the field being interpolated. The implementation may use this to
865      *                           log stuff.
866      * @return The interpolated value.
867      */
868     String transform( String source, String fieldName );
869 }
870 
871 }