001/*
002 Licensed to the Apache Software Foundation (ASF) under one
003 or more contributor license agreements.  See the NOTICE file
004 distributed with this work for additional information
005 regarding copyright ownership.  The ASF licenses this file
006 to you under the Apache License, Version 2.0 (the
007 "License"); you may not use this file except in compliance
008 with the License.  You may obtain a copy of the License at
009 
010     http://www.apache.org/licenses/LICENSE-2.0
011 
012 Unless required by applicable law or agreed to in writing,
013 software distributed under the License is distributed on an
014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 KIND, either express or implied.  See the License for the
016 specific language governing permissions and limitations
017 under the License.
018 =================== DO NOT EDIT THIS FILE ====================
019 Generated by Modello 2.5.1,
020 any modifications will be overwritten.
021 ==============================================================
022 */
023
024package org.apache.maven.tools.plugin.extractor.model.io.xpp3;
025
026  //---------------------------------/
027 //- Imported classes and packages -/
028//---------------------------------/
029
030import java.io.IOException;
031import java.io.InputStream;
032import java.io.Reader;
033import java.text.DateFormat;
034import org.apache.maven.tools.plugin.extractor.model.Component;
035import org.apache.maven.tools.plugin.extractor.model.LifecycleExecution;
036import org.apache.maven.tools.plugin.extractor.model.Mojo;
037import org.apache.maven.tools.plugin.extractor.model.Parameter;
038import org.apache.maven.tools.plugin.extractor.model.PluginMetadata;
039import org.codehaus.plexus.util.xml.XmlStreamReader;
040import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
041import org.codehaus.plexus.util.xml.pull.MXParser;
042import org.codehaus.plexus.util.xml.pull.XmlPullParser;
043import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
044
045/**
046 * Class PluginMetadataXpp3Reader.
047 * 
048 * @version $Revision$ $Date$
049 */
050@SuppressWarnings( "all" )
051public class PluginMetadataXpp3Reader
052{
053
054      //--------------------------/
055     //- Class/Member Variables -/
056    //--------------------------/
057
058    /**
059     * If set the parser will be loaded with all single characters
060     * from the XHTML specification.
061     * The entities used:
062     * <ul>
063     * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent</li>
064     * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent</li>
065     * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</li>
066     * </ul>
067     */
068    private boolean addDefaultEntities = true;
069
070    /**
071     * Field contentTransformer.
072     */
073    public final ContentTransformer contentTransformer;
074
075
076      //----------------/
077     //- Constructors -/
078    //----------------/
079
080    public PluginMetadataXpp3Reader()
081    {
082        this( new ContentTransformer()
083        {
084            public String transform( String source, String fieldName )
085            {
086                return source;
087            }
088        } );
089    } //-- org.apache.maven.tools.plugin.extractor.model.io.xpp3.PluginMetadataXpp3Reader()
090
091    public PluginMetadataXpp3Reader(ContentTransformer contentTransformer)
092    {
093        this.contentTransformer = contentTransformer;
094    } //-- org.apache.maven.tools.plugin.extractor.model.io.xpp3.PluginMetadataXpp3Reader(ContentTransformer)
095
096
097      //-----------/
098     //- Methods -/
099    //-----------/
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 PluginMetadata
583     */
584    public PluginMetadata read( XmlPullParser parser, boolean strict )
585        throws IOException, XmlPullParserException
586    {
587        PluginMetadata pluginMetadata = 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 && ! "pluginMetadata".equals( parser.getName() ) )
595                {
596                    throw new XmlPullParserException( "Expected root element 'pluginMetadata' 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: 'pluginMetadata'", parser, null );
602                }
603                pluginMetadata = parsePluginMetadata( parser, strict );
604                pluginMetadata.setModelEncoding( parser.getInputEncoding() );
605                parsed = true;
606            }
607            eventType = parser.next();
608        }
609        if ( parsed )
610        {
611            return pluginMetadata;
612        }
613        throw new XmlPullParserException( "Expected root element 'pluginMetadata' but found no element at all: invalid XML document", parser, null );
614    } //-- PluginMetadata 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 PluginMetadata
625     */
626    public PluginMetadata 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    } //-- PluginMetadata 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 PluginMetadata
645     */
646    public PluginMetadata read( Reader reader )
647        throws IOException, XmlPullParserException
648    {
649        return read( reader, true );
650    } //-- PluginMetadata 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 PluginMetadata
661     */
662    public PluginMetadata read( InputStream in, boolean strict )
663        throws IOException, XmlPullParserException
664    {
665        return read( new XmlStreamReader( in ), strict );
666    } //-- PluginMetadata 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 PluginMetadata
676     */
677    public PluginMetadata read( InputStream in )
678        throws IOException, XmlPullParserException
679    {
680        return read( new XmlStreamReader( in ) );
681    } //-- PluginMetadata read( InputStream )
682
683    /**
684     * Method parseComponent.
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 Component
692     */
693    private Component parseComponent( XmlPullParser parser, boolean strict )
694        throws IOException, XmlPullParserException
695    {
696        String tagName = parser.getName();
697        Component component = new Component();
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
708            {
709                checkUnknownAttribute( parser, name, tagName, strict );
710            }
711        }
712        java.util.Set<String> parsed = new java.util.HashSet<String>();
713        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
714        {
715            if ( checkFieldWithDuplicate( parser, "role", null, parsed ) )
716            {
717                component.setRole( interpolatedTrimmed( parser.nextText(), "role" ) );
718            }
719            else if ( checkFieldWithDuplicate( parser, "hint", null, parsed ) )
720            {
721                component.setHint( interpolatedTrimmed( parser.nextText(), "hint" ) );
722            }
723            else
724            {
725                checkUnknownElement( parser, strict );
726            }
727        }
728        return component;
729    } //-- Component parseComponent( XmlPullParser, boolean )
730
731    /**
732     * Method parseLifecycleExecution.
733     * 
734     * @param parser a parser object.
735     * @param strict a strict object.
736     * @throws IOException IOException if any.
737     * @throws XmlPullParserException XmlPullParserException if
738     * any.
739     * @return LifecycleExecution
740     */
741    private LifecycleExecution parseLifecycleExecution( XmlPullParser parser, boolean strict )
742        throws IOException, XmlPullParserException
743    {
744        String tagName = parser.getName();
745        LifecycleExecution lifecycleExecution = new LifecycleExecution();
746        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
747        {
748            String name = parser.getAttributeName( i );
749            String value = parser.getAttributeValue( i );
750
751            if ( name.indexOf( ':' ) >= 0 )
752            {
753                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
754            }
755            else
756            {
757                checkUnknownAttribute( parser, name, tagName, strict );
758            }
759        }
760        java.util.Set<String> parsed = new java.util.HashSet<String>();
761        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
762        {
763            if ( checkFieldWithDuplicate( parser, "lifecycle", null, parsed ) )
764            {
765                lifecycleExecution.setLifecycle( interpolatedTrimmed( parser.nextText(), "lifecycle" ) );
766            }
767            else if ( checkFieldWithDuplicate( parser, "phase", null, parsed ) )
768            {
769                lifecycleExecution.setPhase( interpolatedTrimmed( parser.nextText(), "phase" ) );
770            }
771            else if ( checkFieldWithDuplicate( parser, "goal", null, parsed ) )
772            {
773                lifecycleExecution.setGoal( interpolatedTrimmed( parser.nextText(), "goal" ) );
774            }
775            else
776            {
777                checkUnknownElement( parser, strict );
778            }
779        }
780        return lifecycleExecution;
781    } //-- LifecycleExecution parseLifecycleExecution( XmlPullParser, boolean )
782
783    /**
784     * Method parseMojo.
785     * 
786     * @param parser a parser object.
787     * @param strict a strict object.
788     * @throws IOException IOException if any.
789     * @throws XmlPullParserException XmlPullParserException if
790     * any.
791     * @return Mojo
792     */
793    private Mojo parseMojo( XmlPullParser parser, boolean strict )
794        throws IOException, XmlPullParserException
795    {
796        String tagName = parser.getName();
797        Mojo mojo = new Mojo();
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<String> parsed = new java.util.HashSet<String>();
813        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
814        {
815            if ( checkFieldWithDuplicate( parser, "goal", null, parsed ) )
816            {
817                mojo.setGoal( interpolatedTrimmed( parser.nextText(), "goal" ) );
818            }
819            else if ( checkFieldWithDuplicate( parser, "phase", null, parsed ) )
820            {
821                mojo.setPhase( interpolatedTrimmed( parser.nextText(), "phase" ) );
822            }
823            else if ( checkFieldWithDuplicate( parser, "aggregator", null, parsed ) )
824            {
825                mojo.setAggregator( getBooleanValue( interpolatedTrimmed( parser.nextText(), "aggregator" ), "aggregator", parser, "false" ) );
826            }
827            else if ( checkFieldWithDuplicate( parser, "requiresDependencyResolution", null, parsed ) )
828            {
829                mojo.setRequiresDependencyResolution( interpolatedTrimmed( parser.nextText(), "requiresDependencyResolution" ) );
830            }
831            else if ( checkFieldWithDuplicate( parser, "requiresProject", null, parsed ) )
832            {
833                mojo.setRequiresProject( getBooleanValue( interpolatedTrimmed( parser.nextText(), "requiresProject" ), "requiresProject", parser, "false" ) );
834            }
835            else if ( checkFieldWithDuplicate( parser, "requiresReports", null, parsed ) )
836            {
837                mojo.setRequiresReports( getBooleanValue( interpolatedTrimmed( parser.nextText(), "requiresReports" ), "requiresReports", parser, "false" ) );
838            }
839            else if ( checkFieldWithDuplicate( parser, "requiresOnline", null, parsed ) )
840            {
841                mojo.setRequiresOnline( getBooleanValue( interpolatedTrimmed( parser.nextText(), "requiresOnline" ), "requiresOnline", parser, "false" ) );
842            }
843            else if ( checkFieldWithDuplicate( parser, "inheritByDefault", null, parsed ) )
844            {
845                mojo.setInheritByDefault( getBooleanValue( interpolatedTrimmed( parser.nextText(), "inheritByDefault" ), "inheritByDefault", parser, "false" ) );
846            }
847            else if ( checkFieldWithDuplicate( parser, "requiresDirectInvocation", null, parsed ) )
848            {
849                mojo.setRequiresDirectInvocation( getBooleanValue( interpolatedTrimmed( parser.nextText(), "requiresDirectInvocation" ), "requiresDirectInvocation", parser, "false" ) );
850            }
851            else if ( checkFieldWithDuplicate( parser, "execution", null, parsed ) )
852            {
853                mojo.setExecution( parseLifecycleExecution( parser, strict ) );
854            }
855            else if ( checkFieldWithDuplicate( parser, "components", null, parsed ) )
856            {
857                java.util.List<Component> components = new java.util.ArrayList<Component>();
858                while ( parser.nextTag() == XmlPullParser.START_TAG )
859                {
860                    if ( "component".equals( parser.getName() ) )
861                    {
862                        components.add( parseComponent( parser, strict ) );
863                    }
864                    else
865                    {
866                        checkUnknownElement( parser, strict );
867                    }
868                }
869                mojo.setComponents( components );
870            }
871            else if ( checkFieldWithDuplicate( parser, "parameters", null, parsed ) )
872            {
873                java.util.List<Parameter> parameters = new java.util.ArrayList<Parameter>();
874                while ( parser.nextTag() == XmlPullParser.START_TAG )
875                {
876                    if ( "parameter".equals( parser.getName() ) )
877                    {
878                        parameters.add( parseParameter( parser, strict ) );
879                    }
880                    else
881                    {
882                        checkUnknownElement( parser, strict );
883                    }
884                }
885                mojo.setParameters( parameters );
886            }
887            else if ( checkFieldWithDuplicate( parser, "description", null, parsed ) )
888            {
889                mojo.setDescription( interpolatedTrimmed( parser.nextText(), "description" ) );
890            }
891            else if ( checkFieldWithDuplicate( parser, "deprecated", null, parsed ) )
892            {
893                mojo.setDeprecation( interpolatedTrimmed( parser.nextText(), "deprecated" ) );
894            }
895            else if ( checkFieldWithDuplicate( parser, "since", null, parsed ) )
896            {
897                mojo.setSince( interpolatedTrimmed( parser.nextText(), "since" ) );
898            }
899            else if ( checkFieldWithDuplicate( parser, "call", null, parsed ) )
900            {
901                mojo.setCall( interpolatedTrimmed( parser.nextText(), "call" ) );
902            }
903            else
904            {
905                checkUnknownElement( parser, strict );
906            }
907        }
908        return mojo;
909    } //-- Mojo parseMojo( XmlPullParser, boolean )
910
911    /**
912     * Method parseParameter.
913     * 
914     * @param parser a parser object.
915     * @param strict a strict object.
916     * @throws IOException IOException if any.
917     * @throws XmlPullParserException XmlPullParserException if
918     * any.
919     * @return Parameter
920     */
921    private Parameter parseParameter( XmlPullParser parser, boolean strict )
922        throws IOException, XmlPullParserException
923    {
924        String tagName = parser.getName();
925        Parameter parameter = new Parameter();
926        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
927        {
928            String name = parser.getAttributeName( i );
929            String value = parser.getAttributeValue( i );
930
931            if ( name.indexOf( ':' ) >= 0 )
932            {
933                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
934            }
935            else
936            {
937                checkUnknownAttribute( parser, name, tagName, strict );
938            }
939        }
940        java.util.Set<String> parsed = new java.util.HashSet<String>();
941        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
942        {
943            if ( checkFieldWithDuplicate( parser, "name", null, parsed ) )
944            {
945                parameter.setName( interpolatedTrimmed( parser.nextText(), "name" ) );
946            }
947            else if ( checkFieldWithDuplicate( parser, "alias", null, parsed ) )
948            {
949                parameter.setAlias( interpolatedTrimmed( parser.nextText(), "alias" ) );
950            }
951            else if ( checkFieldWithDuplicate( parser, "property", null, parsed ) )
952            {
953                parameter.setProperty( interpolatedTrimmed( parser.nextText(), "property" ) );
954            }
955            else if ( checkFieldWithDuplicate( parser, "required", null, parsed ) )
956            {
957                parameter.setRequired( getBooleanValue( interpolatedTrimmed( parser.nextText(), "required" ), "required", parser, "false" ) );
958            }
959            else if ( checkFieldWithDuplicate( parser, "readonly", null, parsed ) )
960            {
961                parameter.setReadonly( getBooleanValue( interpolatedTrimmed( parser.nextText(), "readonly" ), "readonly", parser, "false" ) );
962            }
963            else if ( checkFieldWithDuplicate( parser, "expression", null, parsed ) )
964            {
965                parameter.setExpression( interpolatedTrimmed( parser.nextText(), "expression" ) );
966            }
967            else if ( checkFieldWithDuplicate( parser, "defaultValue", null, parsed ) )
968            {
969                parameter.setDefaultValue( interpolatedTrimmed( parser.nextText(), "defaultValue" ) );
970            }
971            else if ( checkFieldWithDuplicate( parser, "type", null, parsed ) )
972            {
973                parameter.setType( interpolatedTrimmed( parser.nextText(), "type" ) );
974            }
975            else if ( checkFieldWithDuplicate( parser, "description", null, parsed ) )
976            {
977                parameter.setDescription( interpolatedTrimmed( parser.nextText(), "description" ) );
978            }
979            else if ( checkFieldWithDuplicate( parser, "deprecated", null, parsed ) )
980            {
981                parameter.setDeprecation( interpolatedTrimmed( parser.nextText(), "deprecated" ) );
982            }
983            else if ( checkFieldWithDuplicate( parser, "since", null, parsed ) )
984            {
985                parameter.setSince( interpolatedTrimmed( parser.nextText(), "since" ) );
986            }
987            else
988            {
989                checkUnknownElement( parser, strict );
990            }
991        }
992        return parameter;
993    } //-- Parameter parseParameter( XmlPullParser, boolean )
994
995    /**
996     * Method parsePluginMetadata.
997     * 
998     * @param parser a parser object.
999     * @param strict a strict object.
1000     * @throws IOException IOException if any.
1001     * @throws XmlPullParserException XmlPullParserException if
1002     * any.
1003     * @return PluginMetadata
1004     */
1005    private PluginMetadata parsePluginMetadata( XmlPullParser parser, boolean strict )
1006        throws IOException, XmlPullParserException
1007    {
1008        String tagName = parser.getName();
1009        PluginMetadata pluginMetadata = new PluginMetadata();
1010        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1011        {
1012            String name = parser.getAttributeName( i );
1013            String value = parser.getAttributeValue( i );
1014
1015            if ( name.indexOf( ':' ) >= 0 )
1016            {
1017                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1018            }
1019            else if ( "xmlns".equals( name ) )
1020            {
1021                // ignore xmlns attribute in root class, which is a reserved attribute name
1022            }
1023            else
1024            {
1025                checkUnknownAttribute( parser, name, tagName, strict );
1026            }
1027        }
1028        java.util.Set<String> parsed = new java.util.HashSet<String>();
1029        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1030        {
1031            if ( checkFieldWithDuplicate( parser, "mojos", null, parsed ) )
1032            {
1033                java.util.List<Mojo> mojos = new java.util.ArrayList<Mojo>();
1034                while ( parser.nextTag() == XmlPullParser.START_TAG )
1035                {
1036                    if ( "mojo".equals( parser.getName() ) )
1037                    {
1038                        mojos.add( parseMojo( parser, strict ) );
1039                    }
1040                    else
1041                    {
1042                        checkUnknownElement( parser, strict );
1043                    }
1044                }
1045                pluginMetadata.setMojos( mojos );
1046            }
1047            else
1048            {
1049                checkUnknownElement( parser, strict );
1050            }
1051        }
1052        return pluginMetadata;
1053    } //-- PluginMetadata parsePluginMetadata( XmlPullParser, boolean )
1054
1055    /**
1056     * Sets the state of the "add default entities" flag.
1057     * 
1058     * @param addDefaultEntities a addDefaultEntities object.
1059     */
1060    public void setAddDefaultEntities( boolean addDefaultEntities )
1061    {
1062        this.addDefaultEntities = addDefaultEntities;
1063    } //-- void setAddDefaultEntities( boolean )
1064
1065    public static interface ContentTransformer
1066{
1067    /**
1068     * Interpolate the value read from the xpp3 document
1069     * @param source The source value
1070     * @param fieldName A description of the field being interpolated. The implementation may use this to
1071     *                           log stuff.
1072     * @return The interpolated value.
1073     */
1074    String transform( String source, String fieldName );
1075}
1076
1077}