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