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