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.artifact.repository.metadata.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.artifact.repository.metadata.Metadata;
35  import org.apache.maven.artifact.repository.metadata.Plugin;
36  import org.apache.maven.artifact.repository.metadata.Snapshot;
37  import org.apache.maven.artifact.repository.metadata.SnapshotVersion;
38  import org.apache.maven.artifact.repository.metadata.Versioning;
39  import org.codehaus.plexus.util.xml.XmlStreamReader;
40  import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
41  import org.codehaus.plexus.util.xml.pull.MXParser;
42  import org.codehaus.plexus.util.xml.pull.XmlPullParser;
43  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
44  
45  /**
46   * Class MetadataXpp3Reader.
47   * 
48   * @version $Revision$ $Date$
49   */
50  @SuppressWarnings( "all" )
51  public class MetadataXpp3Reader
52  {
53  
54        //--------------------------/
55       //- Class/Member Variables -/
56      //--------------------------/
57  
58      /**
59       * If set the parser will be loaded with all single characters
60       * from the XHTML specification.
61       * The entities used:
62       * <ul>
63       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent</li>
64       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent</li>
65       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</li>
66       * </ul>
67       */
68      private boolean addDefaultEntities = true;
69  
70      /**
71       * Field contentTransformer.
72       */
73      public final ContentTransformer contentTransformer;
74  
75  
76        //----------------/
77       //- Constructors -/
78      //----------------/
79  
80      public MetadataXpp3Reader()
81      {
82          this( new ContentTransformer()
83          {
84              public String transform( String source, String fieldName )
85              {
86                  return source;
87              }
88          } );
89      } //-- org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader()
90  
91      public MetadataXpp3Reader(ContentTransformer contentTransformer)
92      {
93          this.contentTransformer = contentTransformer;
94      } //-- org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader(ContentTransformer)
95  
96  
97        //-----------/
98       //- Methods -/
99      //-----------/
100 
101     /**
102      * Method checkFieldWithDuplicate.
103      * 
104      * @param parser a parser object.
105      * @param parsed a parsed object.
106      * @param alias a alias object.
107      * @param tagName a tagName object.
108      * @throws XmlPullParserException XmlPullParserException if
109      * any.
110      * @return boolean
111      */
112     private boolean checkFieldWithDuplicate( XmlPullParser parser, String tagName, String alias, java.util.Set<String> parsed )
113         throws XmlPullParserException
114     {
115         if ( !( parser.getName().equals( tagName ) || parser.getName().equals( alias ) ) )
116         {
117             return false;
118         }
119         if ( !parsed.add( tagName ) )
120         {
121             throw new XmlPullParserException( "Duplicated tag: '" + tagName + "'", parser, null );
122         }
123         return true;
124     } //-- boolean checkFieldWithDuplicate( XmlPullParser, String, String, java.util.Set )
125 
126     /**
127      * Method checkUnknownAttribute.
128      * 
129      * @param parser a parser object.
130      * @param strict a strict object.
131      * @param tagName a tagName object.
132      * @param attribute a attribute object.
133      * @throws XmlPullParserException XmlPullParserException if
134      * any.
135      * @throws IOException IOException if any.
136      */
137     private void checkUnknownAttribute( XmlPullParser parser, String attribute, String tagName, boolean strict )
138         throws XmlPullParserException, IOException
139     {
140         // strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
141         if ( strict )
142         {
143             throw new XmlPullParserException( "Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser, null );
144         }
145     } //-- void checkUnknownAttribute( XmlPullParser, String, String, boolean )
146 
147     /**
148      * Method checkUnknownElement.
149      * 
150      * @param parser a parser object.
151      * @param strict a strict object.
152      * @throws XmlPullParserException XmlPullParserException if
153      * any.
154      * @throws IOException IOException if any.
155      */
156     private void checkUnknownElement( XmlPullParser parser, boolean strict )
157         throws XmlPullParserException, IOException
158     {
159         if ( strict )
160         {
161             throw new XmlPullParserException( "Unrecognised tag: '" + parser.getName() + "'", parser, null );
162         }
163 
164         for ( int unrecognizedTagCount = 1; unrecognizedTagCount > 0; )
165         {
166             int eventType = parser.next();
167             if ( eventType == XmlPullParser.START_TAG )
168             {
169                 unrecognizedTagCount++;
170             }
171             else if ( eventType == XmlPullParser.END_TAG )
172             {
173                 unrecognizedTagCount--;
174             }
175         }
176     } //-- void checkUnknownElement( XmlPullParser, boolean )
177 
178     /**
179      * Returns the state of the "add default entities" flag.
180      * 
181      * @return boolean
182      */
183     public boolean getAddDefaultEntities()
184     {
185         return addDefaultEntities;
186     } //-- boolean getAddDefaultEntities()
187 
188     /**
189      * Method getBooleanValue.
190      * 
191      * @param s a s object.
192      * @param parser a parser object.
193      * @param attribute a attribute object.
194      * @throws XmlPullParserException XmlPullParserException if
195      * any.
196      * @return boolean
197      */
198     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser )
199         throws XmlPullParserException
200     {
201         return getBooleanValue( s, attribute, parser, null );
202     } //-- boolean getBooleanValue( String, String, XmlPullParser )
203 
204     /**
205      * Method getBooleanValue.
206      * 
207      * @param s a s object.
208      * @param defaultValue a defaultValue object.
209      * @param parser a parser object.
210      * @param attribute a attribute object.
211      * @throws XmlPullParserException XmlPullParserException if
212      * any.
213      * @return boolean
214      */
215     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser, String defaultValue )
216         throws XmlPullParserException
217     {
218         if ( s != null && s.length() != 0 )
219         {
220             return Boolean.valueOf( s ).booleanValue();
221         }
222         if ( defaultValue != null )
223         {
224             return Boolean.valueOf( defaultValue ).booleanValue();
225         }
226         return false;
227     } //-- boolean getBooleanValue( String, String, XmlPullParser, String )
228 
229     /**
230      * Method getByteValue.
231      * 
232      * @param s a s object.
233      * @param strict a strict object.
234      * @param parser a parser object.
235      * @param attribute a attribute object.
236      * @throws XmlPullParserException XmlPullParserException if
237      * any.
238      * @return byte
239      */
240     private byte getByteValue( String s, String attribute, XmlPullParser parser, boolean strict )
241         throws XmlPullParserException
242     {
243         if ( s != null )
244         {
245             try
246             {
247                 return Byte.valueOf( s ).byteValue();
248             }
249             catch ( NumberFormatException nfe )
250             {
251                 if ( strict )
252                 {
253                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a byte", parser, nfe );
254                 }
255             }
256         }
257         return 0;
258     } //-- byte getByteValue( String, String, XmlPullParser, boolean )
259 
260     /**
261      * Method getCharacterValue.
262      * 
263      * @param s a s object.
264      * @param parser a parser object.
265      * @param attribute a attribute object.
266      * @throws XmlPullParserException XmlPullParserException if
267      * any.
268      * @return char
269      */
270     private char getCharacterValue( String s, String attribute, XmlPullParser parser )
271         throws XmlPullParserException
272     {
273         if ( s != null )
274         {
275             return s.charAt( 0 );
276         }
277         return 0;
278     } //-- char getCharacterValue( String, String, XmlPullParser )
279 
280     /**
281      * Method getDateValue.
282      * 
283      * @param s a s object.
284      * @param parser a parser object.
285      * @param attribute a attribute object.
286      * @throws XmlPullParserException XmlPullParserException if
287      * any.
288      * @return Date
289      */
290     private java.util.Date getDateValue( String s, String attribute, XmlPullParser parser )
291         throws XmlPullParserException
292     {
293         return getDateValue( s, attribute, null, parser );
294     } //-- java.util.Date getDateValue( String, String, XmlPullParser )
295 
296     /**
297      * Method getDateValue.
298      * 
299      * @param s a s object.
300      * @param parser a parser object.
301      * @param dateFormat a dateFormat object.
302      * @param attribute a attribute object.
303      * @throws XmlPullParserException XmlPullParserException if
304      * any.
305      * @return Date
306      */
307     private java.util.Date getDateValue( String s, String attribute, String dateFormat, XmlPullParser parser )
308         throws XmlPullParserException
309     {
310         if ( s != null )
311         {
312             String effectiveDateFormat = dateFormat;
313             if ( dateFormat == null )
314             {
315                 effectiveDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS";
316             }
317             if ( "long".equals( effectiveDateFormat ) )
318             {
319                 try
320                 {
321                     return new java.util.Date( Long.parseLong( s ) );
322                 }
323                 catch ( NumberFormatException e )
324                 {
325                     throw new XmlPullParserException( e.getMessage(), parser, e );
326                 }
327             }
328             else
329             {
330                 try
331                 {
332                     DateFormat dateParser = new java.text.SimpleDateFormat( effectiveDateFormat, java.util.Locale.US );
333                     return dateParser.parse( s );
334                 }
335                 catch ( java.text.ParseException e )
336                 {
337                     throw new XmlPullParserException( e.getMessage(), parser, e );
338                 }
339             }
340         }
341         return null;
342     } //-- java.util.Date getDateValue( String, String, String, XmlPullParser )
343 
344     /**
345      * Method getDoubleValue.
346      * 
347      * @param s a s object.
348      * @param strict a strict object.
349      * @param parser a parser object.
350      * @param attribute a attribute object.
351      * @throws XmlPullParserException XmlPullParserException if
352      * any.
353      * @return double
354      */
355     private double getDoubleValue( String s, String attribute, XmlPullParser parser, boolean strict )
356         throws XmlPullParserException
357     {
358         if ( s != null )
359         {
360             try
361             {
362                 return Double.valueOf( s ).doubleValue();
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     } //-- double getDoubleValue( String, String, XmlPullParser, boolean )
374 
375     /**
376      * Method getFloatValue.
377      * 
378      * @param s a s object.
379      * @param strict a strict object.
380      * @param parser a parser object.
381      * @param attribute a attribute object.
382      * @throws XmlPullParserException XmlPullParserException if
383      * any.
384      * @return float
385      */
386     private float getFloatValue( String s, String attribute, XmlPullParser parser, boolean strict )
387         throws XmlPullParserException
388     {
389         if ( s != null )
390         {
391             try
392             {
393                 return Float.valueOf( s ).floatValue();
394             }
395             catch ( NumberFormatException nfe )
396             {
397                 if ( strict )
398                 {
399                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
400                 }
401             }
402         }
403         return 0;
404     } //-- float getFloatValue( String, String, XmlPullParser, boolean )
405 
406     /**
407      * Method getIntegerValue.
408      * 
409      * @param s a s object.
410      * @param strict a strict object.
411      * @param parser a parser object.
412      * @param attribute a attribute object.
413      * @throws XmlPullParserException XmlPullParserException if
414      * any.
415      * @return int
416      */
417     private int getIntegerValue( String s, String attribute, XmlPullParser parser, boolean strict )
418         throws XmlPullParserException
419     {
420         if ( s != null )
421         {
422             try
423             {
424                 return Integer.valueOf( s ).intValue();
425             }
426             catch ( NumberFormatException nfe )
427             {
428                 if ( strict )
429                 {
430                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be an integer", parser, nfe );
431                 }
432             }
433         }
434         return 0;
435     } //-- int getIntegerValue( String, String, XmlPullParser, boolean )
436 
437     /**
438      * Method getLongValue.
439      * 
440      * @param s a s object.
441      * @param strict a strict object.
442      * @param parser a parser object.
443      * @param attribute a attribute object.
444      * @throws XmlPullParserException XmlPullParserException if
445      * any.
446      * @return long
447      */
448     private long getLongValue( String s, String attribute, XmlPullParser parser, boolean strict )
449         throws XmlPullParserException
450     {
451         if ( s != null )
452         {
453             try
454             {
455                 return Long.valueOf( s ).longValue();
456             }
457             catch ( NumberFormatException nfe )
458             {
459                 if ( strict )
460                 {
461                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a long integer", parser, nfe );
462                 }
463             }
464         }
465         return 0;
466     } //-- long getLongValue( String, String, XmlPullParser, boolean )
467 
468     /**
469      * Method getRequiredAttributeValue.
470      * 
471      * @param s a s object.
472      * @param strict a strict object.
473      * @param parser a parser object.
474      * @param attribute a attribute object.
475      * @throws XmlPullParserException XmlPullParserException if
476      * any.
477      * @return String
478      */
479     private String getRequiredAttributeValue( String s, String attribute, XmlPullParser parser, boolean strict )
480         throws XmlPullParserException
481     {
482         if ( s == null )
483         {
484             if ( strict )
485             {
486                 throw new XmlPullParserException( "Missing required value for attribute '" + attribute + "'", parser, null );
487             }
488         }
489         return s;
490     } //-- String getRequiredAttributeValue( String, String, XmlPullParser, boolean )
491 
492     /**
493      * Method getShortValue.
494      * 
495      * @param s a s object.
496      * @param strict a strict object.
497      * @param parser a parser object.
498      * @param attribute a attribute object.
499      * @throws XmlPullParserException XmlPullParserException if
500      * any.
501      * @return short
502      */
503     private short getShortValue( String s, String attribute, XmlPullParser parser, boolean strict )
504         throws XmlPullParserException
505     {
506         if ( s != null )
507         {
508             try
509             {
510                 return Short.valueOf( s ).shortValue();
511             }
512             catch ( NumberFormatException nfe )
513             {
514                 if ( strict )
515                 {
516                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a short integer", parser, nfe );
517                 }
518             }
519         }
520         return 0;
521     } //-- short getShortValue( String, String, XmlPullParser, boolean )
522 
523     /**
524      * Method getTrimmedValue.
525      * 
526      * @param s a s object.
527      * @return String
528      */
529     private String getTrimmedValue( String s )
530     {
531         if ( s != null )
532         {
533             s = s.trim();
534         }
535         return s;
536     } //-- String getTrimmedValue( String )
537 
538     /**
539      * Method interpolatedTrimmed.
540      * 
541      * @param value a value object.
542      * @param context a context object.
543      * @return String
544      */
545     private String interpolatedTrimmed( String value, String context )
546     {
547         return getTrimmedValue( contentTransformer.transform( value, context ) );
548     } //-- String interpolatedTrimmed( String, String )
549 
550     /**
551      * Method nextTag.
552      * 
553      * @param parser a parser object.
554      * @throws IOException IOException if any.
555      * @throws XmlPullParserException XmlPullParserException if
556      * any.
557      * @return int
558      */
559     private int nextTag( XmlPullParser parser )
560         throws IOException, XmlPullParserException
561     {
562         int eventType = parser.next();
563         if ( eventType == XmlPullParser.TEXT )
564         {
565             eventType = parser.next();
566         }
567         if ( eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_TAG )
568         {
569             throw new XmlPullParserException( "expected START_TAG or END_TAG not " + XmlPullParser.TYPES[eventType], parser, null );
570         }
571         return eventType;
572     } //-- int nextTag( XmlPullParser )
573 
574     /**
575      * Method read.
576      * 
577      * @param parser a parser object.
578      * @param strict a strict object.
579      * @throws IOException IOException if any.
580      * @throws XmlPullParserException XmlPullParserException if
581      * any.
582      * @return Metadata
583      */
584     public Metadata read( XmlPullParser parser, boolean strict )
585         throws IOException, XmlPullParserException
586     {
587         Metadata metadata = null;
588         int eventType = parser.getEventType();
589         boolean parsed = false;
590         while ( eventType != XmlPullParser.END_DOCUMENT )
591         {
592             if ( eventType == XmlPullParser.START_TAG )
593             {
594                 if ( strict && ! "metadata".equals( parser.getName() ) )
595                 {
596                     throw new XmlPullParserException( "Expected root element 'metadata' but found '" + parser.getName() + "'", parser, null );
597                 }
598                 else if ( parsed )
599                 {
600                     // fallback, already expected a XmlPullParserException due to invalid XML
601                     throw new XmlPullParserException( "Duplicated tag: 'metadata'", parser, null );
602                 }
603                 metadata = parseMetadata( parser, strict );
604                 metadata.setModelEncoding( parser.getInputEncoding() );
605                 parsed = true;
606             }
607             eventType = parser.next();
608         }
609         if ( parsed )
610         {
611             return metadata;
612         }
613         throw new XmlPullParserException( "Expected root element 'metadata' but found no element at all: invalid XML document", parser, null );
614     } //-- Metadata read( XmlPullParser, boolean )
615 
616     /**
617      * @see XmlStreamReader
618      * 
619      * @param reader a reader object.
620      * @param strict a strict object.
621      * @throws IOException IOException if any.
622      * @throws XmlPullParserException XmlPullParserException if
623      * any.
624      * @return Metadata
625      */
626     public Metadata read( Reader reader, boolean strict )
627         throws IOException, XmlPullParserException
628     {
629         XmlPullParser parser = addDefaultEntities ? new MXParser(EntityReplacementMap.defaultEntityReplacementMap) : new MXParser( );
630 
631         parser.setInput( reader );
632 
633 
634         return read( parser, strict );
635     } //-- Metadata read( Reader, boolean )
636 
637     /**
638      * @see XmlStreamReader
639      * 
640      * @param reader a reader object.
641      * @throws IOException IOException if any.
642      * @throws XmlPullParserException XmlPullParserException if
643      * any.
644      * @return Metadata
645      */
646     public Metadata read( Reader reader )
647         throws IOException, XmlPullParserException
648     {
649         return read( reader, true );
650     } //-- Metadata read( Reader )
651 
652     /**
653      * Method read.
654      * 
655      * @param in a in object.
656      * @param strict a strict object.
657      * @throws IOException IOException if any.
658      * @throws XmlPullParserException XmlPullParserException if
659      * any.
660      * @return Metadata
661      */
662     public Metadata read( InputStream in, boolean strict )
663         throws IOException, XmlPullParserException
664     {
665         return read( new XmlStreamReader( in ), strict );
666     } //-- Metadata read( InputStream, boolean )
667 
668     /**
669      * Method read.
670      * 
671      * @param in a in object.
672      * @throws IOException IOException if any.
673      * @throws XmlPullParserException XmlPullParserException if
674      * any.
675      * @return Metadata
676      */
677     public Metadata read( InputStream in )
678         throws IOException, XmlPullParserException
679     {
680         return read( new XmlStreamReader( in ) );
681     } //-- Metadata read( InputStream )
682 
683     /**
684      * Method parseMetadata.
685      * 
686      * @param parser a parser object.
687      * @param strict a strict object.
688      * @throws IOException IOException if any.
689      * @throws XmlPullParserException XmlPullParserException if
690      * any.
691      * @return Metadata
692      */
693     private Metadata parseMetadata( XmlPullParser parser, boolean strict )
694         throws IOException, XmlPullParserException
695     {
696         String tagName = parser.getName();
697         Metadata metadata = new Metadata();
698         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
699         {
700             String name = parser.getAttributeName( i );
701             String value = parser.getAttributeValue( i );
702 
703             if ( name.indexOf( ':' ) >= 0 )
704             {
705                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
706             }
707             else if ( "xmlns".equals( name ) )
708             {
709                 // ignore xmlns attribute in root class, which is a reserved attribute name
710             }
711             else if ( "modelVersion".equals( name ) )
712             {
713                 metadata.setModelVersion( interpolatedTrimmed( value, "modelVersion" ) );
714             }
715             else
716             {
717                 checkUnknownAttribute( parser, name, tagName, strict );
718             }
719         }
720         java.util.Set<String> parsed = new java.util.HashSet<String>();
721         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
722         {
723             if ( checkFieldWithDuplicate( parser, "groupId", null, parsed ) )
724             {
725                 metadata.setGroupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
726             }
727             else if ( checkFieldWithDuplicate( parser, "artifactId", null, parsed ) )
728             {
729                 metadata.setArtifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
730             }
731             else if ( checkFieldWithDuplicate( parser, "versioning", null, parsed ) )
732             {
733                 metadata.setVersioning( parseVersioning( parser, strict ) );
734             }
735             else if ( checkFieldWithDuplicate( parser, "version", null, parsed ) )
736             {
737                 metadata.setVersion( interpolatedTrimmed( parser.nextText(), "version" ) );
738             }
739             else if ( checkFieldWithDuplicate( parser, "plugins", null, parsed ) )
740             {
741                 java.util.List<Plugin> plugins = new java.util.ArrayList<Plugin>();
742                 while ( parser.nextTag() == XmlPullParser.START_TAG )
743                 {
744                     if ( "plugin".equals( parser.getName() ) )
745                     {
746                         plugins.add( parsePlugin( parser, strict ) );
747                     }
748                     else
749                     {
750                         checkUnknownElement( parser, strict );
751                     }
752                 }
753                 metadata.setPlugins( plugins );
754             }
755             else
756             {
757                 checkUnknownElement( parser, strict );
758             }
759         }
760         return metadata;
761     } //-- Metadata parseMetadata( XmlPullParser, boolean )
762 
763     /**
764      * Method parsePlugin.
765      * 
766      * @param parser a parser object.
767      * @param strict a strict object.
768      * @throws IOException IOException if any.
769      * @throws XmlPullParserException XmlPullParserException if
770      * any.
771      * @return Plugin
772      */
773     private Plugin parsePlugin( XmlPullParser parser, boolean strict )
774         throws IOException, XmlPullParserException
775     {
776         String tagName = parser.getName();
777         Plugin plugin = new Plugin();
778         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
779         {
780             String name = parser.getAttributeName( i );
781             String value = parser.getAttributeValue( i );
782 
783             if ( name.indexOf( ':' ) >= 0 )
784             {
785                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
786             }
787             else
788             {
789                 checkUnknownAttribute( parser, name, tagName, strict );
790             }
791         }
792         java.util.Set<String> parsed = new java.util.HashSet<String>();
793         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
794         {
795             if ( checkFieldWithDuplicate( parser, "name", null, parsed ) )
796             {
797                 plugin.setName( interpolatedTrimmed( parser.nextText(), "name" ) );
798             }
799             else if ( checkFieldWithDuplicate( parser, "prefix", null, parsed ) )
800             {
801                 plugin.setPrefix( interpolatedTrimmed( parser.nextText(), "prefix" ) );
802             }
803             else if ( checkFieldWithDuplicate( parser, "artifactId", null, parsed ) )
804             {
805                 plugin.setArtifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
806             }
807             else
808             {
809                 checkUnknownElement( parser, strict );
810             }
811         }
812         return plugin;
813     } //-- Plugin parsePlugin( XmlPullParser, boolean )
814 
815     /**
816      * Method parseSnapshot.
817      * 
818      * @param parser a parser object.
819      * @param strict a strict object.
820      * @throws IOException IOException if any.
821      * @throws XmlPullParserException XmlPullParserException if
822      * any.
823      * @return Snapshot
824      */
825     private Snapshot parseSnapshot( XmlPullParser parser, boolean strict )
826         throws IOException, XmlPullParserException
827     {
828         String tagName = parser.getName();
829         Snapshot snapshot = new Snapshot();
830         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
831         {
832             String name = parser.getAttributeName( i );
833             String value = parser.getAttributeValue( i );
834 
835             if ( name.indexOf( ':' ) >= 0 )
836             {
837                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
838             }
839             else
840             {
841                 checkUnknownAttribute( parser, name, tagName, strict );
842             }
843         }
844         java.util.Set<String> parsed = new java.util.HashSet<String>();
845         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
846         {
847             if ( checkFieldWithDuplicate( parser, "timestamp", null, parsed ) )
848             {
849                 snapshot.setTimestamp( interpolatedTrimmed( parser.nextText(), "timestamp" ) );
850             }
851             else if ( checkFieldWithDuplicate( parser, "buildNumber", null, parsed ) )
852             {
853                 snapshot.setBuildNumber( getIntegerValue( interpolatedTrimmed( parser.nextText(), "buildNumber" ), "buildNumber", parser, strict ) );
854             }
855             else if ( checkFieldWithDuplicate( parser, "localCopy", null, parsed ) )
856             {
857                 snapshot.setLocalCopy( getBooleanValue( interpolatedTrimmed( parser.nextText(), "localCopy" ), "localCopy", parser, "false" ) );
858             }
859             else
860             {
861                 checkUnknownElement( parser, strict );
862             }
863         }
864         return snapshot;
865     } //-- Snapshot parseSnapshot( XmlPullParser, boolean )
866 
867     /**
868      * Method parseSnapshotVersion.
869      * 
870      * @param parser a parser object.
871      * @param strict a strict object.
872      * @throws IOException IOException if any.
873      * @throws XmlPullParserException XmlPullParserException if
874      * any.
875      * @return SnapshotVersion
876      */
877     private SnapshotVersion parseSnapshotVersion( XmlPullParser parser, boolean strict )
878         throws IOException, XmlPullParserException
879     {
880         String tagName = parser.getName();
881         SnapshotVersion snapshotVersion = new SnapshotVersion();
882         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
883         {
884             String name = parser.getAttributeName( i );
885             String value = parser.getAttributeValue( i );
886 
887             if ( name.indexOf( ':' ) >= 0 )
888             {
889                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
890             }
891             else
892             {
893                 checkUnknownAttribute( parser, name, tagName, strict );
894             }
895         }
896         java.util.Set<String> parsed = new java.util.HashSet<String>();
897         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
898         {
899             if ( checkFieldWithDuplicate( parser, "classifier", null, parsed ) )
900             {
901                 snapshotVersion.setClassifier( interpolatedTrimmed( parser.nextText(), "classifier" ) );
902             }
903             else if ( checkFieldWithDuplicate( parser, "extension", null, parsed ) )
904             {
905                 snapshotVersion.setExtension( interpolatedTrimmed( parser.nextText(), "extension" ) );
906             }
907             else if ( checkFieldWithDuplicate( parser, "value", null, parsed ) )
908             {
909                 snapshotVersion.setVersion( interpolatedTrimmed( parser.nextText(), "value" ) );
910             }
911             else if ( checkFieldWithDuplicate( parser, "updated", null, parsed ) )
912             {
913                 snapshotVersion.setUpdated( interpolatedTrimmed( parser.nextText(), "updated" ) );
914             }
915             else
916             {
917                 checkUnknownElement( parser, strict );
918             }
919         }
920         return snapshotVersion;
921     } //-- SnapshotVersion parseSnapshotVersion( XmlPullParser, boolean )
922 
923     /**
924      * Method parseVersioning.
925      * 
926      * @param parser a parser object.
927      * @param strict a strict object.
928      * @throws IOException IOException if any.
929      * @throws XmlPullParserException XmlPullParserException if
930      * any.
931      * @return Versioning
932      */
933     private Versioning parseVersioning( XmlPullParser parser, boolean strict )
934         throws IOException, XmlPullParserException
935     {
936         String tagName = parser.getName();
937         Versioning versioning = new Versioning();
938         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
939         {
940             String name = parser.getAttributeName( i );
941             String value = parser.getAttributeValue( i );
942 
943             if ( name.indexOf( ':' ) >= 0 )
944             {
945                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
946             }
947             else
948             {
949                 checkUnknownAttribute( parser, name, tagName, strict );
950             }
951         }
952         java.util.Set<String> parsed = new java.util.HashSet<String>();
953         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
954         {
955             if ( checkFieldWithDuplicate( parser, "latest", null, parsed ) )
956             {
957                 versioning.setLatest( interpolatedTrimmed( parser.nextText(), "latest" ) );
958             }
959             else if ( checkFieldWithDuplicate( parser, "release", null, parsed ) )
960             {
961                 versioning.setRelease( interpolatedTrimmed( parser.nextText(), "release" ) );
962             }
963             else if ( checkFieldWithDuplicate( parser, "versions", null, parsed ) )
964             {
965                 java.util.List<String> versions = new java.util.ArrayList<String>();
966                 while ( parser.nextTag() == XmlPullParser.START_TAG )
967                 {
968                     if ( "version".equals( parser.getName() ) )
969                     {
970                         versions.add( interpolatedTrimmed( parser.nextText(), "versions" ) );
971                     }
972                     else
973                     {
974                         checkUnknownElement( parser, strict );
975                     }
976                 }
977                 versioning.setVersions( versions );
978             }
979             else if ( checkFieldWithDuplicate( parser, "lastUpdated", null, parsed ) )
980             {
981                 versioning.setLastUpdated( interpolatedTrimmed( parser.nextText(), "lastUpdated" ) );
982             }
983             else if ( checkFieldWithDuplicate( parser, "snapshot", null, parsed ) )
984             {
985                 versioning.setSnapshot( parseSnapshot( parser, strict ) );
986             }
987             else if ( checkFieldWithDuplicate( parser, "snapshotVersions", null, parsed ) )
988             {
989                 java.util.List<SnapshotVersion> snapshotVersions = new java.util.ArrayList<SnapshotVersion>();
990                 while ( parser.nextTag() == XmlPullParser.START_TAG )
991                 {
992                     if ( "snapshotVersion".equals( parser.getName() ) )
993                     {
994                         snapshotVersions.add( parseSnapshotVersion( parser, strict ) );
995                     }
996                     else
997                     {
998                         checkUnknownElement( parser, strict );
999                     }
1000                 }
1001                 versioning.setSnapshotVersions( snapshotVersions );
1002             }
1003             else
1004             {
1005                 checkUnknownElement( parser, strict );
1006             }
1007         }
1008         return versioning;
1009     } //-- Versioning parseVersioning( XmlPullParser, boolean )
1010 
1011     /**
1012      * Sets the state of the "add default entities" flag.
1013      * 
1014      * @param addDefaultEntities a addDefaultEntities object.
1015      */
1016     public void setAddDefaultEntities( boolean addDefaultEntities )
1017     {
1018         this.addDefaultEntities = addDefaultEntities;
1019     } //-- void setAddDefaultEntities( boolean )
1020 
1021     public static interface ContentTransformer
1022 {
1023     /**
1024      * Interpolate the value read from the xpp3 document
1025      * @param source The source value
1026      * @param fieldName A description of the field being interpolated. The implementation may use this to
1027      *                           log stuff.
1028      * @return The interpolated value.
1029      */
1030     String transform( String source, String fieldName );
1031 }
1032 
1033 }