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