View Javadoc
1   /*
2    =================== DO NOT EDIT THIS FILE ====================
3    
4    Generated by Modello 2.4.0,
5    
6    any modifications will be overwritten.
7    
8    ==============================================================
9    */
10  
11  package org.apache.maven.doxia.site.decoration.io.xpp3;
12  
13    //---------------------------------/
14   //- Imported classes and packages -/
15  //---------------------------------/
16  
17  import java.io.IOException;
18  import java.io.InputStream;
19  import java.io.Reader;
20  import java.text.DateFormat;
21  import org.apache.maven.doxia.site.decoration.Banner;
22  import org.apache.maven.doxia.site.decoration.Body;
23  import org.apache.maven.doxia.site.decoration.DecorationModel;
24  import org.apache.maven.doxia.site.decoration.LinkItem;
25  import org.apache.maven.doxia.site.decoration.Logo;
26  import org.apache.maven.doxia.site.decoration.Menu;
27  import org.apache.maven.doxia.site.decoration.MenuItem;
28  import org.apache.maven.doxia.site.decoration.PublishDate;
29  import org.apache.maven.doxia.site.decoration.Skin;
30  import org.apache.maven.doxia.site.decoration.Version;
31  import org.codehaus.plexus.util.xml.XmlStreamReader;
32  import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
33  import org.codehaus.plexus.util.xml.pull.MXParser;
34  import org.codehaus.plexus.util.xml.pull.XmlPullParser;
35  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
36  
37  /**
38   * Class DecorationXpp3Reader.
39   * 
40   * @version $Revision$ $Date$
41   */
42  @SuppressWarnings( "all" )
43  public class DecorationXpp3Reader
44  {
45  
46        //--------------------------/
47       //- Class/Member Variables -/
48      //--------------------------/
49  
50      /**
51       * If set the parser will be loaded with all single characters
52       * from the XHTML specification.
53       * The entities used:
54       * <ul>
55       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent</li>
56       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent</li>
57       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</li>
58       * </ul>
59       */
60      private boolean addDefaultEntities = true;
61  
62      /**
63       * Field contentTransformer.
64       */
65      public final ContentTransformer contentTransformer;
66  
67  
68        //----------------/
69       //- Constructors -/
70      //----------------/
71  
72      public DecorationXpp3Reader()
73      {
74          this( new ContentTransformer()
75          {
76              public String transform( String source, String fieldName )
77              {
78                  return source;
79              }
80          } );
81      } //-- org.apache.maven.doxia.site.decoration.io.xpp3.DecorationXpp3Reader()
82  
83      public DecorationXpp3Reader(ContentTransformer contentTransformer)
84      {
85          this.contentTransformer = contentTransformer;
86      } //-- org.apache.maven.doxia.site.decoration.io.xpp3.DecorationXpp3Reader(ContentTransformer)
87  
88  
89        //-----------/
90       //- Methods -/
91      //-----------/
92  
93      /**
94       * Method checkFieldWithDuplicate.
95       * 
96       * @param parser a parser object.
97       * @param parsed a parsed object.
98       * @param alias a alias object.
99       * @param tagName a tagName object.
100      * @throws XmlPullParserException XmlPullParserException if
101      * any.
102      * @return boolean
103      */
104     private boolean checkFieldWithDuplicate( XmlPullParser parser, String tagName, String alias, java.util.Set<String> parsed )
105         throws XmlPullParserException
106     {
107         if ( !( parser.getName().equals( tagName ) || parser.getName().equals( alias ) ) )
108         {
109             return false;
110         }
111         if ( !parsed.add( tagName ) )
112         {
113             throw new XmlPullParserException( "Duplicated tag: '" + tagName + "'", parser, null );
114         }
115         return true;
116     } //-- boolean checkFieldWithDuplicate( XmlPullParser, String, String, java.util.Set )
117 
118     /**
119      * Method checkUnknownAttribute.
120      * 
121      * @param parser a parser object.
122      * @param strict a strict object.
123      * @param tagName a tagName object.
124      * @param attribute a attribute object.
125      * @throws XmlPullParserException XmlPullParserException if
126      * any.
127      * @throws IOException IOException if any.
128      */
129     private void checkUnknownAttribute( XmlPullParser parser, String attribute, String tagName, boolean strict )
130         throws XmlPullParserException, IOException
131     {
132         // strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
133         if ( strict )
134         {
135             throw new XmlPullParserException( "Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser, null );
136         }
137     } //-- void checkUnknownAttribute( XmlPullParser, String, String, boolean )
138 
139     /**
140      * Method checkUnknownElement.
141      * 
142      * @param parser a parser object.
143      * @param strict a strict object.
144      * @throws XmlPullParserException XmlPullParserException if
145      * any.
146      * @throws IOException IOException if any.
147      */
148     private void checkUnknownElement( XmlPullParser parser, boolean strict )
149         throws XmlPullParserException, IOException
150     {
151         if ( strict )
152         {
153             throw new XmlPullParserException( "Unrecognised tag: '" + parser.getName() + "'", parser, null );
154         }
155 
156         for ( int unrecognizedTagCount = 1; unrecognizedTagCount > 0; )
157         {
158             int eventType = parser.next();
159             if ( eventType == XmlPullParser.START_TAG )
160             {
161                 unrecognizedTagCount++;
162             }
163             else if ( eventType == XmlPullParser.END_TAG )
164             {
165                 unrecognizedTagCount--;
166             }
167         }
168     } //-- void checkUnknownElement( XmlPullParser, boolean )
169 
170     /**
171      * Returns the state of the "add default entities" flag.
172      * 
173      * @return boolean
174      */
175     public boolean getAddDefaultEntities()
176     {
177         return addDefaultEntities;
178     } //-- boolean getAddDefaultEntities()
179 
180     /**
181      * Method getBooleanValue.
182      * 
183      * @param s a s object.
184      * @param parser a parser object.
185      * @param attribute a attribute object.
186      * @throws XmlPullParserException XmlPullParserException if
187      * any.
188      * @return boolean
189      */
190     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser )
191         throws XmlPullParserException
192     {
193         return getBooleanValue( s, attribute, parser, null );
194     } //-- boolean getBooleanValue( String, String, XmlPullParser )
195 
196     /**
197      * Method getBooleanValue.
198      * 
199      * @param s a s object.
200      * @param defaultValue a defaultValue object.
201      * @param parser a parser object.
202      * @param attribute a attribute object.
203      * @throws XmlPullParserException XmlPullParserException if
204      * any.
205      * @return boolean
206      */
207     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser, String defaultValue )
208         throws XmlPullParserException
209     {
210         if ( s != null && s.length() != 0 )
211         {
212             return Boolean.valueOf( s ).booleanValue();
213         }
214         if ( defaultValue != null )
215         {
216             return Boolean.valueOf( defaultValue ).booleanValue();
217         }
218         return false;
219     } //-- boolean getBooleanValue( String, String, XmlPullParser, String )
220 
221     /**
222      * Method getByteValue.
223      * 
224      * @param s a s object.
225      * @param strict a strict object.
226      * @param parser a parser object.
227      * @param attribute a attribute object.
228      * @throws XmlPullParserException XmlPullParserException if
229      * any.
230      * @return byte
231      */
232     private byte getByteValue( String s, String attribute, XmlPullParser parser, boolean strict )
233         throws XmlPullParserException
234     {
235         if ( s != null )
236         {
237             try
238             {
239                 return Byte.valueOf( s ).byteValue();
240             }
241             catch ( NumberFormatException nfe )
242             {
243                 if ( strict )
244                 {
245                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a byte", parser, nfe );
246                 }
247             }
248         }
249         return 0;
250     } //-- byte getByteValue( String, String, XmlPullParser, boolean )
251 
252     /**
253      * Method getCharacterValue.
254      * 
255      * @param s a s object.
256      * @param parser a parser object.
257      * @param attribute a attribute object.
258      * @throws XmlPullParserException XmlPullParserException if
259      * any.
260      * @return char
261      */
262     private char getCharacterValue( String s, String attribute, XmlPullParser parser )
263         throws XmlPullParserException
264     {
265         if ( s != null )
266         {
267             return s.charAt( 0 );
268         }
269         return 0;
270     } //-- char getCharacterValue( String, String, XmlPullParser )
271 
272     /**
273      * Method getDateValue.
274      * 
275      * @param s a s object.
276      * @param parser a parser object.
277      * @param attribute a attribute object.
278      * @throws XmlPullParserException XmlPullParserException if
279      * any.
280      * @return Date
281      */
282     private java.util.Date getDateValue( String s, String attribute, XmlPullParser parser )
283         throws XmlPullParserException
284     {
285         return getDateValue( s, attribute, null, parser );
286     } //-- java.util.Date getDateValue( String, String, XmlPullParser )
287 
288     /**
289      * Method getDateValue.
290      * 
291      * @param s a s object.
292      * @param parser a parser object.
293      * @param dateFormat a dateFormat object.
294      * @param attribute a attribute object.
295      * @throws XmlPullParserException XmlPullParserException if
296      * any.
297      * @return Date
298      */
299     private java.util.Date getDateValue( String s, String attribute, String dateFormat, XmlPullParser parser )
300         throws XmlPullParserException
301     {
302         if ( s != null )
303         {
304             String effectiveDateFormat = dateFormat;
305             if ( dateFormat == null )
306             {
307                 effectiveDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS";
308             }
309             if ( "long".equals( effectiveDateFormat ) )
310             {
311                 try
312                 {
313                     return new java.util.Date( Long.parseLong( s ) );
314                 }
315                 catch ( NumberFormatException e )
316                 {
317                     throw new XmlPullParserException( e.getMessage(), parser, e );
318                 }
319             }
320             else
321             {
322                 try
323                 {
324                     DateFormat dateParser = new java.text.SimpleDateFormat( effectiveDateFormat, java.util.Locale.US );
325                     return dateParser.parse( s );
326                 }
327                 catch ( java.text.ParseException e )
328                 {
329                     throw new XmlPullParserException( e.getMessage(), parser, e );
330                 }
331             }
332         }
333         return null;
334     } //-- java.util.Date getDateValue( String, String, String, XmlPullParser )
335 
336     /**
337      * Method getDoubleValue.
338      * 
339      * @param s a s object.
340      * @param strict a strict object.
341      * @param parser a parser object.
342      * @param attribute a attribute object.
343      * @throws XmlPullParserException XmlPullParserException if
344      * any.
345      * @return double
346      */
347     private double getDoubleValue( String s, String attribute, XmlPullParser parser, boolean strict )
348         throws XmlPullParserException
349     {
350         if ( s != null )
351         {
352             try
353             {
354                 return Double.valueOf( s ).doubleValue();
355             }
356             catch ( NumberFormatException nfe )
357             {
358                 if ( strict )
359                 {
360                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
361                 }
362             }
363         }
364         return 0;
365     } //-- double getDoubleValue( String, String, XmlPullParser, boolean )
366 
367     /**
368      * Method getFloatValue.
369      * 
370      * @param s a s object.
371      * @param strict a strict object.
372      * @param parser a parser object.
373      * @param attribute a attribute object.
374      * @throws XmlPullParserException XmlPullParserException if
375      * any.
376      * @return float
377      */
378     private float getFloatValue( String s, String attribute, XmlPullParser parser, boolean strict )
379         throws XmlPullParserException
380     {
381         if ( s != null )
382         {
383             try
384             {
385                 return Float.valueOf( s ).floatValue();
386             }
387             catch ( NumberFormatException nfe )
388             {
389                 if ( strict )
390                 {
391                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
392                 }
393             }
394         }
395         return 0;
396     } //-- float getFloatValue( String, String, XmlPullParser, boolean )
397 
398     /**
399      * Method getIntegerValue.
400      * 
401      * @param s a s object.
402      * @param strict a strict object.
403      * @param parser a parser object.
404      * @param attribute a attribute object.
405      * @throws XmlPullParserException XmlPullParserException if
406      * any.
407      * @return int
408      */
409     private int getIntegerValue( String s, String attribute, XmlPullParser parser, boolean strict )
410         throws XmlPullParserException
411     {
412         if ( s != null )
413         {
414             try
415             {
416                 return Integer.valueOf( s ).intValue();
417             }
418             catch ( NumberFormatException nfe )
419             {
420                 if ( strict )
421                 {
422                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be an integer", parser, nfe );
423                 }
424             }
425         }
426         return 0;
427     } //-- int getIntegerValue( String, String, XmlPullParser, boolean )
428 
429     /**
430      * Method getLongValue.
431      * 
432      * @param s a s object.
433      * @param strict a strict object.
434      * @param parser a parser object.
435      * @param attribute a attribute object.
436      * @throws XmlPullParserException XmlPullParserException if
437      * any.
438      * @return long
439      */
440     private long getLongValue( String s, String attribute, XmlPullParser parser, boolean strict )
441         throws XmlPullParserException
442     {
443         if ( s != null )
444         {
445             try
446             {
447                 return Long.valueOf( s ).longValue();
448             }
449             catch ( NumberFormatException nfe )
450             {
451                 if ( strict )
452                 {
453                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a long integer", parser, nfe );
454                 }
455             }
456         }
457         return 0;
458     } //-- long getLongValue( String, String, XmlPullParser, boolean )
459 
460     /**
461      * Method getRequiredAttributeValue.
462      * 
463      * @param s a s object.
464      * @param strict a strict object.
465      * @param parser a parser object.
466      * @param attribute a attribute object.
467      * @throws XmlPullParserException XmlPullParserException if
468      * any.
469      * @return String
470      */
471     private String getRequiredAttributeValue( String s, String attribute, XmlPullParser parser, boolean strict )
472         throws XmlPullParserException
473     {
474         if ( s == null )
475         {
476             if ( strict )
477             {
478                 throw new XmlPullParserException( "Missing required value for attribute '" + attribute + "'", parser, null );
479             }
480         }
481         return s;
482     } //-- String getRequiredAttributeValue( String, String, XmlPullParser, boolean )
483 
484     /**
485      * Method getShortValue.
486      * 
487      * @param s a s object.
488      * @param strict a strict object.
489      * @param parser a parser object.
490      * @param attribute a attribute object.
491      * @throws XmlPullParserException XmlPullParserException if
492      * any.
493      * @return short
494      */
495     private short getShortValue( String s, String attribute, XmlPullParser parser, boolean strict )
496         throws XmlPullParserException
497     {
498         if ( s != null )
499         {
500             try
501             {
502                 return Short.valueOf( s ).shortValue();
503             }
504             catch ( NumberFormatException nfe )
505             {
506                 if ( strict )
507                 {
508                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a short integer", parser, nfe );
509                 }
510             }
511         }
512         return 0;
513     } //-- short getShortValue( String, String, XmlPullParser, boolean )
514 
515     /**
516      * Method getTrimmedValue.
517      * 
518      * @param s a s object.
519      * @return String
520      */
521     private String getTrimmedValue( String s )
522     {
523         if ( s != null )
524         {
525             s = s.trim();
526         }
527         return s;
528     } //-- String getTrimmedValue( String )
529 
530     /**
531      * Method interpolatedTrimmed.
532      * 
533      * @param value a value object.
534      * @param context a context object.
535      * @return String
536      */
537     private String interpolatedTrimmed( String value, String context )
538     {
539         return getTrimmedValue( contentTransformer.transform( value, context ) );
540     } //-- String interpolatedTrimmed( String, String )
541 
542     /**
543      * Method nextTag.
544      * 
545      * @param parser a parser object.
546      * @throws IOException IOException if any.
547      * @throws XmlPullParserException XmlPullParserException if
548      * any.
549      * @return int
550      */
551     private int nextTag( XmlPullParser parser )
552         throws IOException, XmlPullParserException
553     {
554         int eventType = parser.next();
555         if ( eventType == XmlPullParser.TEXT )
556         {
557             eventType = parser.next();
558         }
559         if ( eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_TAG )
560         {
561             throw new XmlPullParserException( "expected START_TAG or END_TAG not " + XmlPullParser.TYPES[eventType], parser, null );
562         }
563         return eventType;
564     } //-- int nextTag( XmlPullParser )
565 
566     /**
567      * Method read.
568      * 
569      * @param parser a parser object.
570      * @param strict a strict object.
571      * @throws IOException IOException if any.
572      * @throws XmlPullParserException XmlPullParserException if
573      * any.
574      * @return DecorationModel
575      */
576     public DecorationModel read( XmlPullParser parser, boolean strict )
577         throws IOException, XmlPullParserException
578     {
579         DecorationModel decorationModel = null;
580         int eventType = parser.getEventType();
581         boolean parsed = false;
582         while ( eventType != XmlPullParser.END_DOCUMENT )
583         {
584             if ( eventType == XmlPullParser.START_TAG )
585             {
586                 if ( strict && ! "project".equals( parser.getName() ) )
587                 {
588                     throw new XmlPullParserException( "Expected root element 'project' but found '" + parser.getName() + "'", parser, null );
589                 }
590                 else if ( parsed )
591                 {
592                     // fallback, already expected a XmlPullParserException due to invalid XML
593                     throw new XmlPullParserException( "Duplicated tag: 'project'", parser, null );
594                 }
595                 decorationModel = parseDecorationModel( parser, strict );
596                 decorationModel.setModelEncoding( parser.getInputEncoding() );
597                 parsed = true;
598             }
599             eventType = parser.next();
600         }
601         if ( parsed )
602         {
603             return decorationModel;
604         }
605         throw new XmlPullParserException( "Expected root element 'project' but found no element at all: invalid XML document", parser, null );
606     } //-- DecorationModel read( XmlPullParser, boolean )
607 
608     /**
609      * @see XmlStreamReader
610      * 
611      * @param reader a reader object.
612      * @param strict a strict object.
613      * @throws IOException IOException if any.
614      * @throws XmlPullParserException XmlPullParserException if
615      * any.
616      * @return DecorationModel
617      */
618     public DecorationModel read( Reader reader, boolean strict )
619         throws IOException, XmlPullParserException
620     {
621         XmlPullParser parser = addDefaultEntities ? new MXParser(EntityReplacementMap.defaultEntityReplacementMap) : new MXParser( );
622 
623         parser.setInput( reader );
624 
625 
626         return read( parser, strict );
627     } //-- DecorationModel read( Reader, boolean )
628 
629     /**
630      * @see XmlStreamReader
631      * 
632      * @param reader a reader object.
633      * @throws IOException IOException if any.
634      * @throws XmlPullParserException XmlPullParserException if
635      * any.
636      * @return DecorationModel
637      */
638     public DecorationModel read( Reader reader )
639         throws IOException, XmlPullParserException
640     {
641         return read( reader, true );
642     } //-- DecorationModel read( Reader )
643 
644     /**
645      * Method read.
646      * 
647      * @param in a in object.
648      * @param strict a strict object.
649      * @throws IOException IOException if any.
650      * @throws XmlPullParserException XmlPullParserException if
651      * any.
652      * @return DecorationModel
653      */
654     public DecorationModel read( InputStream in, boolean strict )
655         throws IOException, XmlPullParserException
656     {
657         return read( new XmlStreamReader( in ), strict );
658     } //-- DecorationModel read( InputStream, boolean )
659 
660     /**
661      * Method read.
662      * 
663      * @param in a in object.
664      * @throws IOException IOException if any.
665      * @throws XmlPullParserException XmlPullParserException if
666      * any.
667      * @return DecorationModel
668      */
669     public DecorationModel read( InputStream in )
670         throws IOException, XmlPullParserException
671     {
672         return read( new XmlStreamReader( in ) );
673     } //-- DecorationModel read( InputStream )
674 
675     /**
676      * Method parseBanner.
677      * 
678      * @param parser a parser object.
679      * @param strict a strict object.
680      * @throws IOException IOException if any.
681      * @throws XmlPullParserException XmlPullParserException if
682      * any.
683      * @return Banner
684      */
685     private Banner parseBanner( XmlPullParser parser, boolean strict )
686         throws IOException, XmlPullParserException
687     {
688         String tagName = parser.getName();
689         Banner banner = new Banner();
690         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
691         {
692             String name = parser.getAttributeName( i );
693             String value = parser.getAttributeValue( i );
694 
695             if ( name.indexOf( ':' ) >= 0 )
696             {
697                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
698             }
699             else
700             {
701                 checkUnknownAttribute( parser, name, tagName, strict );
702             }
703         }
704         java.util.Set<String> parsed = new java.util.HashSet<String>();
705         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
706         {
707             if ( checkFieldWithDuplicate( parser, "name", null, parsed ) )
708             {
709                 banner.setName( interpolatedTrimmed( parser.nextText(), "name" ) );
710             }
711             else if ( checkFieldWithDuplicate( parser, "src", null, parsed ) )
712             {
713                 banner.setSrc( interpolatedTrimmed( parser.nextText(), "src" ) );
714             }
715             else if ( checkFieldWithDuplicate( parser, "alt", null, parsed ) )
716             {
717                 banner.setAlt( interpolatedTrimmed( parser.nextText(), "alt" ) );
718             }
719             else if ( checkFieldWithDuplicate( parser, "href", null, parsed ) )
720             {
721                 banner.setHref( interpolatedTrimmed( parser.nextText(), "href" ) );
722             }
723             else if ( checkFieldWithDuplicate( parser, "border", null, parsed ) )
724             {
725                 banner.setBorder( interpolatedTrimmed( parser.nextText(), "border" ) );
726             }
727             else if ( checkFieldWithDuplicate( parser, "width", null, parsed ) )
728             {
729                 banner.setWidth( interpolatedTrimmed( parser.nextText(), "width" ) );
730             }
731             else if ( checkFieldWithDuplicate( parser, "height", null, parsed ) )
732             {
733                 banner.setHeight( interpolatedTrimmed( parser.nextText(), "height" ) );
734             }
735             else if ( checkFieldWithDuplicate( parser, "title", null, parsed ) )
736             {
737                 banner.setTitle( interpolatedTrimmed( parser.nextText(), "title" ) );
738             }
739             else
740             {
741                 checkUnknownElement( parser, strict );
742             }
743         }
744         return banner;
745     } //-- Banner parseBanner( XmlPullParser, boolean )
746 
747     /**
748      * Method parseBody.
749      * 
750      * @param parser a parser object.
751      * @param strict a strict object.
752      * @throws IOException IOException if any.
753      * @throws XmlPullParserException XmlPullParserException if
754      * any.
755      * @return Body
756      */
757     private Body parseBody( XmlPullParser parser, boolean strict )
758         throws IOException, XmlPullParserException
759     {
760         String tagName = parser.getName();
761         Body body = new Body();
762         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
763         {
764             String name = parser.getAttributeName( i );
765             String value = parser.getAttributeValue( i );
766 
767             if ( name.indexOf( ':' ) >= 0 )
768             {
769                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
770             }
771             else
772             {
773                 checkUnknownAttribute( parser, name, tagName, strict );
774             }
775         }
776         java.util.Set<String> parsed = new java.util.HashSet<String>();
777         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
778         {
779             if ( checkFieldWithDuplicate( parser, "head", null, parsed ) )
780             {
781                 body.setHead( interpolatedTrimmed( parser.nextText(), "head" ) );
782             }
783             else if ( checkFieldWithDuplicate( parser, "links", null, parsed ) )
784             {
785                 java.util.List<LinkItem> links = new java.util.ArrayList<LinkItem>();
786                 while ( parser.nextTag() == XmlPullParser.START_TAG )
787                 {
788                     if ( "item".equals( parser.getName() ) )
789                     {
790                         links.add( parseLinkItem( parser, strict ) );
791                     }
792                     else
793                     {
794                         checkUnknownElement( parser, strict );
795                     }
796                 }
797                 body.setLinks( links );
798             }
799             else if ( checkFieldWithDuplicate( parser, "breadcrumbs", null, parsed ) )
800             {
801                 java.util.List<LinkItem> breadcrumbs = new java.util.ArrayList<LinkItem>();
802                 while ( parser.nextTag() == XmlPullParser.START_TAG )
803                 {
804                     if ( "item".equals( parser.getName() ) )
805                     {
806                         breadcrumbs.add( parseLinkItem( parser, strict ) );
807                     }
808                     else
809                     {
810                         checkUnknownElement( parser, strict );
811                     }
812                 }
813                 body.setBreadcrumbs( breadcrumbs );
814             }
815             else if ( "menu".equals( parser.getName() ) )
816             {
817                 java.util.List<Menu> menus = body.getMenus();
818                 if ( menus == null )
819                 {
820                     menus = new java.util.ArrayList<Menu>();
821                 }
822                 menus.add( parseMenu( parser, strict ) );
823                 body.setMenus( menus );
824             }
825             else if ( checkFieldWithDuplicate( parser, "footer", null, parsed ) )
826             {
827                 body.setFooter( interpolatedTrimmed( parser.nextText(), "footer" ) );
828             }
829             else
830             {
831                 checkUnknownElement( parser, strict );
832             }
833         }
834         return body;
835     } //-- Body parseBody( XmlPullParser, boolean )
836 
837     /**
838      * Method parseDecorationModel.
839      * 
840      * @param parser a parser object.
841      * @param strict a strict object.
842      * @throws IOException IOException if any.
843      * @throws XmlPullParserException XmlPullParserException if
844      * any.
845      * @return DecorationModel
846      */
847     private DecorationModel parseDecorationModel( XmlPullParser parser, boolean strict )
848         throws IOException, XmlPullParserException
849     {
850         String tagName = parser.getName();
851         DecorationModel decorationModel = new DecorationModel();
852         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
853         {
854             String name = parser.getAttributeName( i );
855             String value = parser.getAttributeValue( i );
856 
857             if ( name.indexOf( ':' ) >= 0 )
858             {
859                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
860             }
861             else if ( "xmlns".equals( name ) )
862             {
863                 // ignore xmlns attribute in root class, which is a reserved attribute name
864             }
865             else if ( "name".equals( name ) )
866             {
867                 decorationModel.setName( interpolatedTrimmed( value, "name" ) );
868             }
869             else if ( "combine.self".equals( name ) )
870             {
871                 decorationModel.setCombineSelf( interpolatedTrimmed( value, "combine.self" ) );
872             }
873             else
874             {
875                 checkUnknownAttribute( parser, name, tagName, strict );
876             }
877         }
878         java.util.Set<String> parsed = new java.util.HashSet<String>();
879         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
880         {
881             if ( checkFieldWithDuplicate( parser, "bannerLeft", null, parsed ) )
882             {
883                 decorationModel.setBannerLeft( parseBanner( parser, strict ) );
884             }
885             else if ( checkFieldWithDuplicate( parser, "bannerRight", null, parsed ) )
886             {
887                 decorationModel.setBannerRight( parseBanner( parser, strict ) );
888             }
889             else if ( checkFieldWithDuplicate( parser, "publishDate", null, parsed ) )
890             {
891                 decorationModel.setPublishDate( parsePublishDate( parser, strict ) );
892             }
893             else if ( checkFieldWithDuplicate( parser, "version", null, parsed ) )
894             {
895                 decorationModel.setVersion( parseVersion( parser, strict ) );
896             }
897             else if ( checkFieldWithDuplicate( parser, "edit", null, parsed ) )
898             {
899                 decorationModel.setEdit( interpolatedTrimmed( parser.nextText(), "edit" ) );
900             }
901             else if ( checkFieldWithDuplicate( parser, "poweredBy", null, parsed ) )
902             {
903                 java.util.List<Logo> poweredBy = new java.util.ArrayList<Logo>();
904                 while ( parser.nextTag() == XmlPullParser.START_TAG )
905                 {
906                     if ( "logo".equals( parser.getName() ) )
907                     {
908                         poweredBy.add( parseLogo( parser, strict ) );
909                     }
910                     else
911                     {
912                         checkUnknownElement( parser, strict );
913                     }
914                 }
915                 decorationModel.setPoweredBy( poweredBy );
916             }
917             else if ( checkFieldWithDuplicate( parser, "skin", null, parsed ) )
918             {
919                 decorationModel.setSkin( parseSkin( parser, strict ) );
920             }
921             else if ( checkFieldWithDuplicate( parser, "body", null, parsed ) )
922             {
923                 decorationModel.setBody( parseBody( parser, strict ) );
924             }
925             else if ( checkFieldWithDuplicate( parser, "custom", null, parsed ) )
926             {
927                 decorationModel.setCustom( org.codehaus.plexus.util.xml.Xpp3DomBuilder.build( parser, true ) );
928             }
929             else
930             {
931                 checkUnknownElement( parser, strict );
932             }
933         }
934         return decorationModel;
935     } //-- DecorationModel parseDecorationModel( XmlPullParser, boolean )
936 
937     /**
938      * Method parseLinkItem.
939      * 
940      * @param parser a parser object.
941      * @param strict a strict object.
942      * @throws IOException IOException if any.
943      * @throws XmlPullParserException XmlPullParserException if
944      * any.
945      * @return LinkItem
946      */
947     private LinkItem parseLinkItem( XmlPullParser parser, boolean strict )
948         throws IOException, XmlPullParserException
949     {
950         String tagName = parser.getName();
951         LinkItem linkItem = new LinkItem();
952         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
953         {
954             String name = parser.getAttributeName( i );
955             String value = parser.getAttributeValue( i );
956 
957             if ( name.indexOf( ':' ) >= 0 )
958             {
959                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
960             }
961             else if ( "name".equals( name ) )
962             {
963                 linkItem.setName( interpolatedTrimmed( value, "name" ) );
964             }
965             else if ( "href".equals( name ) )
966             {
967                 linkItem.setHref( interpolatedTrimmed( value, "href" ) );
968             }
969             else if ( "img".equals( name ) )
970             {
971                 linkItem.setImg( interpolatedTrimmed( value, "img" ) );
972             }
973             else if ( "position".equals( name ) )
974             {
975                 linkItem.setPosition( interpolatedTrimmed( value, "position" ) );
976             }
977             else if ( "alt".equals( name ) )
978             {
979                 linkItem.setAlt( interpolatedTrimmed( value, "alt" ) );
980             }
981             else if ( "border".equals( name ) )
982             {
983                 linkItem.setBorder( interpolatedTrimmed( value, "border" ) );
984             }
985             else if ( "width".equals( name ) )
986             {
987                 linkItem.setWidth( interpolatedTrimmed( value, "width" ) );
988             }
989             else if ( "height".equals( name ) )
990             {
991                 linkItem.setHeight( interpolatedTrimmed( value, "height" ) );
992             }
993             else if ( "target".equals( name ) )
994             {
995                 linkItem.setTarget( interpolatedTrimmed( value, "target" ) );
996             }
997             else if ( "title".equals( name ) )
998             {
999                 linkItem.setTitle( interpolatedTrimmed( value, "title" ) );
1000             }
1001             else
1002             {
1003                 checkUnknownAttribute( parser, name, tagName, strict );
1004             }
1005         }
1006         java.util.Set<String> parsed = new java.util.HashSet<String>();
1007         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1008         {
1009             checkUnknownElement( parser, strict );
1010         }
1011         return linkItem;
1012     } //-- LinkItem parseLinkItem( XmlPullParser, boolean )
1013 
1014     /**
1015      * Method parseLogo.
1016      * 
1017      * @param parser a parser object.
1018      * @param strict a strict object.
1019      * @throws IOException IOException if any.
1020      * @throws XmlPullParserException XmlPullParserException if
1021      * any.
1022      * @return Logo
1023      */
1024     private Logo parseLogo( XmlPullParser parser, boolean strict )
1025         throws IOException, XmlPullParserException
1026     {
1027         String tagName = parser.getName();
1028         Logo logo = new Logo();
1029         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1030         {
1031             String name = parser.getAttributeName( i );
1032             String value = parser.getAttributeValue( i );
1033 
1034             if ( name.indexOf( ':' ) >= 0 )
1035             {
1036                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1037             }
1038             else if ( "name".equals( name ) )
1039             {
1040                 logo.setName( interpolatedTrimmed( value, "name" ) );
1041             }
1042             else if ( "href".equals( name ) )
1043             {
1044                 logo.setHref( interpolatedTrimmed( value, "href" ) );
1045             }
1046             else if ( "img".equals( name ) )
1047             {
1048                 logo.setImg( interpolatedTrimmed( value, "img" ) );
1049             }
1050             else if ( "position".equals( name ) )
1051             {
1052                 logo.setPosition( interpolatedTrimmed( value, "position" ) );
1053             }
1054             else if ( "alt".equals( name ) )
1055             {
1056                 logo.setAlt( interpolatedTrimmed( value, "alt" ) );
1057             }
1058             else if ( "border".equals( name ) )
1059             {
1060                 logo.setBorder( interpolatedTrimmed( value, "border" ) );
1061             }
1062             else if ( "width".equals( name ) )
1063             {
1064                 logo.setWidth( interpolatedTrimmed( value, "width" ) );
1065             }
1066             else if ( "height".equals( name ) )
1067             {
1068                 logo.setHeight( interpolatedTrimmed( value, "height" ) );
1069             }
1070             else if ( "target".equals( name ) )
1071             {
1072                 logo.setTarget( interpolatedTrimmed( value, "target" ) );
1073             }
1074             else if ( "title".equals( name ) )
1075             {
1076                 logo.setTitle( interpolatedTrimmed( value, "title" ) );
1077             }
1078             else
1079             {
1080                 checkUnknownAttribute( parser, name, tagName, strict );
1081             }
1082         }
1083         java.util.Set<String> parsed = new java.util.HashSet<String>();
1084         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1085         {
1086             checkUnknownElement( parser, strict );
1087         }
1088         return logo;
1089     } //-- Logo parseLogo( XmlPullParser, boolean )
1090 
1091     /**
1092      * Method parseMenu.
1093      * 
1094      * @param parser a parser object.
1095      * @param strict a strict object.
1096      * @throws IOException IOException if any.
1097      * @throws XmlPullParserException XmlPullParserException if
1098      * any.
1099      * @return Menu
1100      */
1101     private Menu parseMenu( XmlPullParser parser, boolean strict )
1102         throws IOException, XmlPullParserException
1103     {
1104         String tagName = parser.getName();
1105         Menu menu = new Menu();
1106         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1107         {
1108             String name = parser.getAttributeName( i );
1109             String value = parser.getAttributeValue( i );
1110 
1111             if ( name.indexOf( ':' ) >= 0 )
1112             {
1113                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1114             }
1115             else if ( "name".equals( name ) )
1116             {
1117                 menu.setName( interpolatedTrimmed( value, "name" ) );
1118             }
1119             else if ( "inherit".equals( name ) )
1120             {
1121                 menu.setInherit( interpolatedTrimmed( value, "inherit" ) );
1122             }
1123             else if ( "inheritAsRef".equals( name ) )
1124             {
1125                 menu.setInheritAsRef( getBooleanValue( interpolatedTrimmed( value, "inheritAsRef" ), "inheritAsRef", parser, "false" ) );
1126             }
1127             else if ( "ref".equals( name ) )
1128             {
1129                 menu.setRef( interpolatedTrimmed( value, "ref" ) );
1130             }
1131             else if ( "img".equals( name ) )
1132             {
1133                 menu.setImg( interpolatedTrimmed( value, "img" ) );
1134             }
1135             else if ( "alt".equals( name ) )
1136             {
1137                 menu.setAlt( interpolatedTrimmed( value, "alt" ) );
1138             }
1139             else if ( "position".equals( name ) )
1140             {
1141                 menu.setPosition( interpolatedTrimmed( value, "position" ) );
1142             }
1143             else if ( "border".equals( name ) )
1144             {
1145                 menu.setBorder( interpolatedTrimmed( value, "border" ) );
1146             }
1147             else if ( "width".equals( name ) )
1148             {
1149                 menu.setWidth( interpolatedTrimmed( value, "width" ) );
1150             }
1151             else if ( "height".equals( name ) )
1152             {
1153                 menu.setHeight( interpolatedTrimmed( value, "height" ) );
1154             }
1155             else if ( "title".equals( name ) )
1156             {
1157                 menu.setTitle( interpolatedTrimmed( value, "title" ) );
1158             }
1159             else
1160             {
1161                 checkUnknownAttribute( parser, name, tagName, strict );
1162             }
1163         }
1164         java.util.Set<String> parsed = new java.util.HashSet<String>();
1165         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1166         {
1167             if ( "item".equals( parser.getName() ) )
1168             {
1169                 java.util.List<MenuItem> items = menu.getItems();
1170                 if ( items == null )
1171                 {
1172                     items = new java.util.ArrayList<MenuItem>();
1173                 }
1174                 items.add( parseMenuItem( parser, strict ) );
1175                 menu.setItems( items );
1176             }
1177             else
1178             {
1179                 checkUnknownElement( parser, strict );
1180             }
1181         }
1182         return menu;
1183     } //-- Menu parseMenu( XmlPullParser, boolean )
1184 
1185     /**
1186      * Method parseMenuItem.
1187      * 
1188      * @param parser a parser object.
1189      * @param strict a strict object.
1190      * @throws IOException IOException if any.
1191      * @throws XmlPullParserException XmlPullParserException if
1192      * any.
1193      * @return MenuItem
1194      */
1195     private MenuItem parseMenuItem( XmlPullParser parser, boolean strict )
1196         throws IOException, XmlPullParserException
1197     {
1198         String tagName = parser.getName();
1199         MenuItem menuItem = new MenuItem();
1200         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1201         {
1202             String name = parser.getAttributeName( i );
1203             String value = parser.getAttributeValue( i );
1204 
1205             if ( name.indexOf( ':' ) >= 0 )
1206             {
1207                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1208             }
1209             else if ( "collapse".equals( name ) )
1210             {
1211                 menuItem.setCollapse( getBooleanValue( interpolatedTrimmed( value, "collapse" ), "collapse", parser, "false" ) );
1212             }
1213             else if ( "ref".equals( name ) )
1214             {
1215                 menuItem.setRef( interpolatedTrimmed( value, "ref" ) );
1216             }
1217             else if ( "name".equals( name ) )
1218             {
1219                 menuItem.setName( interpolatedTrimmed( value, "name" ) );
1220             }
1221             else if ( "href".equals( name ) )
1222             {
1223                 menuItem.setHref( interpolatedTrimmed( value, "href" ) );
1224             }
1225             else if ( "img".equals( name ) )
1226             {
1227                 menuItem.setImg( interpolatedTrimmed( value, "img" ) );
1228             }
1229             else if ( "position".equals( name ) )
1230             {
1231                 menuItem.setPosition( interpolatedTrimmed( value, "position" ) );
1232             }
1233             else if ( "alt".equals( name ) )
1234             {
1235                 menuItem.setAlt( interpolatedTrimmed( value, "alt" ) );
1236             }
1237             else if ( "border".equals( name ) )
1238             {
1239                 menuItem.setBorder( interpolatedTrimmed( value, "border" ) );
1240             }
1241             else if ( "width".equals( name ) )
1242             {
1243                 menuItem.setWidth( interpolatedTrimmed( value, "width" ) );
1244             }
1245             else if ( "height".equals( name ) )
1246             {
1247                 menuItem.setHeight( interpolatedTrimmed( value, "height" ) );
1248             }
1249             else if ( "target".equals( name ) )
1250             {
1251                 menuItem.setTarget( interpolatedTrimmed( value, "target" ) );
1252             }
1253             else if ( "title".equals( name ) )
1254             {
1255                 menuItem.setTitle( interpolatedTrimmed( value, "title" ) );
1256             }
1257             else
1258             {
1259                 checkUnknownAttribute( parser, name, tagName, strict );
1260             }
1261         }
1262         java.util.Set<String> parsed = new java.util.HashSet<String>();
1263         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1264         {
1265             if ( checkFieldWithDuplicate( parser, "description", null, parsed ) )
1266             {
1267                 menuItem.setDescription( interpolatedTrimmed( parser.nextText(), "description" ) );
1268             }
1269             else if ( "item".equals( parser.getName() ) )
1270             {
1271                 java.util.List<MenuItem> items = menuItem.getItems();
1272                 if ( items == null )
1273                 {
1274                     items = new java.util.ArrayList<MenuItem>();
1275                 }
1276                 items.add( parseMenuItem( parser, strict ) );
1277                 menuItem.setItems( items );
1278             }
1279             else
1280             {
1281                 checkUnknownElement( parser, strict );
1282             }
1283         }
1284         return menuItem;
1285     } //-- MenuItem parseMenuItem( XmlPullParser, boolean )
1286 
1287     /**
1288      * Method parsePublishDate.
1289      * 
1290      * @param parser a parser object.
1291      * @param strict a strict object.
1292      * @throws IOException IOException if any.
1293      * @throws XmlPullParserException XmlPullParserException if
1294      * any.
1295      * @return PublishDate
1296      */
1297     private PublishDate parsePublishDate( XmlPullParser parser, boolean strict )
1298         throws IOException, XmlPullParserException
1299     {
1300         String tagName = parser.getName();
1301         PublishDate publishDate = new PublishDate();
1302         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1303         {
1304             String name = parser.getAttributeName( i );
1305             String value = parser.getAttributeValue( i );
1306 
1307             if ( name.indexOf( ':' ) >= 0 )
1308             {
1309                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1310             }
1311             else if ( "position".equals( name ) )
1312             {
1313                 publishDate.setPosition( interpolatedTrimmed( value, "position" ) );
1314             }
1315             else if ( "format".equals( name ) )
1316             {
1317                 publishDate.setFormat( interpolatedTrimmed( value, "format" ) );
1318             }
1319             else if ( "timezone".equals( name ) )
1320             {
1321                 publishDate.setTimezone( interpolatedTrimmed( value, "timezone" ) );
1322             }
1323             else
1324             {
1325                 checkUnknownAttribute( parser, name, tagName, strict );
1326             }
1327         }
1328         java.util.Set<String> parsed = new java.util.HashSet<String>();
1329         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1330         {
1331             checkUnknownElement( parser, strict );
1332         }
1333         return publishDate;
1334     } //-- PublishDate parsePublishDate( XmlPullParser, boolean )
1335 
1336     /**
1337      * Method parseSkin.
1338      * 
1339      * @param parser a parser object.
1340      * @param strict a strict object.
1341      * @throws IOException IOException if any.
1342      * @throws XmlPullParserException XmlPullParserException if
1343      * any.
1344      * @return Skin
1345      */
1346     private Skin parseSkin( XmlPullParser parser, boolean strict )
1347         throws IOException, XmlPullParserException
1348     {
1349         String tagName = parser.getName();
1350         Skin skin = new Skin();
1351         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1352         {
1353             String name = parser.getAttributeName( i );
1354             String value = parser.getAttributeValue( i );
1355 
1356             if ( name.indexOf( ':' ) >= 0 )
1357             {
1358                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1359             }
1360             else
1361             {
1362                 checkUnknownAttribute( parser, name, tagName, strict );
1363             }
1364         }
1365         java.util.Set<String> parsed = new java.util.HashSet<String>();
1366         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1367         {
1368             if ( checkFieldWithDuplicate( parser, "groupId", null, parsed ) )
1369             {
1370                 skin.setGroupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
1371             }
1372             else if ( checkFieldWithDuplicate( parser, "artifactId", null, parsed ) )
1373             {
1374                 skin.setArtifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
1375             }
1376             else if ( checkFieldWithDuplicate( parser, "version", null, parsed ) )
1377             {
1378                 skin.setVersion( interpolatedTrimmed( parser.nextText(), "version" ) );
1379             }
1380             else
1381             {
1382                 checkUnknownElement( parser, strict );
1383             }
1384         }
1385         return skin;
1386     } //-- Skin parseSkin( XmlPullParser, boolean )
1387 
1388     /**
1389      * Method parseVersion.
1390      * 
1391      * @param parser a parser object.
1392      * @param strict a strict object.
1393      * @throws IOException IOException if any.
1394      * @throws XmlPullParserException XmlPullParserException if
1395      * any.
1396      * @return Version
1397      */
1398     private Version parseVersion( XmlPullParser parser, boolean strict )
1399         throws IOException, XmlPullParserException
1400     {
1401         String tagName = parser.getName();
1402         Version version = new Version();
1403         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1404         {
1405             String name = parser.getAttributeName( i );
1406             String value = parser.getAttributeValue( i );
1407 
1408             if ( name.indexOf( ':' ) >= 0 )
1409             {
1410                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1411             }
1412             else if ( "position".equals( name ) )
1413             {
1414                 version.setPosition( interpolatedTrimmed( value, "position" ) );
1415             }
1416             else
1417             {
1418                 checkUnknownAttribute( parser, name, tagName, strict );
1419             }
1420         }
1421         java.util.Set<String> parsed = new java.util.HashSet<String>();
1422         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1423         {
1424             checkUnknownElement( parser, strict );
1425         }
1426         return version;
1427     } //-- Version parseVersion( XmlPullParser, boolean )
1428 
1429     /**
1430      * Sets the state of the "add default entities" flag.
1431      * 
1432      * @param addDefaultEntities a addDefaultEntities object.
1433      */
1434     public void setAddDefaultEntities( boolean addDefaultEntities )
1435     {
1436         this.addDefaultEntities = addDefaultEntities;
1437     } //-- void setAddDefaultEntities( boolean )
1438 
1439     public static interface ContentTransformer
1440 {
1441     /**
1442      * Interpolate the value read from the xpp3 document
1443      * @param source The source value
1444      * @param fieldName A description of the field being interpolated. The implementation may use this to
1445      *                           log stuff.
1446      * @return The interpolated value.
1447      */
1448     String transform( String source, String fieldName );
1449 }
1450 
1451 }