View Javadoc
1   // =================== DO NOT EDIT THIS FILE ====================
2   //  Generated by Modello Velocity from reader-ex.vm
3   //  template, any modifications will be overwritten.
4   // ==============================================================
5   package org.apache.maven.model.v4;
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.Set;
19  import org.apache.maven.api.annotations.Generated;
20  import org.apache.maven.internal.xml.XmlNodeBuilder;
21  import org.apache.maven.api.model.InputSource;
22  import org.apache.maven.api.model.InputLocation;
23  import org.apache.maven.api.model.Model;
24  import org.apache.maven.api.model.ModelBase;
25  import org.apache.maven.api.model.PluginContainer;
26  import org.apache.maven.api.model.PluginConfiguration;
27  import org.apache.maven.api.model.BuildBase;
28  import org.apache.maven.api.model.Build;
29  import org.apache.maven.api.model.CiManagement;
30  import org.apache.maven.api.model.Notifier;
31  import org.apache.maven.api.model.Contributor;
32  import org.apache.maven.api.model.Dependency;
33  import org.apache.maven.api.model.Developer;
34  import org.apache.maven.api.model.Exclusion;
35  import org.apache.maven.api.model.IssueManagement;
36  import org.apache.maven.api.model.DistributionManagement;
37  import org.apache.maven.api.model.License;
38  import org.apache.maven.api.model.MailingList;
39  import org.apache.maven.api.model.Organization;
40  import org.apache.maven.api.model.PatternSet;
41  import org.apache.maven.api.model.Parent;
42  import org.apache.maven.api.model.Scm;
43  import org.apache.maven.api.model.FileSet;
44  import org.apache.maven.api.model.Resource;
45  import org.apache.maven.api.model.RepositoryBase;
46  import org.apache.maven.api.model.Repository;
47  import org.apache.maven.api.model.DeploymentRepository;
48  import org.apache.maven.api.model.RepositoryPolicy;
49  import org.apache.maven.api.model.Site;
50  import org.apache.maven.api.model.ConfigurationContainer;
51  import org.apache.maven.api.model.Plugin;
52  import org.apache.maven.api.model.PluginExecution;
53  import org.apache.maven.api.model.DependencyManagement;
54  import org.apache.maven.api.model.PluginManagement;
55  import org.apache.maven.api.model.Reporting;
56  import org.apache.maven.api.model.Profile;
57  import org.apache.maven.api.model.Activation;
58  import org.apache.maven.api.model.ActivationProperty;
59  import org.apache.maven.api.model.ActivationOS;
60  import org.apache.maven.api.model.ActivationFile;
61  import org.apache.maven.api.model.ReportPlugin;
62  import org.apache.maven.api.model.ReportSet;
63  import org.apache.maven.api.model.Prerequisites;
64  import org.apache.maven.api.model.Relocation;
65  import org.apache.maven.api.model.Extension;
66  import org.apache.maven.api.model.InputLocation;
67  import org.apache.maven.api.model.InputSource;
68  import org.codehaus.plexus.util.ReaderFactory;
69  import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
70  import org.codehaus.plexus.util.xml.pull.MXParser;
71  import org.codehaus.plexus.util.xml.pull.XmlPullParser;
72  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
73  
74  @Generated
75  public class MavenXpp3ReaderEx
76  {
77      private boolean addDefaultEntities = true;
78  
79      private final ContentTransformer contentTransformer;
80  
81      public MavenXpp3ReaderEx()
82      {
83          this( ( s, f ) -> s );
84      }
85  
86      public MavenXpp3ReaderEx( ContentTransformer contentTransformer )
87      {
88          this.contentTransformer = contentTransformer;
89      }
90  
91      /**
92       * Returns the state of the "add default entities" flag.
93       *
94       * @return boolean
95       */
96      public boolean getAddDefaultEntities()
97      {
98          return addDefaultEntities;
99      } //-- boolean getAddDefaultEntities()
100 
101     /**
102      * Sets the state of the "add default entities" flag.
103      *
104      * @param addDefaultEntities a addDefaultEntities object.
105      */
106     public void setAddDefaultEntities( boolean addDefaultEntities )
107     {
108         this.addDefaultEntities = addDefaultEntities;
109     } //-- void setAddDefaultEntities( boolean )
110 
111     /**
112      * @see ReaderFactory#newXmlReader
113      *
114      * @param reader a reader object.
115      * @param strict a strict object.
116      * @throws IOException IOException if any.
117      * @throws XmlPullParserException XmlPullParserException if
118      * any.
119      * @return Model
120      */
121     public Model read( Reader reader, boolean strict, InputSource source )
122         throws IOException, XmlPullParserException
123     {
124         XmlPullParser parser = addDefaultEntities ? new MXParser(EntityReplacementMap.defaultEntityReplacementMap) : new MXParser( );
125         parser.setInput( reader );
126         return read( parser, strict, source );
127     } //-- Model read( Reader, boolean )
128 
129     /**
130      * Method read.
131      *
132      * @param in a in object.
133      * @param strict a strict object.
134      * @throws IOException IOException if any.
135      * @throws XmlPullParserException XmlPullParserException if
136      * any.
137      * @return Model
138      */
139     public Model read( InputStream in, boolean strict, InputSource source )
140         throws IOException, XmlPullParserException
141     {
142         return read( ReaderFactory.newXmlReader( in ), strict, source );
143     } //-- Model read( InputStream, boolean )
144 
145     /**
146      * Method read.
147      *
148      * @param parser a parser object.
149      * @param strict a strict object.
150      * @throws IOException IOException if any.
151      * @throws XmlPullParserException XmlPullParserException if
152      * any.
153      * @return Model
154      */
155     public Model read( XmlPullParser parser, boolean strict, InputSource source )
156         throws IOException, XmlPullParserException
157     {
158         Model model = null;
159         int eventType = parser.getEventType();
160         boolean parsed = false;
161         while ( eventType != XmlPullParser.END_DOCUMENT )
162         {
163             if ( eventType == XmlPullParser.START_TAG )
164             {
165                 if ( strict && ! "project".equals( parser.getName() ) )
166                 {
167                     throw new XmlPullParserException( "Expected root element 'project' but found '" + parser.getName() + "'", parser, null );
168                 }
169                 else if ( parsed )
170                 {
171                     // fallback, already expected a XmlPullParserException due to invalid XML
172                     throw new XmlPullParserException( "Duplicated tag: 'project'", parser, null );
173                 }
174                 model = parseModel( parser, strict, source );
175                 parsed = true;
176             }
177             eventType = parser.next();
178         }
179         if ( parsed )
180         {
181             return model;
182         }
183         throw new XmlPullParserException( "Expected root element 'project' but found no element at all: invalid XML document", parser, null );
184     } //-- Model read( XmlPullParser, boolean )
185 
186     private Model parseModel( XmlPullParser parser, boolean strict, InputSource source )
187         throws IOException, XmlPullParserException
188     {
189         String tagName = parser.getName();
190         Model.Builder model = Model.newBuilder( true );
191         model.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
192         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
193         {
194             String name = parser.getAttributeName( i );
195             String value = parser.getAttributeValue( i );
196             if ( name.indexOf( ':' ) >= 0 )
197             {
198                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
199             }
200             else if ( "xmlns".equals( name ) )
201             {
202                 // ignore xmlns attribute in root class, which is a reserved attribute name
203             }
204             else if ( "child.project.url.inherit.append.path".equals( name ) )
205             {
206                 model.location( name, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
207                 model.childProjectUrlInheritAppendPath( interpolatedTrimmed( value, "child.project.url.inherit.append.path" ) );
208             }
209             else
210             {
211                 checkUnknownAttribute( parser, name, tagName, strict );
212             }
213         }
214         Set<String> parsed = new HashSet<>();
215         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
216         {
217             String childName = unalias( parser.getName() );
218             if ( !parsed.add( childName ) )
219             {
220                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
221             }
222             int line = parser.getLineNumber();
223             int column = parser.getColumnNumber();
224             Map<Object, InputLocation> locations = null;
225             switch ( childName )
226             {
227                 case "modelVersion":
228                 {
229                     model.modelVersion( interpolatedTrimmed( parser.nextText(), "modelVersion" ) );
230                     break;
231                 }
232                 case "parent":
233                 {
234                     model.parent( parseParent( parser, strict, source ) );
235                     break;
236                 }
237                 case "groupId":
238                 {
239                     model.groupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
240                     break;
241                 }
242                 case "artifactId":
243                 {
244                     model.artifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
245                     break;
246                 }
247                 case "version":
248                 {
249                     model.version( interpolatedTrimmed( parser.nextText(), "version" ) );
250                     break;
251                 }
252                 case "packaging":
253                 {
254                     model.packaging( interpolatedTrimmed( parser.nextText(), "packaging" ) );
255                     break;
256                 }
257                 case "name":
258                 {
259                     model.name( interpolatedTrimmed( parser.nextText(), "name" ) );
260                     break;
261                 }
262                 case "description":
263                 {
264                     model.description( interpolatedTrimmed( parser.nextText(), "description" ) );
265                     break;
266                 }
267                 case "url":
268                 {
269                     model.url( interpolatedTrimmed( parser.nextText(), "url" ) );
270                     break;
271                 }
272                 case "inceptionYear":
273                 {
274                     model.inceptionYear( interpolatedTrimmed( parser.nextText(), "inceptionYear" ) );
275                     break;
276                 }
277                 case "organization":
278                 {
279                     model.organization( parseOrganization( parser, strict, source ) );
280                     break;
281                 }
282                 case "licenses":
283                 {
284                     List<License> licenses = new ArrayList<>();
285                     while ( parser.nextTag() == XmlPullParser.START_TAG )
286                     {
287                         if ( "license".equals( parser.getName() ) )
288                         {
289                             licenses.add( parseLicense( parser, strict, source ) );
290                         }
291                         else
292                         {
293                             checkUnknownElement( parser, strict );
294                         }
295                     }
296                     model.licenses( licenses );
297                     break;
298                 }
299                 case "developers":
300                 {
301                     List<Developer> developers = new ArrayList<>();
302                     while ( parser.nextTag() == XmlPullParser.START_TAG )
303                     {
304                         if ( "developer".equals( parser.getName() ) )
305                         {
306                             developers.add( parseDeveloper( parser, strict, source ) );
307                         }
308                         else
309                         {
310                             checkUnknownElement( parser, strict );
311                         }
312                     }
313                     model.developers( developers );
314                     break;
315                 }
316                 case "contributors":
317                 {
318                     List<Contributor> contributors = new ArrayList<>();
319                     while ( parser.nextTag() == XmlPullParser.START_TAG )
320                     {
321                         if ( "contributor".equals( parser.getName() ) )
322                         {
323                             contributors.add( parseContributor( parser, strict, source ) );
324                         }
325                         else
326                         {
327                             checkUnknownElement( parser, strict );
328                         }
329                     }
330                     model.contributors( contributors );
331                     break;
332                 }
333                 case "mailingLists":
334                 {
335                     List<MailingList> mailingLists = new ArrayList<>();
336                     while ( parser.nextTag() == XmlPullParser.START_TAG )
337                     {
338                         if ( "mailingList".equals( parser.getName() ) )
339                         {
340                             mailingLists.add( parseMailingList( parser, strict, source ) );
341                         }
342                         else
343                         {
344                             checkUnknownElement( parser, strict );
345                         }
346                     }
347                     model.mailingLists( mailingLists );
348                     break;
349                 }
350                 case "prerequisites":
351                 {
352                     model.prerequisites( parsePrerequisites( parser, strict, source ) );
353                     break;
354                 }
355                 case "modules":
356                 {
357                     List<String> modules = new ArrayList<>();
358                     locations = new HashMap<>();
359                     while ( parser.nextTag() == XmlPullParser.START_TAG )
360                     {
361                         if ( "module".equals( parser.getName() ) )
362                         {
363                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
364                             modules.add( interpolatedTrimmed( parser.nextText(), "modules" ) );
365                         }
366                         else
367                         {
368                             checkUnknownElement( parser, strict );
369                         }
370                     }
371                     model.modules( modules );
372                     break;
373                 }
374                 case "scm":
375                 {
376                     model.scm( parseScm( parser, strict, source ) );
377                     break;
378                 }
379                 case "issueManagement":
380                 {
381                     model.issueManagement( parseIssueManagement( parser, strict, source ) );
382                     break;
383                 }
384                 case "ciManagement":
385                 {
386                     model.ciManagement( parseCiManagement( parser, strict, source ) );
387                     break;
388                 }
389                 case "distributionManagement":
390                 {
391                     model.distributionManagement( parseDistributionManagement( parser, strict, source ) );
392                     break;
393                 }
394                 case "properties":
395                 {
396                     Map<String, String> properties = new LinkedHashMap<>();
397                     locations = new HashMap<>();
398                     while ( parser.nextTag() == XmlPullParser.START_TAG )
399                     {
400                         String key = parser.getName();
401                         String value = parser.nextText().trim();
402                         locations.put( key, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
403                         properties.put( key, value );
404                     }
405                     model.properties( properties );
406                     break;
407                 }
408                 case "dependencyManagement":
409                 {
410                     model.dependencyManagement( parseDependencyManagement( parser, strict, source ) );
411                     break;
412                 }
413                 case "dependencies":
414                 {
415                     List<Dependency> dependencies = new ArrayList<>();
416                     while ( parser.nextTag() == XmlPullParser.START_TAG )
417                     {
418                         if ( "dependency".equals( parser.getName() ) )
419                         {
420                             dependencies.add( parseDependency( parser, strict, source ) );
421                         }
422                         else
423                         {
424                             checkUnknownElement( parser, strict );
425                         }
426                     }
427                     model.dependencies( dependencies );
428                     break;
429                 }
430                 case "repositories":
431                 {
432                     List<Repository> repositories = new ArrayList<>();
433                     while ( parser.nextTag() == XmlPullParser.START_TAG )
434                     {
435                         if ( "repository".equals( parser.getName() ) )
436                         {
437                             repositories.add( parseRepository( parser, strict, source ) );
438                         }
439                         else
440                         {
441                             checkUnknownElement( parser, strict );
442                         }
443                     }
444                     model.repositories( repositories );
445                     break;
446                 }
447                 case "pluginRepositories":
448                 {
449                     List<Repository> pluginRepositories = new ArrayList<>();
450                     while ( parser.nextTag() == XmlPullParser.START_TAG )
451                     {
452                         if ( "pluginRepository".equals( parser.getName() ) )
453                         {
454                             pluginRepositories.add( parseRepository( parser, strict, source ) );
455                         }
456                         else
457                         {
458                             checkUnknownElement( parser, strict );
459                         }
460                     }
461                     model.pluginRepositories( pluginRepositories );
462                     break;
463                 }
464                 case "build":
465                 {
466                     model.build( parseBuild( parser, strict, source ) );
467                     break;
468                 }
469                 case "reporting":
470                 {
471                     model.reporting( parseReporting( parser, strict, source ) );
472                     break;
473                 }
474                 case "profiles":
475                 {
476                     List<Profile> profiles = new ArrayList<>();
477                     while ( parser.nextTag() == XmlPullParser.START_TAG )
478                     {
479                         if ( "profile".equals( parser.getName() ) )
480                         {
481                             profiles.add( parseProfile( parser, strict, source ) );
482                         }
483                         else
484                         {
485                             checkUnknownElement( parser, strict );
486                         }
487                     }
488                     model.profiles( profiles );
489                     break;
490                 }
491                 default:
492                 {
493                     checkUnknownElement( parser, strict );
494                     break;
495                 }
496             }
497             model.location( childName, new InputLocation( line, column, source, locations ) );
498         }
499         model.modelEncoding( parser.getInputEncoding() );
500         return model.build();
501     }
502 
503     private ModelBase parseModelBase( XmlPullParser parser, boolean strict, InputSource source )
504         throws IOException, XmlPullParserException
505     {
506         String tagName = parser.getName();
507         ModelBase.Builder modelBase = ModelBase.newBuilder( true );
508         modelBase.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
509         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
510         {
511             String name = parser.getAttributeName( i );
512             String value = parser.getAttributeValue( i );
513             if ( name.indexOf( ':' ) >= 0 )
514             {
515                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
516             }
517             else
518             {
519                 checkUnknownAttribute( parser, name, tagName, strict );
520             }
521         }
522         Set<String> parsed = new HashSet<>();
523         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
524         {
525             String childName = unalias( parser.getName() );
526             if ( !parsed.add( childName ) )
527             {
528                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
529             }
530             int line = parser.getLineNumber();
531             int column = parser.getColumnNumber();
532             Map<Object, InputLocation> locations = null;
533             switch ( childName )
534             {
535                 case "modules":
536                 {
537                     List<String> modules = new ArrayList<>();
538                     locations = new HashMap<>();
539                     while ( parser.nextTag() == XmlPullParser.START_TAG )
540                     {
541                         if ( "module".equals( parser.getName() ) )
542                         {
543                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
544                             modules.add( interpolatedTrimmed( parser.nextText(), "modules" ) );
545                         }
546                         else
547                         {
548                             checkUnknownElement( parser, strict );
549                         }
550                     }
551                     modelBase.modules( modules );
552                     break;
553                 }
554                 case "distributionManagement":
555                 {
556                     modelBase.distributionManagement( parseDistributionManagement( parser, strict, source ) );
557                     break;
558                 }
559                 case "properties":
560                 {
561                     Map<String, String> properties = new LinkedHashMap<>();
562                     locations = new HashMap<>();
563                     while ( parser.nextTag() == XmlPullParser.START_TAG )
564                     {
565                         String key = parser.getName();
566                         String value = parser.nextText().trim();
567                         locations.put( key, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
568                         properties.put( key, value );
569                     }
570                     modelBase.properties( properties );
571                     break;
572                 }
573                 case "dependencyManagement":
574                 {
575                     modelBase.dependencyManagement( parseDependencyManagement( parser, strict, source ) );
576                     break;
577                 }
578                 case "dependencies":
579                 {
580                     List<Dependency> dependencies = new ArrayList<>();
581                     while ( parser.nextTag() == XmlPullParser.START_TAG )
582                     {
583                         if ( "dependency".equals( parser.getName() ) )
584                         {
585                             dependencies.add( parseDependency( parser, strict, source ) );
586                         }
587                         else
588                         {
589                             checkUnknownElement( parser, strict );
590                         }
591                     }
592                     modelBase.dependencies( dependencies );
593                     break;
594                 }
595                 case "repositories":
596                 {
597                     List<Repository> repositories = new ArrayList<>();
598                     while ( parser.nextTag() == XmlPullParser.START_TAG )
599                     {
600                         if ( "repository".equals( parser.getName() ) )
601                         {
602                             repositories.add( parseRepository( parser, strict, source ) );
603                         }
604                         else
605                         {
606                             checkUnknownElement( parser, strict );
607                         }
608                     }
609                     modelBase.repositories( repositories );
610                     break;
611                 }
612                 case "pluginRepositories":
613                 {
614                     List<Repository> pluginRepositories = new ArrayList<>();
615                     while ( parser.nextTag() == XmlPullParser.START_TAG )
616                     {
617                         if ( "pluginRepository".equals( parser.getName() ) )
618                         {
619                             pluginRepositories.add( parseRepository( parser, strict, source ) );
620                         }
621                         else
622                         {
623                             checkUnknownElement( parser, strict );
624                         }
625                     }
626                     modelBase.pluginRepositories( pluginRepositories );
627                     break;
628                 }
629                 case "reporting":
630                 {
631                     modelBase.reporting( parseReporting( parser, strict, source ) );
632                     break;
633                 }
634                 default:
635                 {
636                     checkUnknownElement( parser, strict );
637                     break;
638                 }
639             }
640             modelBase.location( childName, new InputLocation( line, column, source, locations ) );
641         }
642         return modelBase.build();
643     }
644 
645     private PluginContainer parsePluginContainer( XmlPullParser parser, boolean strict, InputSource source )
646         throws IOException, XmlPullParserException
647     {
648         String tagName = parser.getName();
649         PluginContainer.Builder pluginContainer = PluginContainer.newBuilder( true );
650         pluginContainer.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
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
660             {
661                 checkUnknownAttribute( parser, name, tagName, strict );
662             }
663         }
664         Set<String> parsed = new HashSet<>();
665         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
666         {
667             String childName = unalias( parser.getName() );
668             if ( !parsed.add( childName ) )
669             {
670                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
671             }
672             int line = parser.getLineNumber();
673             int column = parser.getColumnNumber();
674             Map<Object, InputLocation> locations = null;
675             switch ( childName )
676             {
677                 case "plugins":
678                 {
679                     List<Plugin> plugins = new ArrayList<>();
680                     while ( parser.nextTag() == XmlPullParser.START_TAG )
681                     {
682                         if ( "plugin".equals( parser.getName() ) )
683                         {
684                             plugins.add( parsePlugin( parser, strict, source ) );
685                         }
686                         else
687                         {
688                             checkUnknownElement( parser, strict );
689                         }
690                     }
691                     pluginContainer.plugins( plugins );
692                     break;
693                 }
694                 default:
695                 {
696                     checkUnknownElement( parser, strict );
697                     break;
698                 }
699             }
700             pluginContainer.location( childName, new InputLocation( line, column, source, locations ) );
701         }
702         return pluginContainer.build();
703     }
704 
705     private PluginConfiguration parsePluginConfiguration( XmlPullParser parser, boolean strict, InputSource source )
706         throws IOException, XmlPullParserException
707     {
708         String tagName = parser.getName();
709         PluginConfiguration.Builder pluginConfiguration = PluginConfiguration.newBuilder( true );
710         pluginConfiguration.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
711         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
712         {
713             String name = parser.getAttributeName( i );
714             String value = parser.getAttributeValue( i );
715             if ( name.indexOf( ':' ) >= 0 )
716             {
717                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
718             }
719             else
720             {
721                 checkUnknownAttribute( parser, name, tagName, strict );
722             }
723         }
724         Set<String> parsed = new HashSet<>();
725         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
726         {
727             String childName = unalias( parser.getName() );
728             if ( !parsed.add( childName ) )
729             {
730                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
731             }
732             int line = parser.getLineNumber();
733             int column = parser.getColumnNumber();
734             Map<Object, InputLocation> locations = null;
735             switch ( childName )
736             {
737                 case "pluginManagement":
738                 {
739                     pluginConfiguration.pluginManagement( parsePluginManagement( parser, strict, source ) );
740                     break;
741                 }
742                 case "plugins":
743                 {
744                     List<Plugin> plugins = new ArrayList<>();
745                     while ( parser.nextTag() == XmlPullParser.START_TAG )
746                     {
747                         if ( "plugin".equals( parser.getName() ) )
748                         {
749                             plugins.add( parsePlugin( parser, strict, source ) );
750                         }
751                         else
752                         {
753                             checkUnknownElement( parser, strict );
754                         }
755                     }
756                     pluginConfiguration.plugins( plugins );
757                     break;
758                 }
759                 default:
760                 {
761                     checkUnknownElement( parser, strict );
762                     break;
763                 }
764             }
765             pluginConfiguration.location( childName, new InputLocation( line, column, source, locations ) );
766         }
767         return pluginConfiguration.build();
768     }
769 
770     private BuildBase parseBuildBase( XmlPullParser parser, boolean strict, InputSource source )
771         throws IOException, XmlPullParserException
772     {
773         String tagName = parser.getName();
774         BuildBase.Builder buildBase = BuildBase.newBuilder( true );
775         buildBase.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
776         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
777         {
778             String name = parser.getAttributeName( i );
779             String value = parser.getAttributeValue( i );
780             if ( name.indexOf( ':' ) >= 0 )
781             {
782                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
783             }
784             else
785             {
786                 checkUnknownAttribute( parser, name, tagName, strict );
787             }
788         }
789         Set<String> parsed = new HashSet<>();
790         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
791         {
792             String childName = unalias( parser.getName() );
793             if ( !parsed.add( childName ) )
794             {
795                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
796             }
797             int line = parser.getLineNumber();
798             int column = parser.getColumnNumber();
799             Map<Object, InputLocation> locations = null;
800             switch ( childName )
801             {
802                 case "defaultGoal":
803                 {
804                     buildBase.defaultGoal( interpolatedTrimmed( parser.nextText(), "defaultGoal" ) );
805                     break;
806                 }
807                 case "resources":
808                 {
809                     List<Resource> resources = new ArrayList<>();
810                     while ( parser.nextTag() == XmlPullParser.START_TAG )
811                     {
812                         if ( "resource".equals( parser.getName() ) )
813                         {
814                             resources.add( parseResource( parser, strict, source ) );
815                         }
816                         else
817                         {
818                             checkUnknownElement( parser, strict );
819                         }
820                     }
821                     buildBase.resources( resources );
822                     break;
823                 }
824                 case "testResources":
825                 {
826                     List<Resource> testResources = new ArrayList<>();
827                     while ( parser.nextTag() == XmlPullParser.START_TAG )
828                     {
829                         if ( "testResource".equals( parser.getName() ) )
830                         {
831                             testResources.add( parseResource( parser, strict, source ) );
832                         }
833                         else
834                         {
835                             checkUnknownElement( parser, strict );
836                         }
837                     }
838                     buildBase.testResources( testResources );
839                     break;
840                 }
841                 case "directory":
842                 {
843                     buildBase.directory( interpolatedTrimmed( parser.nextText(), "directory" ) );
844                     break;
845                 }
846                 case "finalName":
847                 {
848                     buildBase.finalName( interpolatedTrimmed( parser.nextText(), "finalName" ) );
849                     break;
850                 }
851                 case "filters":
852                 {
853                     List<String> filters = new ArrayList<>();
854                     locations = new HashMap<>();
855                     while ( parser.nextTag() == XmlPullParser.START_TAG )
856                     {
857                         if ( "filter".equals( parser.getName() ) )
858                         {
859                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
860                             filters.add( interpolatedTrimmed( parser.nextText(), "filters" ) );
861                         }
862                         else
863                         {
864                             checkUnknownElement( parser, strict );
865                         }
866                     }
867                     buildBase.filters( filters );
868                     break;
869                 }
870                 case "pluginManagement":
871                 {
872                     buildBase.pluginManagement( parsePluginManagement( parser, strict, source ) );
873                     break;
874                 }
875                 case "plugins":
876                 {
877                     List<Plugin> plugins = new ArrayList<>();
878                     while ( parser.nextTag() == XmlPullParser.START_TAG )
879                     {
880                         if ( "plugin".equals( parser.getName() ) )
881                         {
882                             plugins.add( parsePlugin( parser, strict, source ) );
883                         }
884                         else
885                         {
886                             checkUnknownElement( parser, strict );
887                         }
888                     }
889                     buildBase.plugins( plugins );
890                     break;
891                 }
892                 default:
893                 {
894                     checkUnknownElement( parser, strict );
895                     break;
896                 }
897             }
898             buildBase.location( childName, new InputLocation( line, column, source, locations ) );
899         }
900         return buildBase.build();
901     }
902 
903     private Build parseBuild( XmlPullParser parser, boolean strict, InputSource source )
904         throws IOException, XmlPullParserException
905     {
906         String tagName = parser.getName();
907         Build.Builder build = Build.newBuilder( true );
908         build.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
909         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
910         {
911             String name = parser.getAttributeName( i );
912             String value = parser.getAttributeValue( i );
913             if ( name.indexOf( ':' ) >= 0 )
914             {
915                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
916             }
917             else
918             {
919                 checkUnknownAttribute( parser, name, tagName, strict );
920             }
921         }
922         Set<String> parsed = new HashSet<>();
923         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
924         {
925             String childName = unalias( parser.getName() );
926             if ( !parsed.add( childName ) )
927             {
928                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
929             }
930             int line = parser.getLineNumber();
931             int column = parser.getColumnNumber();
932             Map<Object, InputLocation> locations = null;
933             switch ( childName )
934             {
935                 case "sourceDirectory":
936                 {
937                     build.sourceDirectory( interpolatedTrimmed( parser.nextText(), "sourceDirectory" ) );
938                     break;
939                 }
940                 case "scriptSourceDirectory":
941                 {
942                     build.scriptSourceDirectory( interpolatedTrimmed( parser.nextText(), "scriptSourceDirectory" ) );
943                     break;
944                 }
945                 case "testSourceDirectory":
946                 {
947                     build.testSourceDirectory( interpolatedTrimmed( parser.nextText(), "testSourceDirectory" ) );
948                     break;
949                 }
950                 case "outputDirectory":
951                 {
952                     build.outputDirectory( interpolatedTrimmed( parser.nextText(), "outputDirectory" ) );
953                     break;
954                 }
955                 case "testOutputDirectory":
956                 {
957                     build.testOutputDirectory( interpolatedTrimmed( parser.nextText(), "testOutputDirectory" ) );
958                     break;
959                 }
960                 case "extensions":
961                 {
962                     List<Extension> extensions = new ArrayList<>();
963                     while ( parser.nextTag() == XmlPullParser.START_TAG )
964                     {
965                         if ( "extension".equals( parser.getName() ) )
966                         {
967                             extensions.add( parseExtension( parser, strict, source ) );
968                         }
969                         else
970                         {
971                             checkUnknownElement( parser, strict );
972                         }
973                     }
974                     build.extensions( extensions );
975                     break;
976                 }
977                 case "defaultGoal":
978                 {
979                     build.defaultGoal( interpolatedTrimmed( parser.nextText(), "defaultGoal" ) );
980                     break;
981                 }
982                 case "resources":
983                 {
984                     List<Resource> resources = new ArrayList<>();
985                     while ( parser.nextTag() == XmlPullParser.START_TAG )
986                     {
987                         if ( "resource".equals( parser.getName() ) )
988                         {
989                             resources.add( parseResource( parser, strict, source ) );
990                         }
991                         else
992                         {
993                             checkUnknownElement( parser, strict );
994                         }
995                     }
996                     build.resources( resources );
997                     break;
998                 }
999                 case "testResources":
1000                 {
1001                     List<Resource> testResources = new ArrayList<>();
1002                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1003                     {
1004                         if ( "testResource".equals( parser.getName() ) )
1005                         {
1006                             testResources.add( parseResource( parser, strict, source ) );
1007                         }
1008                         else
1009                         {
1010                             checkUnknownElement( parser, strict );
1011                         }
1012                     }
1013                     build.testResources( testResources );
1014                     break;
1015                 }
1016                 case "directory":
1017                 {
1018                     build.directory( interpolatedTrimmed( parser.nextText(), "directory" ) );
1019                     break;
1020                 }
1021                 case "finalName":
1022                 {
1023                     build.finalName( interpolatedTrimmed( parser.nextText(), "finalName" ) );
1024                     break;
1025                 }
1026                 case "filters":
1027                 {
1028                     List<String> filters = new ArrayList<>();
1029                     locations = new HashMap<>();
1030                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1031                     {
1032                         if ( "filter".equals( parser.getName() ) )
1033                         {
1034                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1035                             filters.add( interpolatedTrimmed( parser.nextText(), "filters" ) );
1036                         }
1037                         else
1038                         {
1039                             checkUnknownElement( parser, strict );
1040                         }
1041                     }
1042                     build.filters( filters );
1043                     break;
1044                 }
1045                 case "pluginManagement":
1046                 {
1047                     build.pluginManagement( parsePluginManagement( parser, strict, source ) );
1048                     break;
1049                 }
1050                 case "plugins":
1051                 {
1052                     List<Plugin> plugins = new ArrayList<>();
1053                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1054                     {
1055                         if ( "plugin".equals( parser.getName() ) )
1056                         {
1057                             plugins.add( parsePlugin( parser, strict, source ) );
1058                         }
1059                         else
1060                         {
1061                             checkUnknownElement( parser, strict );
1062                         }
1063                     }
1064                     build.plugins( plugins );
1065                     break;
1066                 }
1067                 default:
1068                 {
1069                     checkUnknownElement( parser, strict );
1070                     break;
1071                 }
1072             }
1073             build.location( childName, new InputLocation( line, column, source, locations ) );
1074         }
1075         return build.build();
1076     }
1077 
1078     private CiManagement parseCiManagement( XmlPullParser parser, boolean strict, InputSource source )
1079         throws IOException, XmlPullParserException
1080     {
1081         String tagName = parser.getName();
1082         CiManagement.Builder ciManagement = CiManagement.newBuilder( true );
1083         ciManagement.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1084         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1085         {
1086             String name = parser.getAttributeName( i );
1087             String value = parser.getAttributeValue( i );
1088             if ( name.indexOf( ':' ) >= 0 )
1089             {
1090                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1091             }
1092             else
1093             {
1094                 checkUnknownAttribute( parser, name, tagName, strict );
1095             }
1096         }
1097         Set<String> parsed = new HashSet<>();
1098         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1099         {
1100             String childName = unalias( parser.getName() );
1101             if ( !parsed.add( childName ) )
1102             {
1103                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1104             }
1105             int line = parser.getLineNumber();
1106             int column = parser.getColumnNumber();
1107             Map<Object, InputLocation> locations = null;
1108             switch ( childName )
1109             {
1110                 case "system":
1111                 {
1112                     ciManagement.system( interpolatedTrimmed( parser.nextText(), "system" ) );
1113                     break;
1114                 }
1115                 case "url":
1116                 {
1117                     ciManagement.url( interpolatedTrimmed( parser.nextText(), "url" ) );
1118                     break;
1119                 }
1120                 case "notifiers":
1121                 {
1122                     List<Notifier> notifiers = new ArrayList<>();
1123                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1124                     {
1125                         if ( "notifier".equals( parser.getName() ) )
1126                         {
1127                             notifiers.add( parseNotifier( parser, strict, source ) );
1128                         }
1129                         else
1130                         {
1131                             checkUnknownElement( parser, strict );
1132                         }
1133                     }
1134                     ciManagement.notifiers( notifiers );
1135                     break;
1136                 }
1137                 default:
1138                 {
1139                     checkUnknownElement( parser, strict );
1140                     break;
1141                 }
1142             }
1143             ciManagement.location( childName, new InputLocation( line, column, source, locations ) );
1144         }
1145         return ciManagement.build();
1146     }
1147 
1148     private Notifier parseNotifier( XmlPullParser parser, boolean strict, InputSource source )
1149         throws IOException, XmlPullParserException
1150     {
1151         String tagName = parser.getName();
1152         Notifier.Builder notifier = Notifier.newBuilder( true );
1153         notifier.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1154         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1155         {
1156             String name = parser.getAttributeName( i );
1157             String value = parser.getAttributeValue( i );
1158             if ( name.indexOf( ':' ) >= 0 )
1159             {
1160                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1161             }
1162             else
1163             {
1164                 checkUnknownAttribute( parser, name, tagName, strict );
1165             }
1166         }
1167         Set<String> parsed = new HashSet<>();
1168         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1169         {
1170             String childName = unalias( parser.getName() );
1171             if ( !parsed.add( childName ) )
1172             {
1173                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1174             }
1175             int line = parser.getLineNumber();
1176             int column = parser.getColumnNumber();
1177             Map<Object, InputLocation> locations = null;
1178             switch ( childName )
1179             {
1180                 case "type":
1181                 {
1182                     notifier.type( interpolatedTrimmed( parser.nextText(), "type" ) );
1183                     break;
1184                 }
1185                 case "sendOnError":
1186                 {
1187                     notifier.sendOnError( getBooleanValue( interpolatedTrimmed( parser.nextText(), "sendOnError" ), "sendOnError", parser, true ) );
1188                     break;
1189                 }
1190                 case "sendOnFailure":
1191                 {
1192                     notifier.sendOnFailure( getBooleanValue( interpolatedTrimmed( parser.nextText(), "sendOnFailure" ), "sendOnFailure", parser, true ) );
1193                     break;
1194                 }
1195                 case "sendOnSuccess":
1196                 {
1197                     notifier.sendOnSuccess( getBooleanValue( interpolatedTrimmed( parser.nextText(), "sendOnSuccess" ), "sendOnSuccess", parser, true ) );
1198                     break;
1199                 }
1200                 case "sendOnWarning":
1201                 {
1202                     notifier.sendOnWarning( getBooleanValue( interpolatedTrimmed( parser.nextText(), "sendOnWarning" ), "sendOnWarning", parser, true ) );
1203                     break;
1204                 }
1205                 case "address":
1206                 {
1207                     notifier.address( interpolatedTrimmed( parser.nextText(), "address" ) );
1208                     break;
1209                 }
1210                 case "configuration":
1211                 {
1212                     Map<String, String> configuration = new LinkedHashMap<>();
1213                     locations = new HashMap<>();
1214                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1215                     {
1216                         String key = parser.getName();
1217                         String value = parser.nextText().trim();
1218                         locations.put( key, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1219                         configuration.put( key, value );
1220                     }
1221                     notifier.configuration( configuration );
1222                     break;
1223                 }
1224                 default:
1225                 {
1226                     checkUnknownElement( parser, strict );
1227                     break;
1228                 }
1229             }
1230             notifier.location( childName, new InputLocation( line, column, source, locations ) );
1231         }
1232         return notifier.build();
1233     }
1234 
1235     private Contributor parseContributor( XmlPullParser parser, boolean strict, InputSource source )
1236         throws IOException, XmlPullParserException
1237     {
1238         String tagName = parser.getName();
1239         Contributor.Builder contributor = Contributor.newBuilder( true );
1240         contributor.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1241         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1242         {
1243             String name = parser.getAttributeName( i );
1244             String value = parser.getAttributeValue( i );
1245             if ( name.indexOf( ':' ) >= 0 )
1246             {
1247                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1248             }
1249             else
1250             {
1251                 checkUnknownAttribute( parser, name, tagName, strict );
1252             }
1253         }
1254         Set<String> parsed = new HashSet<>();
1255         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1256         {
1257             String childName = unalias( parser.getName() );
1258             if ( !parsed.add( childName ) )
1259             {
1260                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1261             }
1262             int line = parser.getLineNumber();
1263             int column = parser.getColumnNumber();
1264             Map<Object, InputLocation> locations = null;
1265             switch ( childName )
1266             {
1267                 case "name":
1268                 {
1269                     contributor.name( interpolatedTrimmed( parser.nextText(), "name" ) );
1270                     break;
1271                 }
1272                 case "email":
1273                 {
1274                     contributor.email( interpolatedTrimmed( parser.nextText(), "email" ) );
1275                     break;
1276                 }
1277                 case "url":
1278                 {
1279                     contributor.url( interpolatedTrimmed( parser.nextText(), "url" ) );
1280                     break;
1281                 }
1282                 case "organization":
1283                 {
1284                     contributor.organization( interpolatedTrimmed( parser.nextText(), "organization" ) );
1285                     break;
1286                 }
1287                 case "organizationUrl":
1288                 {
1289                     contributor.organizationUrl( interpolatedTrimmed( parser.nextText(), "organizationUrl" ) );
1290                     break;
1291                 }
1292                 case "roles":
1293                 {
1294                     List<String> roles = new ArrayList<>();
1295                     locations = new HashMap<>();
1296                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1297                     {
1298                         if ( "role".equals( parser.getName() ) )
1299                         {
1300                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1301                             roles.add( interpolatedTrimmed( parser.nextText(), "roles" ) );
1302                         }
1303                         else
1304                         {
1305                             checkUnknownElement( parser, strict );
1306                         }
1307                     }
1308                     contributor.roles( roles );
1309                     break;
1310                 }
1311                 case "timezone":
1312                 {
1313                     contributor.timezone( interpolatedTrimmed( parser.nextText(), "timezone" ) );
1314                     break;
1315                 }
1316                 case "properties":
1317                 {
1318                     Map<String, String> properties = new LinkedHashMap<>();
1319                     locations = new HashMap<>();
1320                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1321                     {
1322                         String key = parser.getName();
1323                         String value = parser.nextText().trim();
1324                         locations.put( key, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1325                         properties.put( key, value );
1326                     }
1327                     contributor.properties( properties );
1328                     break;
1329                 }
1330                 default:
1331                 {
1332                     checkUnknownElement( parser, strict );
1333                     break;
1334                 }
1335             }
1336             contributor.location( childName, new InputLocation( line, column, source, locations ) );
1337         }
1338         return contributor.build();
1339     }
1340 
1341     private Dependency parseDependency( XmlPullParser parser, boolean strict, InputSource source )
1342         throws IOException, XmlPullParserException
1343     {
1344         String tagName = parser.getName();
1345         Dependency.Builder dependency = Dependency.newBuilder( true );
1346         dependency.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1347         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1348         {
1349             String name = parser.getAttributeName( i );
1350             String value = parser.getAttributeValue( i );
1351             if ( name.indexOf( ':' ) >= 0 )
1352             {
1353                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1354             }
1355             else
1356             {
1357                 checkUnknownAttribute( parser, name, tagName, strict );
1358             }
1359         }
1360         Set<String> parsed = new HashSet<>();
1361         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1362         {
1363             String childName = unalias( parser.getName() );
1364             if ( !parsed.add( childName ) )
1365             {
1366                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1367             }
1368             int line = parser.getLineNumber();
1369             int column = parser.getColumnNumber();
1370             Map<Object, InputLocation> locations = null;
1371             switch ( childName )
1372             {
1373                 case "groupId":
1374                 {
1375                     dependency.groupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
1376                     break;
1377                 }
1378                 case "artifactId":
1379                 {
1380                     dependency.artifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
1381                     break;
1382                 }
1383                 case "version":
1384                 {
1385                     dependency.version( interpolatedTrimmed( parser.nextText(), "version" ) );
1386                     break;
1387                 }
1388                 case "type":
1389                 {
1390                     dependency.type( interpolatedTrimmed( parser.nextText(), "type" ) );
1391                     break;
1392                 }
1393                 case "classifier":
1394                 {
1395                     dependency.classifier( interpolatedTrimmed( parser.nextText(), "classifier" ) );
1396                     break;
1397                 }
1398                 case "scope":
1399                 {
1400                     dependency.scope( interpolatedTrimmed( parser.nextText(), "scope" ) );
1401                     break;
1402                 }
1403                 case "systemPath":
1404                 {
1405                     dependency.systemPath( interpolatedTrimmed( parser.nextText(), "systemPath" ) );
1406                     break;
1407                 }
1408                 case "exclusions":
1409                 {
1410                     List<Exclusion> exclusions = new ArrayList<>();
1411                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1412                     {
1413                         if ( "exclusion".equals( parser.getName() ) )
1414                         {
1415                             exclusions.add( parseExclusion( parser, strict, source ) );
1416                         }
1417                         else
1418                         {
1419                             checkUnknownElement( parser, strict );
1420                         }
1421                     }
1422                     dependency.exclusions( exclusions );
1423                     break;
1424                 }
1425                 case "optional":
1426                 {
1427                     dependency.optional( interpolatedTrimmed( parser.nextText(), "optional" ) );
1428                     break;
1429                 }
1430                 default:
1431                 {
1432                     checkUnknownElement( parser, strict );
1433                     break;
1434                 }
1435             }
1436             dependency.location( childName, new InputLocation( line, column, source, locations ) );
1437         }
1438         return dependency.build();
1439     }
1440 
1441     private Developer parseDeveloper( XmlPullParser parser, boolean strict, InputSource source )
1442         throws IOException, XmlPullParserException
1443     {
1444         String tagName = parser.getName();
1445         Developer.Builder developer = Developer.newBuilder( true );
1446         developer.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1447         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1448         {
1449             String name = parser.getAttributeName( i );
1450             String value = parser.getAttributeValue( i );
1451             if ( name.indexOf( ':' ) >= 0 )
1452             {
1453                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1454             }
1455             else
1456             {
1457                 checkUnknownAttribute( parser, name, tagName, strict );
1458             }
1459         }
1460         Set<String> parsed = new HashSet<>();
1461         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1462         {
1463             String childName = unalias( parser.getName() );
1464             if ( !parsed.add( childName ) )
1465             {
1466                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1467             }
1468             int line = parser.getLineNumber();
1469             int column = parser.getColumnNumber();
1470             Map<Object, InputLocation> locations = null;
1471             switch ( childName )
1472             {
1473                 case "id":
1474                 {
1475                     developer.id( interpolatedTrimmed( parser.nextText(), "id" ) );
1476                     break;
1477                 }
1478                 case "name":
1479                 {
1480                     developer.name( interpolatedTrimmed( parser.nextText(), "name" ) );
1481                     break;
1482                 }
1483                 case "email":
1484                 {
1485                     developer.email( interpolatedTrimmed( parser.nextText(), "email" ) );
1486                     break;
1487                 }
1488                 case "url":
1489                 {
1490                     developer.url( interpolatedTrimmed( parser.nextText(), "url" ) );
1491                     break;
1492                 }
1493                 case "organization":
1494                 {
1495                     developer.organization( interpolatedTrimmed( parser.nextText(), "organization" ) );
1496                     break;
1497                 }
1498                 case "organizationUrl":
1499                 {
1500                     developer.organizationUrl( interpolatedTrimmed( parser.nextText(), "organizationUrl" ) );
1501                     break;
1502                 }
1503                 case "roles":
1504                 {
1505                     List<String> roles = new ArrayList<>();
1506                     locations = new HashMap<>();
1507                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1508                     {
1509                         if ( "role".equals( parser.getName() ) )
1510                         {
1511                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1512                             roles.add( interpolatedTrimmed( parser.nextText(), "roles" ) );
1513                         }
1514                         else
1515                         {
1516                             checkUnknownElement( parser, strict );
1517                         }
1518                     }
1519                     developer.roles( roles );
1520                     break;
1521                 }
1522                 case "timezone":
1523                 {
1524                     developer.timezone( interpolatedTrimmed( parser.nextText(), "timezone" ) );
1525                     break;
1526                 }
1527                 case "properties":
1528                 {
1529                     Map<String, String> properties = new LinkedHashMap<>();
1530                     locations = new HashMap<>();
1531                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1532                     {
1533                         String key = parser.getName();
1534                         String value = parser.nextText().trim();
1535                         locations.put( key, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1536                         properties.put( key, value );
1537                     }
1538                     developer.properties( properties );
1539                     break;
1540                 }
1541                 default:
1542                 {
1543                     checkUnknownElement( parser, strict );
1544                     break;
1545                 }
1546             }
1547             developer.location( childName, new InputLocation( line, column, source, locations ) );
1548         }
1549         return developer.build();
1550     }
1551 
1552     private Exclusion parseExclusion( XmlPullParser parser, boolean strict, InputSource source )
1553         throws IOException, XmlPullParserException
1554     {
1555         String tagName = parser.getName();
1556         Exclusion.Builder exclusion = Exclusion.newBuilder( true );
1557         exclusion.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1558         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1559         {
1560             String name = parser.getAttributeName( i );
1561             String value = parser.getAttributeValue( i );
1562             if ( name.indexOf( ':' ) >= 0 )
1563             {
1564                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1565             }
1566             else
1567             {
1568                 checkUnknownAttribute( parser, name, tagName, strict );
1569             }
1570         }
1571         Set<String> parsed = new HashSet<>();
1572         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1573         {
1574             String childName = unalias( parser.getName() );
1575             if ( !parsed.add( childName ) )
1576             {
1577                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1578             }
1579             int line = parser.getLineNumber();
1580             int column = parser.getColumnNumber();
1581             Map<Object, InputLocation> locations = null;
1582             switch ( childName )
1583             {
1584                 case "groupId":
1585                 {
1586                     exclusion.groupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
1587                     break;
1588                 }
1589                 case "artifactId":
1590                 {
1591                     exclusion.artifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
1592                     break;
1593                 }
1594                 default:
1595                 {
1596                     checkUnknownElement( parser, strict );
1597                     break;
1598                 }
1599             }
1600             exclusion.location( childName, new InputLocation( line, column, source, locations ) );
1601         }
1602         return exclusion.build();
1603     }
1604 
1605     private IssueManagement parseIssueManagement( XmlPullParser parser, boolean strict, InputSource source )
1606         throws IOException, XmlPullParserException
1607     {
1608         String tagName = parser.getName();
1609         IssueManagement.Builder issueManagement = IssueManagement.newBuilder( true );
1610         issueManagement.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1611         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1612         {
1613             String name = parser.getAttributeName( i );
1614             String value = parser.getAttributeValue( i );
1615             if ( name.indexOf( ':' ) >= 0 )
1616             {
1617                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1618             }
1619             else
1620             {
1621                 checkUnknownAttribute( parser, name, tagName, strict );
1622             }
1623         }
1624         Set<String> parsed = new HashSet<>();
1625         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1626         {
1627             String childName = unalias( parser.getName() );
1628             if ( !parsed.add( childName ) )
1629             {
1630                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1631             }
1632             int line = parser.getLineNumber();
1633             int column = parser.getColumnNumber();
1634             Map<Object, InputLocation> locations = null;
1635             switch ( childName )
1636             {
1637                 case "system":
1638                 {
1639                     issueManagement.system( interpolatedTrimmed( parser.nextText(), "system" ) );
1640                     break;
1641                 }
1642                 case "url":
1643                 {
1644                     issueManagement.url( interpolatedTrimmed( parser.nextText(), "url" ) );
1645                     break;
1646                 }
1647                 default:
1648                 {
1649                     checkUnknownElement( parser, strict );
1650                     break;
1651                 }
1652             }
1653             issueManagement.location( childName, new InputLocation( line, column, source, locations ) );
1654         }
1655         return issueManagement.build();
1656     }
1657 
1658     private DistributionManagement parseDistributionManagement( XmlPullParser parser, boolean strict, InputSource source )
1659         throws IOException, XmlPullParserException
1660     {
1661         String tagName = parser.getName();
1662         DistributionManagement.Builder distributionManagement = DistributionManagement.newBuilder( true );
1663         distributionManagement.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1664         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1665         {
1666             String name = parser.getAttributeName( i );
1667             String value = parser.getAttributeValue( i );
1668             if ( name.indexOf( ':' ) >= 0 )
1669             {
1670                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1671             }
1672             else
1673             {
1674                 checkUnknownAttribute( parser, name, tagName, strict );
1675             }
1676         }
1677         Set<String> parsed = new HashSet<>();
1678         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1679         {
1680             String childName = unalias( parser.getName() );
1681             if ( !parsed.add( childName ) )
1682             {
1683                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1684             }
1685             int line = parser.getLineNumber();
1686             int column = parser.getColumnNumber();
1687             Map<Object, InputLocation> locations = null;
1688             switch ( childName )
1689             {
1690                 case "repository":
1691                 {
1692                     distributionManagement.repository( parseDeploymentRepository( parser, strict, source ) );
1693                     break;
1694                 }
1695                 case "snapshotRepository":
1696                 {
1697                     distributionManagement.snapshotRepository( parseDeploymentRepository( parser, strict, source ) );
1698                     break;
1699                 }
1700                 case "site":
1701                 {
1702                     distributionManagement.site( parseSite( parser, strict, source ) );
1703                     break;
1704                 }
1705                 case "downloadUrl":
1706                 {
1707                     distributionManagement.downloadUrl( interpolatedTrimmed( parser.nextText(), "downloadUrl" ) );
1708                     break;
1709                 }
1710                 case "relocation":
1711                 {
1712                     distributionManagement.relocation( parseRelocation( parser, strict, source ) );
1713                     break;
1714                 }
1715                 case "status":
1716                 {
1717                     distributionManagement.status( interpolatedTrimmed( parser.nextText(), "status" ) );
1718                     break;
1719                 }
1720                 default:
1721                 {
1722                     checkUnknownElement( parser, strict );
1723                     break;
1724                 }
1725             }
1726             distributionManagement.location( childName, new InputLocation( line, column, source, locations ) );
1727         }
1728         return distributionManagement.build();
1729     }
1730 
1731     private License parseLicense( XmlPullParser parser, boolean strict, InputSource source )
1732         throws IOException, XmlPullParserException
1733     {
1734         String tagName = parser.getName();
1735         License.Builder license = License.newBuilder( true );
1736         license.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1737         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1738         {
1739             String name = parser.getAttributeName( i );
1740             String value = parser.getAttributeValue( i );
1741             if ( name.indexOf( ':' ) >= 0 )
1742             {
1743                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1744             }
1745             else
1746             {
1747                 checkUnknownAttribute( parser, name, tagName, strict );
1748             }
1749         }
1750         Set<String> parsed = new HashSet<>();
1751         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1752         {
1753             String childName = unalias( parser.getName() );
1754             if ( !parsed.add( childName ) )
1755             {
1756                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1757             }
1758             int line = parser.getLineNumber();
1759             int column = parser.getColumnNumber();
1760             Map<Object, InputLocation> locations = null;
1761             switch ( childName )
1762             {
1763                 case "name":
1764                 {
1765                     license.name( interpolatedTrimmed( parser.nextText(), "name" ) );
1766                     break;
1767                 }
1768                 case "url":
1769                 {
1770                     license.url( interpolatedTrimmed( parser.nextText(), "url" ) );
1771                     break;
1772                 }
1773                 case "distribution":
1774                 {
1775                     license.distribution( interpolatedTrimmed( parser.nextText(), "distribution" ) );
1776                     break;
1777                 }
1778                 case "comments":
1779                 {
1780                     license.comments( interpolatedTrimmed( parser.nextText(), "comments" ) );
1781                     break;
1782                 }
1783                 default:
1784                 {
1785                     checkUnknownElement( parser, strict );
1786                     break;
1787                 }
1788             }
1789             license.location( childName, new InputLocation( line, column, source, locations ) );
1790         }
1791         return license.build();
1792     }
1793 
1794     private MailingList parseMailingList( XmlPullParser parser, boolean strict, InputSource source )
1795         throws IOException, XmlPullParserException
1796     {
1797         String tagName = parser.getName();
1798         MailingList.Builder mailingList = MailingList.newBuilder( true );
1799         mailingList.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1800         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1801         {
1802             String name = parser.getAttributeName( i );
1803             String value = parser.getAttributeValue( i );
1804             if ( name.indexOf( ':' ) >= 0 )
1805             {
1806                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1807             }
1808             else
1809             {
1810                 checkUnknownAttribute( parser, name, tagName, strict );
1811             }
1812         }
1813         Set<String> parsed = new HashSet<>();
1814         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1815         {
1816             String childName = unalias( parser.getName() );
1817             if ( !parsed.add( childName ) )
1818             {
1819                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1820             }
1821             int line = parser.getLineNumber();
1822             int column = parser.getColumnNumber();
1823             Map<Object, InputLocation> locations = null;
1824             switch ( childName )
1825             {
1826                 case "name":
1827                 {
1828                     mailingList.name( interpolatedTrimmed( parser.nextText(), "name" ) );
1829                     break;
1830                 }
1831                 case "subscribe":
1832                 {
1833                     mailingList.subscribe( interpolatedTrimmed( parser.nextText(), "subscribe" ) );
1834                     break;
1835                 }
1836                 case "unsubscribe":
1837                 {
1838                     mailingList.unsubscribe( interpolatedTrimmed( parser.nextText(), "unsubscribe" ) );
1839                     break;
1840                 }
1841                 case "post":
1842                 {
1843                     mailingList.post( interpolatedTrimmed( parser.nextText(), "post" ) );
1844                     break;
1845                 }
1846                 case "archive":
1847                 {
1848                     mailingList.archive( interpolatedTrimmed( parser.nextText(), "archive" ) );
1849                     break;
1850                 }
1851                 case "otherArchives":
1852                 {
1853                     List<String> otherArchives = new ArrayList<>();
1854                     locations = new HashMap<>();
1855                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1856                     {
1857                         if ( "otherArchive".equals( parser.getName() ) )
1858                         {
1859                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1860                             otherArchives.add( interpolatedTrimmed( parser.nextText(), "otherArchives" ) );
1861                         }
1862                         else
1863                         {
1864                             checkUnknownElement( parser, strict );
1865                         }
1866                     }
1867                     mailingList.otherArchives( otherArchives );
1868                     break;
1869                 }
1870                 default:
1871                 {
1872                     checkUnknownElement( parser, strict );
1873                     break;
1874                 }
1875             }
1876             mailingList.location( childName, new InputLocation( line, column, source, locations ) );
1877         }
1878         return mailingList.build();
1879     }
1880 
1881     private Organization parseOrganization( XmlPullParser parser, boolean strict, InputSource source )
1882         throws IOException, XmlPullParserException
1883     {
1884         String tagName = parser.getName();
1885         Organization.Builder organization = Organization.newBuilder( true );
1886         organization.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1887         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1888         {
1889             String name = parser.getAttributeName( i );
1890             String value = parser.getAttributeValue( i );
1891             if ( name.indexOf( ':' ) >= 0 )
1892             {
1893                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1894             }
1895             else
1896             {
1897                 checkUnknownAttribute( parser, name, tagName, strict );
1898             }
1899         }
1900         Set<String> parsed = new HashSet<>();
1901         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1902         {
1903             String childName = unalias( parser.getName() );
1904             if ( !parsed.add( childName ) )
1905             {
1906                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1907             }
1908             int line = parser.getLineNumber();
1909             int column = parser.getColumnNumber();
1910             Map<Object, InputLocation> locations = null;
1911             switch ( childName )
1912             {
1913                 case "name":
1914                 {
1915                     organization.name( interpolatedTrimmed( parser.nextText(), "name" ) );
1916                     break;
1917                 }
1918                 case "url":
1919                 {
1920                     organization.url( interpolatedTrimmed( parser.nextText(), "url" ) );
1921                     break;
1922                 }
1923                 default:
1924                 {
1925                     checkUnknownElement( parser, strict );
1926                     break;
1927                 }
1928             }
1929             organization.location( childName, new InputLocation( line, column, source, locations ) );
1930         }
1931         return organization.build();
1932     }
1933 
1934     private PatternSet parsePatternSet( XmlPullParser parser, boolean strict, InputSource source )
1935         throws IOException, XmlPullParserException
1936     {
1937         String tagName = parser.getName();
1938         PatternSet.Builder patternSet = PatternSet.newBuilder( true );
1939         patternSet.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1940         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1941         {
1942             String name = parser.getAttributeName( i );
1943             String value = parser.getAttributeValue( i );
1944             if ( name.indexOf( ':' ) >= 0 )
1945             {
1946                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1947             }
1948             else
1949             {
1950                 checkUnknownAttribute( parser, name, tagName, strict );
1951             }
1952         }
1953         Set<String> parsed = new HashSet<>();
1954         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1955         {
1956             String childName = unalias( parser.getName() );
1957             if ( !parsed.add( childName ) )
1958             {
1959                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
1960             }
1961             int line = parser.getLineNumber();
1962             int column = parser.getColumnNumber();
1963             Map<Object, InputLocation> locations = null;
1964             switch ( childName )
1965             {
1966                 case "includes":
1967                 {
1968                     List<String> includes = new ArrayList<>();
1969                     locations = new HashMap<>();
1970                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1971                     {
1972                         if ( "include".equals( parser.getName() ) )
1973                         {
1974                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1975                             includes.add( interpolatedTrimmed( parser.nextText(), "includes" ) );
1976                         }
1977                         else
1978                         {
1979                             checkUnknownElement( parser, strict );
1980                         }
1981                     }
1982                     patternSet.includes( includes );
1983                     break;
1984                 }
1985                 case "excludes":
1986                 {
1987                     List<String> excludes = new ArrayList<>();
1988                     locations = new HashMap<>();
1989                     while ( parser.nextTag() == XmlPullParser.START_TAG )
1990                     {
1991                         if ( "exclude".equals( parser.getName() ) )
1992                         {
1993                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
1994                             excludes.add( interpolatedTrimmed( parser.nextText(), "excludes" ) );
1995                         }
1996                         else
1997                         {
1998                             checkUnknownElement( parser, strict );
1999                         }
2000                     }
2001                     patternSet.excludes( excludes );
2002                     break;
2003                 }
2004                 default:
2005                 {
2006                     checkUnknownElement( parser, strict );
2007                     break;
2008                 }
2009             }
2010             patternSet.location( childName, new InputLocation( line, column, source, locations ) );
2011         }
2012         return patternSet.build();
2013     }
2014 
2015     private Parent parseParent( XmlPullParser parser, boolean strict, InputSource source )
2016         throws IOException, XmlPullParserException
2017     {
2018         String tagName = parser.getName();
2019         Parent.Builder parent = Parent.newBuilder( true );
2020         parent.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2021         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2022         {
2023             String name = parser.getAttributeName( i );
2024             String value = parser.getAttributeValue( i );
2025             if ( name.indexOf( ':' ) >= 0 )
2026             {
2027                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2028             }
2029             else
2030             {
2031                 checkUnknownAttribute( parser, name, tagName, strict );
2032             }
2033         }
2034         Set<String> parsed = new HashSet<>();
2035         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2036         {
2037             String childName = unalias( parser.getName() );
2038             if ( !parsed.add( childName ) )
2039             {
2040                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2041             }
2042             int line = parser.getLineNumber();
2043             int column = parser.getColumnNumber();
2044             Map<Object, InputLocation> locations = null;
2045             switch ( childName )
2046             {
2047                 case "groupId":
2048                 {
2049                     parent.groupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
2050                     break;
2051                 }
2052                 case "artifactId":
2053                 {
2054                     parent.artifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
2055                     break;
2056                 }
2057                 case "version":
2058                 {
2059                     parent.version( interpolatedTrimmed( parser.nextText(), "version" ) );
2060                     break;
2061                 }
2062                 case "relativePath":
2063                 {
2064                     parent.relativePath( interpolatedTrimmed( parser.nextText(), "relativePath" ) );
2065                     break;
2066                 }
2067                 default:
2068                 {
2069                     checkUnknownElement( parser, strict );
2070                     break;
2071                 }
2072             }
2073             parent.location( childName, new InputLocation( line, column, source, locations ) );
2074         }
2075         return parent.build();
2076     }
2077 
2078     private Scm parseScm( XmlPullParser parser, boolean strict, InputSource source )
2079         throws IOException, XmlPullParserException
2080     {
2081         String tagName = parser.getName();
2082         Scm.Builder scm = Scm.newBuilder( true );
2083         scm.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2084         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2085         {
2086             String name = parser.getAttributeName( i );
2087             String value = parser.getAttributeValue( i );
2088             if ( name.indexOf( ':' ) >= 0 )
2089             {
2090                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2091             }
2092             else if ( "child.scm.connection.inherit.append.path".equals( name ) )
2093             {
2094                 scm.location( name, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2095                 scm.childScmConnectionInheritAppendPath( interpolatedTrimmed( value, "child.scm.connection.inherit.append.path" ) );
2096             }
2097             else if ( "child.scm.developerConnection.inherit.append.path".equals( name ) )
2098             {
2099                 scm.location( name, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2100                 scm.childScmDeveloperConnectionInheritAppendPath( interpolatedTrimmed( value, "child.scm.developerConnection.inherit.append.path" ) );
2101             }
2102             else if ( "child.scm.url.inherit.append.path".equals( name ) )
2103             {
2104                 scm.location( name, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2105                 scm.childScmUrlInheritAppendPath( interpolatedTrimmed( value, "child.scm.url.inherit.append.path" ) );
2106             }
2107             else
2108             {
2109                 checkUnknownAttribute( parser, name, tagName, strict );
2110             }
2111         }
2112         Set<String> parsed = new HashSet<>();
2113         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2114         {
2115             String childName = unalias( parser.getName() );
2116             if ( !parsed.add( childName ) )
2117             {
2118                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2119             }
2120             int line = parser.getLineNumber();
2121             int column = parser.getColumnNumber();
2122             Map<Object, InputLocation> locations = null;
2123             switch ( childName )
2124             {
2125                 case "connection":
2126                 {
2127                     scm.connection( interpolatedTrimmed( parser.nextText(), "connection" ) );
2128                     break;
2129                 }
2130                 case "developerConnection":
2131                 {
2132                     scm.developerConnection( interpolatedTrimmed( parser.nextText(), "developerConnection" ) );
2133                     break;
2134                 }
2135                 case "tag":
2136                 {
2137                     scm.tag( interpolatedTrimmed( parser.nextText(), "tag" ) );
2138                     break;
2139                 }
2140                 case "url":
2141                 {
2142                     scm.url( interpolatedTrimmed( parser.nextText(), "url" ) );
2143                     break;
2144                 }
2145                 default:
2146                 {
2147                     checkUnknownElement( parser, strict );
2148                     break;
2149                 }
2150             }
2151             scm.location( childName, new InputLocation( line, column, source, locations ) );
2152         }
2153         return scm.build();
2154     }
2155 
2156     private FileSet parseFileSet( XmlPullParser parser, boolean strict, InputSource source )
2157         throws IOException, XmlPullParserException
2158     {
2159         String tagName = parser.getName();
2160         FileSet.Builder fileSet = FileSet.newBuilder( true );
2161         fileSet.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2162         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2163         {
2164             String name = parser.getAttributeName( i );
2165             String value = parser.getAttributeValue( i );
2166             if ( name.indexOf( ':' ) >= 0 )
2167             {
2168                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2169             }
2170             else
2171             {
2172                 checkUnknownAttribute( parser, name, tagName, strict );
2173             }
2174         }
2175         Set<String> parsed = new HashSet<>();
2176         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2177         {
2178             String childName = unalias( parser.getName() );
2179             if ( !parsed.add( childName ) )
2180             {
2181                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2182             }
2183             int line = parser.getLineNumber();
2184             int column = parser.getColumnNumber();
2185             Map<Object, InputLocation> locations = null;
2186             switch ( childName )
2187             {
2188                 case "directory":
2189                 {
2190                     fileSet.directory( interpolatedTrimmed( parser.nextText(), "directory" ) );
2191                     break;
2192                 }
2193                 case "includes":
2194                 {
2195                     List<String> includes = new ArrayList<>();
2196                     locations = new HashMap<>();
2197                     while ( parser.nextTag() == XmlPullParser.START_TAG )
2198                     {
2199                         if ( "include".equals( parser.getName() ) )
2200                         {
2201                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2202                             includes.add( interpolatedTrimmed( parser.nextText(), "includes" ) );
2203                         }
2204                         else
2205                         {
2206                             checkUnknownElement( parser, strict );
2207                         }
2208                     }
2209                     fileSet.includes( includes );
2210                     break;
2211                 }
2212                 case "excludes":
2213                 {
2214                     List<String> excludes = new ArrayList<>();
2215                     locations = new HashMap<>();
2216                     while ( parser.nextTag() == XmlPullParser.START_TAG )
2217                     {
2218                         if ( "exclude".equals( parser.getName() ) )
2219                         {
2220                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2221                             excludes.add( interpolatedTrimmed( parser.nextText(), "excludes" ) );
2222                         }
2223                         else
2224                         {
2225                             checkUnknownElement( parser, strict );
2226                         }
2227                     }
2228                     fileSet.excludes( excludes );
2229                     break;
2230                 }
2231                 default:
2232                 {
2233                     checkUnknownElement( parser, strict );
2234                     break;
2235                 }
2236             }
2237             fileSet.location( childName, new InputLocation( line, column, source, locations ) );
2238         }
2239         return fileSet.build();
2240     }
2241 
2242     private Resource parseResource( XmlPullParser parser, boolean strict, InputSource source )
2243         throws IOException, XmlPullParserException
2244     {
2245         String tagName = parser.getName();
2246         Resource.Builder resource = Resource.newBuilder( true );
2247         resource.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2248         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2249         {
2250             String name = parser.getAttributeName( i );
2251             String value = parser.getAttributeValue( i );
2252             if ( name.indexOf( ':' ) >= 0 )
2253             {
2254                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2255             }
2256             else
2257             {
2258                 checkUnknownAttribute( parser, name, tagName, strict );
2259             }
2260         }
2261         Set<String> parsed = new HashSet<>();
2262         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2263         {
2264             String childName = unalias( parser.getName() );
2265             if ( !parsed.add( childName ) )
2266             {
2267                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2268             }
2269             int line = parser.getLineNumber();
2270             int column = parser.getColumnNumber();
2271             Map<Object, InputLocation> locations = null;
2272             switch ( childName )
2273             {
2274                 case "targetPath":
2275                 {
2276                     resource.targetPath( interpolatedTrimmed( parser.nextText(), "targetPath" ) );
2277                     break;
2278                 }
2279                 case "filtering":
2280                 {
2281                     resource.filtering( interpolatedTrimmed( parser.nextText(), "filtering" ) );
2282                     break;
2283                 }
2284                 case "directory":
2285                 {
2286                     resource.directory( interpolatedTrimmed( parser.nextText(), "directory" ) );
2287                     break;
2288                 }
2289                 case "includes":
2290                 {
2291                     List<String> includes = new ArrayList<>();
2292                     locations = new HashMap<>();
2293                     while ( parser.nextTag() == XmlPullParser.START_TAG )
2294                     {
2295                         if ( "include".equals( parser.getName() ) )
2296                         {
2297                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2298                             includes.add( interpolatedTrimmed( parser.nextText(), "includes" ) );
2299                         }
2300                         else
2301                         {
2302                             checkUnknownElement( parser, strict );
2303                         }
2304                     }
2305                     resource.includes( includes );
2306                     break;
2307                 }
2308                 case "excludes":
2309                 {
2310                     List<String> excludes = new ArrayList<>();
2311                     locations = new HashMap<>();
2312                     while ( parser.nextTag() == XmlPullParser.START_TAG )
2313                     {
2314                         if ( "exclude".equals( parser.getName() ) )
2315                         {
2316                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2317                             excludes.add( interpolatedTrimmed( parser.nextText(), "excludes" ) );
2318                         }
2319                         else
2320                         {
2321                             checkUnknownElement( parser, strict );
2322                         }
2323                     }
2324                     resource.excludes( excludes );
2325                     break;
2326                 }
2327                 default:
2328                 {
2329                     checkUnknownElement( parser, strict );
2330                     break;
2331                 }
2332             }
2333             resource.location( childName, new InputLocation( line, column, source, locations ) );
2334         }
2335         return resource.build();
2336     }
2337 
2338     private RepositoryBase parseRepositoryBase( XmlPullParser parser, boolean strict, InputSource source )
2339         throws IOException, XmlPullParserException
2340     {
2341         String tagName = parser.getName();
2342         RepositoryBase.Builder repositoryBase = RepositoryBase.newBuilder( true );
2343         repositoryBase.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2344         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2345         {
2346             String name = parser.getAttributeName( i );
2347             String value = parser.getAttributeValue( i );
2348             if ( name.indexOf( ':' ) >= 0 )
2349             {
2350                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2351             }
2352             else
2353             {
2354                 checkUnknownAttribute( parser, name, tagName, strict );
2355             }
2356         }
2357         Set<String> parsed = new HashSet<>();
2358         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2359         {
2360             String childName = unalias( parser.getName() );
2361             if ( !parsed.add( childName ) )
2362             {
2363                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2364             }
2365             int line = parser.getLineNumber();
2366             int column = parser.getColumnNumber();
2367             Map<Object, InputLocation> locations = null;
2368             switch ( childName )
2369             {
2370                 case "id":
2371                 {
2372                     repositoryBase.id( interpolatedTrimmed( parser.nextText(), "id" ) );
2373                     break;
2374                 }
2375                 case "name":
2376                 {
2377                     repositoryBase.name( interpolatedTrimmed( parser.nextText(), "name" ) );
2378                     break;
2379                 }
2380                 case "url":
2381                 {
2382                     repositoryBase.url( interpolatedTrimmed( parser.nextText(), "url" ) );
2383                     break;
2384                 }
2385                 case "layout":
2386                 {
2387                     repositoryBase.layout( interpolatedTrimmed( parser.nextText(), "layout" ) );
2388                     break;
2389                 }
2390                 default:
2391                 {
2392                     checkUnknownElement( parser, strict );
2393                     break;
2394                 }
2395             }
2396             repositoryBase.location( childName, new InputLocation( line, column, source, locations ) );
2397         }
2398         return repositoryBase.build();
2399     }
2400 
2401     private Repository parseRepository( XmlPullParser parser, boolean strict, InputSource source )
2402         throws IOException, XmlPullParserException
2403     {
2404         String tagName = parser.getName();
2405         Repository.Builder repository = Repository.newBuilder( true );
2406         repository.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2407         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2408         {
2409             String name = parser.getAttributeName( i );
2410             String value = parser.getAttributeValue( i );
2411             if ( name.indexOf( ':' ) >= 0 )
2412             {
2413                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2414             }
2415             else
2416             {
2417                 checkUnknownAttribute( parser, name, tagName, strict );
2418             }
2419         }
2420         Set<String> parsed = new HashSet<>();
2421         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2422         {
2423             String childName = unalias( parser.getName() );
2424             if ( !parsed.add( childName ) )
2425             {
2426                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2427             }
2428             int line = parser.getLineNumber();
2429             int column = parser.getColumnNumber();
2430             Map<Object, InputLocation> locations = null;
2431             switch ( childName )
2432             {
2433                 case "releases":
2434                 {
2435                     repository.releases( parseRepositoryPolicy( parser, strict, source ) );
2436                     break;
2437                 }
2438                 case "snapshots":
2439                 {
2440                     repository.snapshots( parseRepositoryPolicy( parser, strict, source ) );
2441                     break;
2442                 }
2443                 case "id":
2444                 {
2445                     repository.id( interpolatedTrimmed( parser.nextText(), "id" ) );
2446                     break;
2447                 }
2448                 case "name":
2449                 {
2450                     repository.name( interpolatedTrimmed( parser.nextText(), "name" ) );
2451                     break;
2452                 }
2453                 case "url":
2454                 {
2455                     repository.url( interpolatedTrimmed( parser.nextText(), "url" ) );
2456                     break;
2457                 }
2458                 case "layout":
2459                 {
2460                     repository.layout( interpolatedTrimmed( parser.nextText(), "layout" ) );
2461                     break;
2462                 }
2463                 default:
2464                 {
2465                     checkUnknownElement( parser, strict );
2466                     break;
2467                 }
2468             }
2469             repository.location( childName, new InputLocation( line, column, source, locations ) );
2470         }
2471         return repository.build();
2472     }
2473 
2474     private DeploymentRepository parseDeploymentRepository( XmlPullParser parser, boolean strict, InputSource source )
2475         throws IOException, XmlPullParserException
2476     {
2477         String tagName = parser.getName();
2478         DeploymentRepository.Builder deploymentRepository = DeploymentRepository.newBuilder( true );
2479         deploymentRepository.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2480         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2481         {
2482             String name = parser.getAttributeName( i );
2483             String value = parser.getAttributeValue( i );
2484             if ( name.indexOf( ':' ) >= 0 )
2485             {
2486                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2487             }
2488             else
2489             {
2490                 checkUnknownAttribute( parser, name, tagName, strict );
2491             }
2492         }
2493         Set<String> parsed = new HashSet<>();
2494         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2495         {
2496             String childName = unalias( parser.getName() );
2497             if ( !parsed.add( childName ) )
2498             {
2499                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2500             }
2501             int line = parser.getLineNumber();
2502             int column = parser.getColumnNumber();
2503             Map<Object, InputLocation> locations = null;
2504             switch ( childName )
2505             {
2506                 case "uniqueVersion":
2507                 {
2508                     deploymentRepository.uniqueVersion( getBooleanValue( interpolatedTrimmed( parser.nextText(), "uniqueVersion" ), "uniqueVersion", parser, true ) );
2509                     break;
2510                 }
2511                 case "releases":
2512                 {
2513                     deploymentRepository.releases( parseRepositoryPolicy( parser, strict, source ) );
2514                     break;
2515                 }
2516                 case "snapshots":
2517                 {
2518                     deploymentRepository.snapshots( parseRepositoryPolicy( parser, strict, source ) );
2519                     break;
2520                 }
2521                 case "id":
2522                 {
2523                     deploymentRepository.id( interpolatedTrimmed( parser.nextText(), "id" ) );
2524                     break;
2525                 }
2526                 case "name":
2527                 {
2528                     deploymentRepository.name( interpolatedTrimmed( parser.nextText(), "name" ) );
2529                     break;
2530                 }
2531                 case "url":
2532                 {
2533                     deploymentRepository.url( interpolatedTrimmed( parser.nextText(), "url" ) );
2534                     break;
2535                 }
2536                 case "layout":
2537                 {
2538                     deploymentRepository.layout( interpolatedTrimmed( parser.nextText(), "layout" ) );
2539                     break;
2540                 }
2541                 default:
2542                 {
2543                     checkUnknownElement( parser, strict );
2544                     break;
2545                 }
2546             }
2547             deploymentRepository.location( childName, new InputLocation( line, column, source, locations ) );
2548         }
2549         return deploymentRepository.build();
2550     }
2551 
2552     private RepositoryPolicy parseRepositoryPolicy( XmlPullParser parser, boolean strict, InputSource source )
2553         throws IOException, XmlPullParserException
2554     {
2555         String tagName = parser.getName();
2556         RepositoryPolicy.Builder repositoryPolicy = RepositoryPolicy.newBuilder( true );
2557         repositoryPolicy.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2558         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2559         {
2560             String name = parser.getAttributeName( i );
2561             String value = parser.getAttributeValue( i );
2562             if ( name.indexOf( ':' ) >= 0 )
2563             {
2564                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2565             }
2566             else
2567             {
2568                 checkUnknownAttribute( parser, name, tagName, strict );
2569             }
2570         }
2571         Set<String> parsed = new HashSet<>();
2572         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2573         {
2574             String childName = unalias( parser.getName() );
2575             if ( !parsed.add( childName ) )
2576             {
2577                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2578             }
2579             int line = parser.getLineNumber();
2580             int column = parser.getColumnNumber();
2581             Map<Object, InputLocation> locations = null;
2582             switch ( childName )
2583             {
2584                 case "enabled":
2585                 {
2586                     repositoryPolicy.enabled( interpolatedTrimmed( parser.nextText(), "enabled" ) );
2587                     break;
2588                 }
2589                 case "updatePolicy":
2590                 {
2591                     repositoryPolicy.updatePolicy( interpolatedTrimmed( parser.nextText(), "updatePolicy" ) );
2592                     break;
2593                 }
2594                 case "checksumPolicy":
2595                 {
2596                     repositoryPolicy.checksumPolicy( interpolatedTrimmed( parser.nextText(), "checksumPolicy" ) );
2597                     break;
2598                 }
2599                 default:
2600                 {
2601                     checkUnknownElement( parser, strict );
2602                     break;
2603                 }
2604             }
2605             repositoryPolicy.location( childName, new InputLocation( line, column, source, locations ) );
2606         }
2607         return repositoryPolicy.build();
2608     }
2609 
2610     private Site parseSite( XmlPullParser parser, boolean strict, InputSource source )
2611         throws IOException, XmlPullParserException
2612     {
2613         String tagName = parser.getName();
2614         Site.Builder site = Site.newBuilder( true );
2615         site.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2616         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2617         {
2618             String name = parser.getAttributeName( i );
2619             String value = parser.getAttributeValue( i );
2620             if ( name.indexOf( ':' ) >= 0 )
2621             {
2622                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2623             }
2624             else if ( "child.site.url.inherit.append.path".equals( name ) )
2625             {
2626                 site.location( name, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2627                 site.childSiteUrlInheritAppendPath( interpolatedTrimmed( value, "child.site.url.inherit.append.path" ) );
2628             }
2629             else
2630             {
2631                 checkUnknownAttribute( parser, name, tagName, strict );
2632             }
2633         }
2634         Set<String> parsed = new HashSet<>();
2635         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2636         {
2637             String childName = unalias( parser.getName() );
2638             if ( !parsed.add( childName ) )
2639             {
2640                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2641             }
2642             int line = parser.getLineNumber();
2643             int column = parser.getColumnNumber();
2644             Map<Object, InputLocation> locations = null;
2645             switch ( childName )
2646             {
2647                 case "id":
2648                 {
2649                     site.id( interpolatedTrimmed( parser.nextText(), "id" ) );
2650                     break;
2651                 }
2652                 case "name":
2653                 {
2654                     site.name( interpolatedTrimmed( parser.nextText(), "name" ) );
2655                     break;
2656                 }
2657                 case "url":
2658                 {
2659                     site.url( interpolatedTrimmed( parser.nextText(), "url" ) );
2660                     break;
2661                 }
2662                 default:
2663                 {
2664                     checkUnknownElement( parser, strict );
2665                     break;
2666                 }
2667             }
2668             site.location( childName, new InputLocation( line, column, source, locations ) );
2669         }
2670         return site.build();
2671     }
2672 
2673     private ConfigurationContainer parseConfigurationContainer( XmlPullParser parser, boolean strict, InputSource source )
2674         throws IOException, XmlPullParserException
2675     {
2676         String tagName = parser.getName();
2677         ConfigurationContainer.Builder configurationContainer = ConfigurationContainer.newBuilder( true );
2678         configurationContainer.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2679         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2680         {
2681             String name = parser.getAttributeName( i );
2682             String value = parser.getAttributeValue( i );
2683             if ( name.indexOf( ':' ) >= 0 )
2684             {
2685                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2686             }
2687             else
2688             {
2689                 checkUnknownAttribute( parser, name, tagName, strict );
2690             }
2691         }
2692         Set<String> parsed = new HashSet<>();
2693         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2694         {
2695             String childName = unalias( parser.getName() );
2696             if ( !parsed.add( childName ) )
2697             {
2698                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2699             }
2700             int line = parser.getLineNumber();
2701             int column = parser.getColumnNumber();
2702             Map<Object, InputLocation> locations = null;
2703             switch ( childName )
2704             {
2705                 case "inherited":
2706                 {
2707                     configurationContainer.inherited( interpolatedTrimmed( parser.nextText(), "inherited" ) );
2708                     break;
2709                 }
2710                 case "configuration":
2711                 {
2712                     configurationContainer.configuration( XmlNodeBuilder.build( parser, true ) );
2713                     break;
2714                 }
2715                 default:
2716                 {
2717                     checkUnknownElement( parser, strict );
2718                     break;
2719                 }
2720             }
2721             configurationContainer.location( childName, new InputLocation( line, column, source, locations ) );
2722         }
2723         return configurationContainer.build();
2724     }
2725 
2726     private Plugin parsePlugin( XmlPullParser parser, boolean strict, InputSource source )
2727         throws IOException, XmlPullParserException
2728     {
2729         String tagName = parser.getName();
2730         Plugin.Builder plugin = Plugin.newBuilder( true );
2731         plugin.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2732         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2733         {
2734             String name = parser.getAttributeName( i );
2735             String value = parser.getAttributeValue( i );
2736             if ( name.indexOf( ':' ) >= 0 )
2737             {
2738                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2739             }
2740             else
2741             {
2742                 checkUnknownAttribute( parser, name, tagName, strict );
2743             }
2744         }
2745         Set<String> parsed = new HashSet<>();
2746         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2747         {
2748             String childName = unalias( parser.getName() );
2749             if ( !parsed.add( childName ) )
2750             {
2751                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2752             }
2753             int line = parser.getLineNumber();
2754             int column = parser.getColumnNumber();
2755             Map<Object, InputLocation> locations = null;
2756             switch ( childName )
2757             {
2758                 case "groupId":
2759                 {
2760                     plugin.groupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
2761                     break;
2762                 }
2763                 case "artifactId":
2764                 {
2765                     plugin.artifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
2766                     break;
2767                 }
2768                 case "version":
2769                 {
2770                     plugin.version( interpolatedTrimmed( parser.nextText(), "version" ) );
2771                     break;
2772                 }
2773                 case "extensions":
2774                 {
2775                     plugin.extensions( interpolatedTrimmed( parser.nextText(), "extensions" ) );
2776                     break;
2777                 }
2778                 case "executions":
2779                 {
2780                     List<PluginExecution> executions = new ArrayList<>();
2781                     while ( parser.nextTag() == XmlPullParser.START_TAG )
2782                     {
2783                         if ( "execution".equals( parser.getName() ) )
2784                         {
2785                             executions.add( parsePluginExecution( parser, strict, source ) );
2786                         }
2787                         else
2788                         {
2789                             checkUnknownElement( parser, strict );
2790                         }
2791                     }
2792                     plugin.executions( executions );
2793                     break;
2794                 }
2795                 case "dependencies":
2796                 {
2797                     List<Dependency> dependencies = new ArrayList<>();
2798                     while ( parser.nextTag() == XmlPullParser.START_TAG )
2799                     {
2800                         if ( "dependency".equals( parser.getName() ) )
2801                         {
2802                             dependencies.add( parseDependency( parser, strict, source ) );
2803                         }
2804                         else
2805                         {
2806                             checkUnknownElement( parser, strict );
2807                         }
2808                     }
2809                     plugin.dependencies( dependencies );
2810                     break;
2811                 }
2812                 case "inherited":
2813                 {
2814                     plugin.inherited( interpolatedTrimmed( parser.nextText(), "inherited" ) );
2815                     break;
2816                 }
2817                 case "configuration":
2818                 {
2819                     plugin.configuration( XmlNodeBuilder.build( parser, true ) );
2820                     break;
2821                 }
2822                 default:
2823                 {
2824                     checkUnknownElement( parser, strict );
2825                     break;
2826                 }
2827             }
2828             plugin.location( childName, new InputLocation( line, column, source, locations ) );
2829         }
2830         return plugin.build();
2831     }
2832 
2833     private PluginExecution parsePluginExecution( XmlPullParser parser, boolean strict, InputSource source )
2834         throws IOException, XmlPullParserException
2835     {
2836         String tagName = parser.getName();
2837         PluginExecution.Builder pluginExecution = PluginExecution.newBuilder( true );
2838         pluginExecution.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2839         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2840         {
2841             String name = parser.getAttributeName( i );
2842             String value = parser.getAttributeValue( i );
2843             if ( name.indexOf( ':' ) >= 0 )
2844             {
2845                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2846             }
2847             else
2848             {
2849                 checkUnknownAttribute( parser, name, tagName, strict );
2850             }
2851         }
2852         Set<String> parsed = new HashSet<>();
2853         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2854         {
2855             String childName = unalias( parser.getName() );
2856             if ( !parsed.add( childName ) )
2857             {
2858                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2859             }
2860             int line = parser.getLineNumber();
2861             int column = parser.getColumnNumber();
2862             Map<Object, InputLocation> locations = null;
2863             switch ( childName )
2864             {
2865                 case "id":
2866                 {
2867                     pluginExecution.id( interpolatedTrimmed( parser.nextText(), "id" ) );
2868                     break;
2869                 }
2870                 case "phase":
2871                 {
2872                     pluginExecution.phase( interpolatedTrimmed( parser.nextText(), "phase" ) );
2873                     break;
2874                 }
2875                 case "goals":
2876                 {
2877                     List<String> goals = new ArrayList<>();
2878                     locations = new HashMap<>();
2879                     while ( parser.nextTag() == XmlPullParser.START_TAG )
2880                     {
2881                         if ( "goal".equals( parser.getName() ) )
2882                         {
2883                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2884                             goals.add( interpolatedTrimmed( parser.nextText(), "goals" ) );
2885                         }
2886                         else
2887                         {
2888                             checkUnknownElement( parser, strict );
2889                         }
2890                     }
2891                     pluginExecution.goals( goals );
2892                     break;
2893                 }
2894                 case "inherited":
2895                 {
2896                     pluginExecution.inherited( interpolatedTrimmed( parser.nextText(), "inherited" ) );
2897                     break;
2898                 }
2899                 case "configuration":
2900                 {
2901                     pluginExecution.configuration( XmlNodeBuilder.build( parser, true ) );
2902                     break;
2903                 }
2904                 default:
2905                 {
2906                     checkUnknownElement( parser, strict );
2907                     break;
2908                 }
2909             }
2910             pluginExecution.location( childName, new InputLocation( line, column, source, locations ) );
2911         }
2912         return pluginExecution.build();
2913     }
2914 
2915     private DependencyManagement parseDependencyManagement( XmlPullParser parser, boolean strict, InputSource source )
2916         throws IOException, XmlPullParserException
2917     {
2918         String tagName = parser.getName();
2919         DependencyManagement.Builder dependencyManagement = DependencyManagement.newBuilder( true );
2920         dependencyManagement.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2921         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2922         {
2923             String name = parser.getAttributeName( i );
2924             String value = parser.getAttributeValue( i );
2925             if ( name.indexOf( ':' ) >= 0 )
2926             {
2927                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2928             }
2929             else
2930             {
2931                 checkUnknownAttribute( parser, name, tagName, strict );
2932             }
2933         }
2934         Set<String> parsed = new HashSet<>();
2935         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2936         {
2937             String childName = unalias( parser.getName() );
2938             if ( !parsed.add( childName ) )
2939             {
2940                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
2941             }
2942             int line = parser.getLineNumber();
2943             int column = parser.getColumnNumber();
2944             Map<Object, InputLocation> locations = null;
2945             switch ( childName )
2946             {
2947                 case "dependencies":
2948                 {
2949                     List<Dependency> dependencies = new ArrayList<>();
2950                     while ( parser.nextTag() == XmlPullParser.START_TAG )
2951                     {
2952                         if ( "dependency".equals( parser.getName() ) )
2953                         {
2954                             dependencies.add( parseDependency( parser, strict, source ) );
2955                         }
2956                         else
2957                         {
2958                             checkUnknownElement( parser, strict );
2959                         }
2960                     }
2961                     dependencyManagement.dependencies( dependencies );
2962                     break;
2963                 }
2964                 default:
2965                 {
2966                     checkUnknownElement( parser, strict );
2967                     break;
2968                 }
2969             }
2970             dependencyManagement.location( childName, new InputLocation( line, column, source, locations ) );
2971         }
2972         return dependencyManagement.build();
2973     }
2974 
2975     private PluginManagement parsePluginManagement( XmlPullParser parser, boolean strict, InputSource source )
2976         throws IOException, XmlPullParserException
2977     {
2978         String tagName = parser.getName();
2979         PluginManagement.Builder pluginManagement = PluginManagement.newBuilder( true );
2980         pluginManagement.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
2981         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
2982         {
2983             String name = parser.getAttributeName( i );
2984             String value = parser.getAttributeValue( i );
2985             if ( name.indexOf( ':' ) >= 0 )
2986             {
2987                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
2988             }
2989             else
2990             {
2991                 checkUnknownAttribute( parser, name, tagName, strict );
2992             }
2993         }
2994         Set<String> parsed = new HashSet<>();
2995         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
2996         {
2997             String childName = unalias( parser.getName() );
2998             if ( !parsed.add( childName ) )
2999             {
3000                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3001             }
3002             int line = parser.getLineNumber();
3003             int column = parser.getColumnNumber();
3004             Map<Object, InputLocation> locations = null;
3005             switch ( childName )
3006             {
3007                 case "plugins":
3008                 {
3009                     List<Plugin> plugins = new ArrayList<>();
3010                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3011                     {
3012                         if ( "plugin".equals( parser.getName() ) )
3013                         {
3014                             plugins.add( parsePlugin( parser, strict, source ) );
3015                         }
3016                         else
3017                         {
3018                             checkUnknownElement( parser, strict );
3019                         }
3020                     }
3021                     pluginManagement.plugins( plugins );
3022                     break;
3023                 }
3024                 default:
3025                 {
3026                     checkUnknownElement( parser, strict );
3027                     break;
3028                 }
3029             }
3030             pluginManagement.location( childName, new InputLocation( line, column, source, locations ) );
3031         }
3032         return pluginManagement.build();
3033     }
3034 
3035     private Reporting parseReporting( XmlPullParser parser, boolean strict, InputSource source )
3036         throws IOException, XmlPullParserException
3037     {
3038         String tagName = parser.getName();
3039         Reporting.Builder reporting = Reporting.newBuilder( true );
3040         reporting.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3041         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3042         {
3043             String name = parser.getAttributeName( i );
3044             String value = parser.getAttributeValue( i );
3045             if ( name.indexOf( ':' ) >= 0 )
3046             {
3047                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3048             }
3049             else
3050             {
3051                 checkUnknownAttribute( parser, name, tagName, strict );
3052             }
3053         }
3054         Set<String> parsed = new HashSet<>();
3055         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3056         {
3057             String childName = unalias( parser.getName() );
3058             if ( !parsed.add( childName ) )
3059             {
3060                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3061             }
3062             int line = parser.getLineNumber();
3063             int column = parser.getColumnNumber();
3064             Map<Object, InputLocation> locations = null;
3065             switch ( childName )
3066             {
3067                 case "excludeDefaults":
3068                 {
3069                     reporting.excludeDefaults( interpolatedTrimmed( parser.nextText(), "excludeDefaults" ) );
3070                     break;
3071                 }
3072                 case "outputDirectory":
3073                 {
3074                     reporting.outputDirectory( interpolatedTrimmed( parser.nextText(), "outputDirectory" ) );
3075                     break;
3076                 }
3077                 case "plugins":
3078                 {
3079                     List<ReportPlugin> plugins = new ArrayList<>();
3080                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3081                     {
3082                         if ( "plugin".equals( parser.getName() ) )
3083                         {
3084                             plugins.add( parseReportPlugin( parser, strict, source ) );
3085                         }
3086                         else
3087                         {
3088                             checkUnknownElement( parser, strict );
3089                         }
3090                     }
3091                     reporting.plugins( plugins );
3092                     break;
3093                 }
3094                 default:
3095                 {
3096                     checkUnknownElement( parser, strict );
3097                     break;
3098                 }
3099             }
3100             reporting.location( childName, new InputLocation( line, column, source, locations ) );
3101         }
3102         return reporting.build();
3103     }
3104 
3105     private Profile parseProfile( XmlPullParser parser, boolean strict, InputSource source )
3106         throws IOException, XmlPullParserException
3107     {
3108         String tagName = parser.getName();
3109         Profile.Builder profile = Profile.newBuilder( true );
3110         profile.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3111         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3112         {
3113             String name = parser.getAttributeName( i );
3114             String value = parser.getAttributeValue( i );
3115             if ( name.indexOf( ':' ) >= 0 )
3116             {
3117                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3118             }
3119             else
3120             {
3121                 checkUnknownAttribute( parser, name, tagName, strict );
3122             }
3123         }
3124         Set<String> parsed = new HashSet<>();
3125         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3126         {
3127             String childName = unalias( parser.getName() );
3128             if ( !parsed.add( childName ) )
3129             {
3130                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3131             }
3132             int line = parser.getLineNumber();
3133             int column = parser.getColumnNumber();
3134             Map<Object, InputLocation> locations = null;
3135             switch ( childName )
3136             {
3137                 case "id":
3138                 {
3139                     profile.id( interpolatedTrimmed( parser.nextText(), "id" ) );
3140                     break;
3141                 }
3142                 case "activation":
3143                 {
3144                     profile.activation( parseActivation( parser, strict, source ) );
3145                     break;
3146                 }
3147                 case "build":
3148                 {
3149                     profile.build( parseBuildBase( parser, strict, source ) );
3150                     break;
3151                 }
3152                 case "modules":
3153                 {
3154                     List<String> modules = new ArrayList<>();
3155                     locations = new HashMap<>();
3156                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3157                     {
3158                         if ( "module".equals( parser.getName() ) )
3159                         {
3160                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3161                             modules.add( interpolatedTrimmed( parser.nextText(), "modules" ) );
3162                         }
3163                         else
3164                         {
3165                             checkUnknownElement( parser, strict );
3166                         }
3167                     }
3168                     profile.modules( modules );
3169                     break;
3170                 }
3171                 case "distributionManagement":
3172                 {
3173                     profile.distributionManagement( parseDistributionManagement( parser, strict, source ) );
3174                     break;
3175                 }
3176                 case "properties":
3177                 {
3178                     Map<String, String> properties = new LinkedHashMap<>();
3179                     locations = new HashMap<>();
3180                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3181                     {
3182                         String key = parser.getName();
3183                         String value = parser.nextText().trim();
3184                         locations.put( key, new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3185                         properties.put( key, value );
3186                     }
3187                     profile.properties( properties );
3188                     break;
3189                 }
3190                 case "dependencyManagement":
3191                 {
3192                     profile.dependencyManagement( parseDependencyManagement( parser, strict, source ) );
3193                     break;
3194                 }
3195                 case "dependencies":
3196                 {
3197                     List<Dependency> dependencies = new ArrayList<>();
3198                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3199                     {
3200                         if ( "dependency".equals( parser.getName() ) )
3201                         {
3202                             dependencies.add( parseDependency( parser, strict, source ) );
3203                         }
3204                         else
3205                         {
3206                             checkUnknownElement( parser, strict );
3207                         }
3208                     }
3209                     profile.dependencies( dependencies );
3210                     break;
3211                 }
3212                 case "repositories":
3213                 {
3214                     List<Repository> repositories = new ArrayList<>();
3215                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3216                     {
3217                         if ( "repository".equals( parser.getName() ) )
3218                         {
3219                             repositories.add( parseRepository( parser, strict, source ) );
3220                         }
3221                         else
3222                         {
3223                             checkUnknownElement( parser, strict );
3224                         }
3225                     }
3226                     profile.repositories( repositories );
3227                     break;
3228                 }
3229                 case "pluginRepositories":
3230                 {
3231                     List<Repository> pluginRepositories = new ArrayList<>();
3232                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3233                     {
3234                         if ( "pluginRepository".equals( parser.getName() ) )
3235                         {
3236                             pluginRepositories.add( parseRepository( parser, strict, source ) );
3237                         }
3238                         else
3239                         {
3240                             checkUnknownElement( parser, strict );
3241                         }
3242                     }
3243                     profile.pluginRepositories( pluginRepositories );
3244                     break;
3245                 }
3246                 case "reporting":
3247                 {
3248                     profile.reporting( parseReporting( parser, strict, source ) );
3249                     break;
3250                 }
3251                 default:
3252                 {
3253                     checkUnknownElement( parser, strict );
3254                     break;
3255                 }
3256             }
3257             profile.location( childName, new InputLocation( line, column, source, locations ) );
3258         }
3259         return profile.build();
3260     }
3261 
3262     private Activation parseActivation( XmlPullParser parser, boolean strict, InputSource source )
3263         throws IOException, XmlPullParserException
3264     {
3265         String tagName = parser.getName();
3266         Activation.Builder activation = Activation.newBuilder( true );
3267         activation.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3268         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3269         {
3270             String name = parser.getAttributeName( i );
3271             String value = parser.getAttributeValue( i );
3272             if ( name.indexOf( ':' ) >= 0 )
3273             {
3274                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3275             }
3276             else
3277             {
3278                 checkUnknownAttribute( parser, name, tagName, strict );
3279             }
3280         }
3281         Set<String> parsed = new HashSet<>();
3282         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3283         {
3284             String childName = unalias( parser.getName() );
3285             if ( !parsed.add( childName ) )
3286             {
3287                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3288             }
3289             int line = parser.getLineNumber();
3290             int column = parser.getColumnNumber();
3291             Map<Object, InputLocation> locations = null;
3292             switch ( childName )
3293             {
3294                 case "activeByDefault":
3295                 {
3296                     activation.activeByDefault( getBooleanValue( interpolatedTrimmed( parser.nextText(), "activeByDefault" ), "activeByDefault", parser, false ) );
3297                     break;
3298                 }
3299                 case "jdk":
3300                 {
3301                     activation.jdk( interpolatedTrimmed( parser.nextText(), "jdk" ) );
3302                     break;
3303                 }
3304                 case "os":
3305                 {
3306                     activation.os( parseActivationOS( parser, strict, source ) );
3307                     break;
3308                 }
3309                 case "property":
3310                 {
3311                     activation.property( parseActivationProperty( parser, strict, source ) );
3312                     break;
3313                 }
3314                 case "file":
3315                 {
3316                     activation.file( parseActivationFile( parser, strict, source ) );
3317                     break;
3318                 }
3319                 default:
3320                 {
3321                     checkUnknownElement( parser, strict );
3322                     break;
3323                 }
3324             }
3325             activation.location( childName, new InputLocation( line, column, source, locations ) );
3326         }
3327         return activation.build();
3328     }
3329 
3330     private ActivationProperty parseActivationProperty( XmlPullParser parser, boolean strict, InputSource source )
3331         throws IOException, XmlPullParserException
3332     {
3333         String tagName = parser.getName();
3334         ActivationProperty.Builder activationProperty = ActivationProperty.newBuilder( true );
3335         activationProperty.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3336         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3337         {
3338             String name = parser.getAttributeName( i );
3339             String value = parser.getAttributeValue( i );
3340             if ( name.indexOf( ':' ) >= 0 )
3341             {
3342                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3343             }
3344             else
3345             {
3346                 checkUnknownAttribute( parser, name, tagName, strict );
3347             }
3348         }
3349         Set<String> parsed = new HashSet<>();
3350         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3351         {
3352             String childName = unalias( parser.getName() );
3353             if ( !parsed.add( childName ) )
3354             {
3355                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3356             }
3357             int line = parser.getLineNumber();
3358             int column = parser.getColumnNumber();
3359             Map<Object, InputLocation> locations = null;
3360             switch ( childName )
3361             {
3362                 case "name":
3363                 {
3364                     activationProperty.name( interpolatedTrimmed( parser.nextText(), "name" ) );
3365                     break;
3366                 }
3367                 case "value":
3368                 {
3369                     activationProperty.value( interpolatedTrimmed( parser.nextText(), "value" ) );
3370                     break;
3371                 }
3372                 default:
3373                 {
3374                     checkUnknownElement( parser, strict );
3375                     break;
3376                 }
3377             }
3378             activationProperty.location( childName, new InputLocation( line, column, source, locations ) );
3379         }
3380         return activationProperty.build();
3381     }
3382 
3383     private ActivationOS parseActivationOS( XmlPullParser parser, boolean strict, InputSource source )
3384         throws IOException, XmlPullParserException
3385     {
3386         String tagName = parser.getName();
3387         ActivationOS.Builder activationOS = ActivationOS.newBuilder( true );
3388         activationOS.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3389         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3390         {
3391             String name = parser.getAttributeName( i );
3392             String value = parser.getAttributeValue( i );
3393             if ( name.indexOf( ':' ) >= 0 )
3394             {
3395                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3396             }
3397             else
3398             {
3399                 checkUnknownAttribute( parser, name, tagName, strict );
3400             }
3401         }
3402         Set<String> parsed = new HashSet<>();
3403         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3404         {
3405             String childName = unalias( parser.getName() );
3406             if ( !parsed.add( childName ) )
3407             {
3408                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3409             }
3410             int line = parser.getLineNumber();
3411             int column = parser.getColumnNumber();
3412             Map<Object, InputLocation> locations = null;
3413             switch ( childName )
3414             {
3415                 case "name":
3416                 {
3417                     activationOS.name( interpolatedTrimmed( parser.nextText(), "name" ) );
3418                     break;
3419                 }
3420                 case "family":
3421                 {
3422                     activationOS.family( interpolatedTrimmed( parser.nextText(), "family" ) );
3423                     break;
3424                 }
3425                 case "arch":
3426                 {
3427                     activationOS.arch( interpolatedTrimmed( parser.nextText(), "arch" ) );
3428                     break;
3429                 }
3430                 case "version":
3431                 {
3432                     activationOS.version( interpolatedTrimmed( parser.nextText(), "version" ) );
3433                     break;
3434                 }
3435                 default:
3436                 {
3437                     checkUnknownElement( parser, strict );
3438                     break;
3439                 }
3440             }
3441             activationOS.location( childName, new InputLocation( line, column, source, locations ) );
3442         }
3443         return activationOS.build();
3444     }
3445 
3446     private ActivationFile parseActivationFile( XmlPullParser parser, boolean strict, InputSource source )
3447         throws IOException, XmlPullParserException
3448     {
3449         String tagName = parser.getName();
3450         ActivationFile.Builder activationFile = ActivationFile.newBuilder( true );
3451         activationFile.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3452         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3453         {
3454             String name = parser.getAttributeName( i );
3455             String value = parser.getAttributeValue( i );
3456             if ( name.indexOf( ':' ) >= 0 )
3457             {
3458                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3459             }
3460             else
3461             {
3462                 checkUnknownAttribute( parser, name, tagName, strict );
3463             }
3464         }
3465         Set<String> parsed = new HashSet<>();
3466         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3467         {
3468             String childName = unalias( parser.getName() );
3469             if ( !parsed.add( childName ) )
3470             {
3471                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3472             }
3473             int line = parser.getLineNumber();
3474             int column = parser.getColumnNumber();
3475             Map<Object, InputLocation> locations = null;
3476             switch ( childName )
3477             {
3478                 case "missing":
3479                 {
3480                     activationFile.missing( interpolatedTrimmed( parser.nextText(), "missing" ) );
3481                     break;
3482                 }
3483                 case "exists":
3484                 {
3485                     activationFile.exists( interpolatedTrimmed( parser.nextText(), "exists" ) );
3486                     break;
3487                 }
3488                 default:
3489                 {
3490                     checkUnknownElement( parser, strict );
3491                     break;
3492                 }
3493             }
3494             activationFile.location( childName, new InputLocation( line, column, source, locations ) );
3495         }
3496         return activationFile.build();
3497     }
3498 
3499     private ReportPlugin parseReportPlugin( XmlPullParser parser, boolean strict, InputSource source )
3500         throws IOException, XmlPullParserException
3501     {
3502         String tagName = parser.getName();
3503         ReportPlugin.Builder reportPlugin = ReportPlugin.newBuilder( true );
3504         reportPlugin.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3505         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3506         {
3507             String name = parser.getAttributeName( i );
3508             String value = parser.getAttributeValue( i );
3509             if ( name.indexOf( ':' ) >= 0 )
3510             {
3511                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3512             }
3513             else
3514             {
3515                 checkUnknownAttribute( parser, name, tagName, strict );
3516             }
3517         }
3518         Set<String> parsed = new HashSet<>();
3519         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3520         {
3521             String childName = unalias( parser.getName() );
3522             if ( !parsed.add( childName ) )
3523             {
3524                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3525             }
3526             int line = parser.getLineNumber();
3527             int column = parser.getColumnNumber();
3528             Map<Object, InputLocation> locations = null;
3529             switch ( childName )
3530             {
3531                 case "groupId":
3532                 {
3533                     reportPlugin.groupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
3534                     break;
3535                 }
3536                 case "artifactId":
3537                 {
3538                     reportPlugin.artifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
3539                     break;
3540                 }
3541                 case "version":
3542                 {
3543                     reportPlugin.version( interpolatedTrimmed( parser.nextText(), "version" ) );
3544                     break;
3545                 }
3546                 case "reportSets":
3547                 {
3548                     List<ReportSet> reportSets = new ArrayList<>();
3549                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3550                     {
3551                         if ( "reportSet".equals( parser.getName() ) )
3552                         {
3553                             reportSets.add( parseReportSet( parser, strict, source ) );
3554                         }
3555                         else
3556                         {
3557                             checkUnknownElement( parser, strict );
3558                         }
3559                     }
3560                     reportPlugin.reportSets( reportSets );
3561                     break;
3562                 }
3563                 case "inherited":
3564                 {
3565                     reportPlugin.inherited( interpolatedTrimmed( parser.nextText(), "inherited" ) );
3566                     break;
3567                 }
3568                 case "configuration":
3569                 {
3570                     reportPlugin.configuration( XmlNodeBuilder.build( parser, true ) );
3571                     break;
3572                 }
3573                 default:
3574                 {
3575                     checkUnknownElement( parser, strict );
3576                     break;
3577                 }
3578             }
3579             reportPlugin.location( childName, new InputLocation( line, column, source, locations ) );
3580         }
3581         return reportPlugin.build();
3582     }
3583 
3584     private ReportSet parseReportSet( XmlPullParser parser, boolean strict, InputSource source )
3585         throws IOException, XmlPullParserException
3586     {
3587         String tagName = parser.getName();
3588         ReportSet.Builder reportSet = ReportSet.newBuilder( true );
3589         reportSet.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3590         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3591         {
3592             String name = parser.getAttributeName( i );
3593             String value = parser.getAttributeValue( i );
3594             if ( name.indexOf( ':' ) >= 0 )
3595             {
3596                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3597             }
3598             else
3599             {
3600                 checkUnknownAttribute( parser, name, tagName, strict );
3601             }
3602         }
3603         Set<String> parsed = new HashSet<>();
3604         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3605         {
3606             String childName = unalias( parser.getName() );
3607             if ( !parsed.add( childName ) )
3608             {
3609                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3610             }
3611             int line = parser.getLineNumber();
3612             int column = parser.getColumnNumber();
3613             Map<Object, InputLocation> locations = null;
3614             switch ( childName )
3615             {
3616                 case "id":
3617                 {
3618                     reportSet.id( interpolatedTrimmed( parser.nextText(), "id" ) );
3619                     break;
3620                 }
3621                 case "reports":
3622                 {
3623                     List<String> reports = new ArrayList<>();
3624                     locations = new HashMap<>();
3625                     while ( parser.nextTag() == XmlPullParser.START_TAG )
3626                     {
3627                         if ( "report".equals( parser.getName() ) )
3628                         {
3629                             locations.put( Integer.valueOf( locations.size() ), new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3630                             reports.add( interpolatedTrimmed( parser.nextText(), "reports" ) );
3631                         }
3632                         else
3633                         {
3634                             checkUnknownElement( parser, strict );
3635                         }
3636                     }
3637                     reportSet.reports( reports );
3638                     break;
3639                 }
3640                 case "inherited":
3641                 {
3642                     reportSet.inherited( interpolatedTrimmed( parser.nextText(), "inherited" ) );
3643                     break;
3644                 }
3645                 case "configuration":
3646                 {
3647                     reportSet.configuration( XmlNodeBuilder.build( parser, true ) );
3648                     break;
3649                 }
3650                 default:
3651                 {
3652                     checkUnknownElement( parser, strict );
3653                     break;
3654                 }
3655             }
3656             reportSet.location( childName, new InputLocation( line, column, source, locations ) );
3657         }
3658         return reportSet.build();
3659     }
3660 
3661     private Prerequisites parsePrerequisites( XmlPullParser parser, boolean strict, InputSource source )
3662         throws IOException, XmlPullParserException
3663     {
3664         String tagName = parser.getName();
3665         Prerequisites.Builder prerequisites = Prerequisites.newBuilder( true );
3666         prerequisites.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3667         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3668         {
3669             String name = parser.getAttributeName( i );
3670             String value = parser.getAttributeValue( i );
3671             if ( name.indexOf( ':' ) >= 0 )
3672             {
3673                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3674             }
3675             else
3676             {
3677                 checkUnknownAttribute( parser, name, tagName, strict );
3678             }
3679         }
3680         Set<String> parsed = new HashSet<>();
3681         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3682         {
3683             String childName = unalias( parser.getName() );
3684             if ( !parsed.add( childName ) )
3685             {
3686                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3687             }
3688             int line = parser.getLineNumber();
3689             int column = parser.getColumnNumber();
3690             Map<Object, InputLocation> locations = null;
3691             switch ( childName )
3692             {
3693                 case "maven":
3694                 {
3695                     prerequisites.maven( interpolatedTrimmed( parser.nextText(), "maven" ) );
3696                     break;
3697                 }
3698                 default:
3699                 {
3700                     checkUnknownElement( parser, strict );
3701                     break;
3702                 }
3703             }
3704             prerequisites.location( childName, new InputLocation( line, column, source, locations ) );
3705         }
3706         return prerequisites.build();
3707     }
3708 
3709     private Relocation parseRelocation( XmlPullParser parser, boolean strict, InputSource source )
3710         throws IOException, XmlPullParserException
3711     {
3712         String tagName = parser.getName();
3713         Relocation.Builder relocation = Relocation.newBuilder( true );
3714         relocation.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3715         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3716         {
3717             String name = parser.getAttributeName( i );
3718             String value = parser.getAttributeValue( i );
3719             if ( name.indexOf( ':' ) >= 0 )
3720             {
3721                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3722             }
3723             else
3724             {
3725                 checkUnknownAttribute( parser, name, tagName, strict );
3726             }
3727         }
3728         Set<String> parsed = new HashSet<>();
3729         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3730         {
3731             String childName = unalias( parser.getName() );
3732             if ( !parsed.add( childName ) )
3733             {
3734                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3735             }
3736             int line = parser.getLineNumber();
3737             int column = parser.getColumnNumber();
3738             Map<Object, InputLocation> locations = null;
3739             switch ( childName )
3740             {
3741                 case "groupId":
3742                 {
3743                     relocation.groupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
3744                     break;
3745                 }
3746                 case "artifactId":
3747                 {
3748                     relocation.artifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
3749                     break;
3750                 }
3751                 case "version":
3752                 {
3753                     relocation.version( interpolatedTrimmed( parser.nextText(), "version" ) );
3754                     break;
3755                 }
3756                 case "message":
3757                 {
3758                     relocation.message( interpolatedTrimmed( parser.nextText(), "message" ) );
3759                     break;
3760                 }
3761                 default:
3762                 {
3763                     checkUnknownElement( parser, strict );
3764                     break;
3765                 }
3766             }
3767             relocation.location( childName, new InputLocation( line, column, source, locations ) );
3768         }
3769         return relocation.build();
3770     }
3771 
3772     private Extension parseExtension( XmlPullParser parser, boolean strict, InputSource source )
3773         throws IOException, XmlPullParserException
3774     {
3775         String tagName = parser.getName();
3776         Extension.Builder extension = Extension.newBuilder( true );
3777         extension.location( "", new InputLocation( parser.getLineNumber(), parser.getColumnNumber(), source ) );
3778         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
3779         {
3780             String name = parser.getAttributeName( i );
3781             String value = parser.getAttributeValue( i );
3782             if ( name.indexOf( ':' ) >= 0 )
3783             {
3784                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
3785             }
3786             else
3787             {
3788                 checkUnknownAttribute( parser, name, tagName, strict );
3789             }
3790         }
3791         Set<String> parsed = new HashSet<>();
3792         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
3793         {
3794             String childName = unalias( parser.getName() );
3795             if ( !parsed.add( childName ) )
3796             {
3797                 throw new XmlPullParserException( "Duplicated tag: '" + childName + "'", parser, null );
3798             }
3799             int line = parser.getLineNumber();
3800             int column = parser.getColumnNumber();
3801             Map<Object, InputLocation> locations = null;
3802             switch ( childName )
3803             {
3804                 case "groupId":
3805                 {
3806                     extension.groupId( interpolatedTrimmed( parser.nextText(), "groupId" ) );
3807                     break;
3808                 }
3809                 case "artifactId":
3810                 {
3811                     extension.artifactId( interpolatedTrimmed( parser.nextText(), "artifactId" ) );
3812                     break;
3813                 }
3814                 case "version":
3815                 {
3816                     extension.version( interpolatedTrimmed( parser.nextText(), "version" ) );
3817                     break;
3818                 }
3819                 default:
3820                 {
3821                     checkUnknownElement( parser, strict );
3822                     break;
3823                 }
3824             }
3825             extension.location( childName, new InputLocation( line, column, source, locations ) );
3826         }
3827         return extension.build();
3828     }
3829 
3830 
3831     private String unalias( String tagName )
3832     {
3833         switch ( tagName )
3834         {
3835             case "organisation":
3836                 return "organization";
3837             case "organisationUrl":
3838                 return "organizationUrl";
3839             default:
3840                 return tagName;
3841         }
3842     }
3843 
3844     /**
3845      * Method checkUnknownAttribute.
3846      *
3847      * @param parser a parser object.
3848      * @param strict a strict object.
3849      * @param tagName a tagName object.
3850      * @param attribute a attribute object.
3851      * @throws XmlPullParserException XmlPullParserException if
3852      * any.
3853      * @throws IOException IOException if any.
3854      */
3855     private void checkUnknownAttribute( XmlPullParser parser, String attribute, String tagName, boolean strict )
3856         throws XmlPullParserException, IOException
3857     {
3858         // strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
3859         if ( strict )
3860         {
3861             throw new XmlPullParserException( "Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser, null );
3862         }
3863     } //-- void checkUnknownAttribute( XmlPullParser, String, String, boolean )
3864 
3865     /**
3866      * Method checkUnknownElement.
3867      *
3868      * @param parser a parser object.
3869      * @param strict a strict object.
3870      * @throws XmlPullParserException XmlPullParserException if
3871      * any.
3872      * @throws IOException IOException if any.
3873      */
3874     private void checkUnknownElement( XmlPullParser parser, boolean strict )
3875         throws XmlPullParserException, IOException
3876     {
3877         if ( strict )
3878         {
3879             throw new XmlPullParserException( "Unrecognised tag: '" + parser.getName() + "'", parser, null );
3880         }
3881 
3882         for ( int unrecognizedTagCount = 1; unrecognizedTagCount > 0; )
3883         {
3884             int eventType = parser.next();
3885             if ( eventType == XmlPullParser.START_TAG )
3886             {
3887                 unrecognizedTagCount++;
3888             }
3889             else if ( eventType == XmlPullParser.END_TAG )
3890             {
3891                 unrecognizedTagCount--;
3892             }
3893         }
3894     } //-- void checkUnknownElement( XmlPullParser, boolean )
3895 
3896     /**
3897      * Method getTrimmedValue.
3898      *
3899      * @param s a s object.
3900      * @return String
3901      */
3902     private String getTrimmedValue( String s )
3903     {
3904         if ( s != null )
3905         {
3906             s = s.trim();
3907         }
3908         return s;
3909     } //-- String getTrimmedValue( String )
3910 
3911     /**
3912      * Method interpolatedTrimmed.
3913      *
3914      * @param value a value object.
3915      * @param context a context object.
3916      * @return String
3917      */
3918     private String interpolatedTrimmed( String value, String context )
3919     {
3920         return getTrimmedValue( contentTransformer.transform( value, context ) );
3921     } //-- String interpolatedTrimmed( String, String )
3922 
3923     /**
3924      * Method nextTag.
3925      *
3926      * @param parser a parser object.
3927      * @throws IOException IOException if any.
3928      * @throws XmlPullParserException XmlPullParserException if
3929      * any.
3930      * @return int
3931      */
3932     private int nextTag( XmlPullParser parser )
3933         throws IOException, XmlPullParserException
3934     {
3935         int eventType = parser.next();
3936         if ( eventType == XmlPullParser.TEXT )
3937         {
3938             eventType = parser.next();
3939         }
3940         if ( eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_TAG )
3941         {
3942             throw new XmlPullParserException( "expected START_TAG or END_TAG not " + XmlPullParser.TYPES[eventType], parser, null );
3943         }
3944         return eventType;
3945     } //-- int nextTag( XmlPullParser )
3946 
3947     /**
3948      * Method getBooleanValue.
3949      *
3950      * @param s a s object.
3951      * @param defaultValue a defaultValue object.
3952      * @param parser a parser object.
3953      * @param attribute a attribute object.
3954      * @throws XmlPullParserException XmlPullParserException if
3955      * any.
3956      * @return boolean
3957      */
3958     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser, boolean defaultValue )
3959         throws XmlPullParserException
3960     {
3961         if ( s != null && s.length() != 0 )
3962         {
3963             return Boolean.valueOf( s ).booleanValue();
3964         }
3965         return defaultValue;
3966     } //-- boolean getBooleanValue( String, String, XmlPullParser, String )
3967 
3968     /**
3969      * Method getIntegerValue.
3970      *
3971      * @param s a s object.
3972      * @param strict a strict object.
3973      * @param parser a parser object.
3974      * @param attribute a attribute object.
3975      * @throws XmlPullParserException XmlPullParserException if
3976      * any.
3977      * @return int
3978      */
3979     private int getIntegerValue( String s, String attribute, XmlPullParser parser, boolean strict, int defaultValue )
3980         throws XmlPullParserException
3981     {
3982         if ( s != null )
3983         {
3984             try
3985             {
3986                 return Integer.valueOf( s ).intValue();
3987             }
3988             catch ( NumberFormatException nfe )
3989             {
3990                 if ( strict )
3991                 {
3992                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be an integer", parser, nfe );
3993                 }
3994             }
3995         }
3996         return defaultValue;
3997     } //-- int getIntegerValue( String, String, XmlPullParser, boolean )
3998 
3999     public static interface ContentTransformer
4000     {
4001         /**
4002          * Interpolate the value read from the xpp3 document
4003          * @param source The source value
4004          * @param fieldName A description of the field being interpolated. The implementation may use this to
4005          *                           log stuff.
4006          * @return The interpolated value.
4007          */
4008         String transform( String source, String fieldName );
4009     }
4010 
4011 }