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