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