View Javadoc
1   // =================== DO NOT EDIT THIS FILE ====================
2   //  Generated by Modello Velocity from reader-stax.vm
3   //  template, any modifications will be overwritten.
4   // ==============================================================
5   package org.apache.maven.plugin.lifecycle.io;
6   
7   import java.io.IOException;
8   import java.io.InputStream;
9   import java.io.Reader;
10  import java.text.DateFormat;
11  import java.util.ArrayList;
12  import java.util.Collections;
13  import java.util.Date;
14  import java.util.HashMap;
15  import java.util.HashSet;
16  import java.util.LinkedHashMap;
17  import java.util.List;
18  import java.util.Map;
19  import java.util.Set;
20  import org.apache.maven.api.annotations.Generated;
21  import org.apache.maven.api.plugin.descriptor.lifecycle.LifecycleConfiguration;
22  import org.apache.maven.api.plugin.descriptor.lifecycle.Lifecycle;
23  import org.apache.maven.api.plugin.descriptor.lifecycle.Phase;
24  import org.apache.maven.api.plugin.descriptor.lifecycle.Execution;
25  import org.apache.maven.internal.xml.XmlNodeStaxBuilder;
26  import org.apache.maven.api.xml.XmlNode;
27  import javax.xml.stream.XMLInputFactory;
28  import javax.xml.stream.XMLStreamException;
29  import javax.xml.stream.XMLStreamReader;
30  import javax.xml.transform.stream.StreamSource;
31  
32  import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
33  import static javax.xml.XMLConstants.XML_NS_URI;
34  
35  @Generated
36  public class LifecycleStaxReader {
37  
38      private static final Map<String, String> DEFAULT_ENTITIES;
39      static {
40          Map<String, String> entities = new HashMap<>();
41          entities.put("nbsp", "\u00a0");
42          entities.put("iexcl", "\u00a1");
43          entities.put("cent", "\u00a2");
44          entities.put("pound", "\u00a3");
45          entities.put("curren", "\u00a4");
46          entities.put("yen", "\u00a5");
47          entities.put("brvbar", "\u00a6");
48          entities.put("sect", "\u00a7");
49          entities.put("uml", "\u00a8");
50          entities.put("copy", "\u00a9");
51          entities.put("ordf", "\u00aa");
52          entities.put("laquo", "\u00ab");
53          entities.put("not", "\u00ac");
54          entities.put("shy", "\u00ad");
55          entities.put("reg", "\u00ae");
56          entities.put("macr", "\u00af");
57          entities.put("deg", "\u00b0");
58          entities.put("plusmn", "\u00b1");
59          entities.put("sup2", "\u00b2");
60          entities.put("sup3", "\u00b3");
61          entities.put("acute", "\u00b4");
62          entities.put("micro", "\u00b5");
63          entities.put("para", "\u00b6");
64          entities.put("middot", "\u00b7");
65          entities.put("cedil", "\u00b8");
66          entities.put("sup1", "\u00b9");
67          entities.put("ordm", "\u00ba");
68          entities.put("raquo", "\u00bb");
69          entities.put("frac14", "\u00bc");
70          entities.put("frac12", "\u00bd");
71          entities.put("frac34", "\u00be");
72          entities.put("iquest", "\u00bf");
73          entities.put("Agrave", "\u00c0");
74          entities.put("Aacute", "\u00c1");
75          entities.put("Acirc", "\u00c2");
76          entities.put("Atilde", "\u00c3");
77          entities.put("Auml", "\u00c4");
78          entities.put("Aring", "\u00c5");
79          entities.put("AElig", "\u00c6");
80          entities.put("Ccedil", "\u00c7");
81          entities.put("Egrave", "\u00c8");
82          entities.put("Eacute", "\u00c9");
83          entities.put("Ecirc", "\u00ca");
84          entities.put("Euml", "\u00cb");
85          entities.put("Igrave", "\u00cc");
86          entities.put("Iacute", "\u00cd");
87          entities.put("Icirc", "\u00ce");
88          entities.put("Iuml", "\u00cf");
89          entities.put("ETH", "\u00d0");
90          entities.put("Ntilde", "\u00d1");
91          entities.put("Ograve", "\u00d2");
92          entities.put("Oacute", "\u00d3");
93          entities.put("Ocirc", "\u00d4");
94          entities.put("Otilde", "\u00d5");
95          entities.put("Ouml", "\u00d6");
96          entities.put("times", "\u00d7");
97          entities.put("Oslash", "\u00d8");
98          entities.put("Ugrave", "\u00d9");
99          entities.put("Uacute", "\u00da");
100         entities.put("Ucirc", "\u00db");
101         entities.put("Uuml", "\u00dc");
102         entities.put("Yacute", "\u00dd");
103         entities.put("THORN", "\u00de");
104         entities.put("szlig", "\u00df");
105         entities.put("agrave", "\u00e0");
106         entities.put("aacute", "\u00e1");
107         entities.put("acirc", "\u00e2");
108         entities.put("atilde", "\u00e3");
109         entities.put("auml", "\u00e4");
110         entities.put("aring", "\u00e5");
111         entities.put("aelig", "\u00e6");
112         entities.put("ccedil", "\u00e7");
113         entities.put("egrave", "\u00e8");
114         entities.put("eacute", "\u00e9");
115         entities.put("ecirc", "\u00ea");
116         entities.put("euml", "\u00eb");
117         entities.put("igrave", "\u00ec");
118         entities.put("iacute", "\u00ed");
119         entities.put("icirc", "\u00ee");
120         entities.put("iuml", "\u00ef");
121         entities.put("eth", "\u00f0");
122         entities.put("ntilde", "\u00f1");
123         entities.put("ograve", "\u00f2");
124         entities.put("oacute", "\u00f3");
125         entities.put("ocirc", "\u00f4");
126         entities.put("otilde", "\u00f5");
127         entities.put("ouml", "\u00f6");
128         entities.put("divide", "\u00f7");
129         entities.put("oslash", "\u00f8");
130         entities.put("ugrave", "\u00f9");
131         entities.put("uacute", "\u00fa");
132         entities.put("ucirc", "\u00fb");
133         entities.put("uuml", "\u00fc");
134         entities.put("yacute", "\u00fd");
135         entities.put("thorn", "\u00fe");
136         entities.put("yuml", "\u00ff");
137 
138         // ----------------------------------------------------------------------
139         // Special entities
140         // ----------------------------------------------------------------------
141 
142         entities.put("OElig", "\u0152");
143         entities.put("oelig", "\u0153");
144         entities.put("Scaron", "\u0160");
145         entities.put("scaron", "\u0161");
146         entities.put("Yuml", "\u0178");
147         entities.put("circ", "\u02c6");
148         entities.put("tilde", "\u02dc");
149         entities.put("ensp", "\u2002");
150         entities.put("emsp", "\u2003");
151         entities.put("thinsp", "\u2009");
152         entities.put("zwnj", "\u200c");
153         entities.put("zwj", "\u200d");
154         entities.put("lrm", "\u200e");
155         entities.put("rlm", "\u200f");
156         entities.put("ndash", "\u2013");
157         entities.put("mdash", "\u2014");
158         entities.put("lsquo", "\u2018");
159         entities.put("rsquo", "\u2019");
160         entities.put("sbquo", "\u201a");
161         entities.put("ldquo", "\u201c");
162         entities.put("rdquo", "\u201d");
163         entities.put("bdquo", "\u201e");
164         entities.put("dagger", "\u2020");
165         entities.put("Dagger", "\u2021");
166         entities.put("permil", "\u2030");
167         entities.put("lsaquo", "\u2039");
168         entities.put("rsaquo", "\u203a");
169         entities.put("euro", "\u20ac");
170 
171         // ----------------------------------------------------------------------
172         // Symbol entities
173         // ----------------------------------------------------------------------
174 
175         entities.put("fnof", "\u0192");
176         entities.put("Alpha", "\u0391");
177         entities.put("Beta", "\u0392");
178         entities.put("Gamma", "\u0393");
179         entities.put("Delta", "\u0394");
180         entities.put("Epsilon", "\u0395");
181         entities.put("Zeta", "\u0396");
182         entities.put("Eta", "\u0397");
183         entities.put("Theta", "\u0398");
184         entities.put("Iota", "\u0399");
185         entities.put("Kappa", "\u039a");
186         entities.put("Lambda", "\u039b");
187         entities.put("Mu", "\u039c");
188         entities.put("Nu", "\u039d");
189         entities.put("Xi", "\u039e");
190         entities.put("Omicron", "\u039f");
191         entities.put("Pi", "\u03a0");
192         entities.put("Rho", "\u03a1");
193         entities.put("Sigma", "\u03a3");
194         entities.put("Tau", "\u03a4");
195         entities.put("Upsilon", "\u03a5");
196         entities.put("Phi", "\u03a6");
197         entities.put("Chi", "\u03a7");
198         entities.put("Psi", "\u03a8");
199         entities.put("Omega", "\u03a9");
200         entities.put("alpha", "\u03b1");
201         entities.put("beta", "\u03b2");
202         entities.put("gamma", "\u03b3");
203         entities.put("delta", "\u03b4");
204         entities.put("epsilon", "\u03b5");
205         entities.put("zeta", "\u03b6");
206         entities.put("eta", "\u03b7");
207         entities.put("theta", "\u03b8");
208         entities.put("iota", "\u03b9");
209         entities.put("kappa", "\u03ba");
210         entities.put("lambda", "\u03bb");
211         entities.put("mu", "\u03bc");
212         entities.put("nu", "\u03bd");
213         entities.put("xi", "\u03be");
214         entities.put("omicron", "\u03bf");
215         entities.put("pi", "\u03c0");
216         entities.put("rho", "\u03c1");
217         entities.put("sigmaf", "\u03c2");
218         entities.put("sigma", "\u03c3");
219         entities.put("tau", "\u03c4");
220         entities.put("upsilon", "\u03c5");
221         entities.put("phi", "\u03c6");
222         entities.put("chi", "\u03c7");
223         entities.put("psi", "\u03c8");
224         entities.put("omega", "\u03c9");
225         entities.put("thetasym", "\u03d1");
226         entities.put("upsih", "\u03d2");
227         entities.put("piv", "\u03d6");
228         entities.put("bull", "\u2022");
229         entities.put("hellip", "\u2026");
230         entities.put("prime", "\u2032");
231         entities.put("Prime", "\u2033");
232         entities.put("oline", "\u203e");
233         entities.put("frasl", "\u2044");
234         entities.put("weierp", "\u2118");
235         entities.put("image", "\u2111");
236         entities.put("real", "\u211c");
237         entities.put("trade", "\u2122");
238         entities.put("alefsym", "\u2135");
239         entities.put("larr", "\u2190");
240         entities.put("uarr", "\u2191");
241         entities.put("rarr", "\u2192");
242         entities.put("darr", "\u2193");
243         entities.put("harr", "\u2194");
244         entities.put("crarr", "\u21b5");
245         entities.put("lArr", "\u21d0");
246         entities.put("uArr", "\u21d1");
247         entities.put("rArr", "\u21d2");
248         entities.put("dArr", "\u21d3");
249         entities.put("hArr", "\u21d4");
250         entities.put("forall", "\u2200");
251         entities.put("part", "\u2202");
252         entities.put("exist", "\u2203");
253         entities.put("empty", "\u2205");
254         entities.put("nabla", "\u2207");
255         entities.put("isin", "\u2208");
256         entities.put("notin", "\u2209");
257         entities.put("ni", "\u220b");
258         entities.put("prod", "\u220f");
259         entities.put("sum", "\u2211");
260         entities.put("minus", "\u2212");
261         entities.put("lowast", "\u2217");
262         entities.put("radic", "\u221a");
263         entities.put("prop", "\u221d");
264         entities.put("infin", "\u221e");
265         entities.put("ang", "\u2220");
266         entities.put("and", "\u2227");
267         entities.put("or", "\u2228");
268         entities.put("cap", "\u2229");
269         entities.put("cup", "\u222a");
270         entities.put("int", "\u222b");
271         entities.put("there4", "\u2234");
272         entities.put("sim", "\u223c");
273         entities.put("cong", "\u2245");
274         entities.put("asymp", "\u2248");
275         entities.put("ne", "\u2260");
276         entities.put("equiv", "\u2261");
277         entities.put("le", "\u2264");
278         entities.put("ge", "\u2265");
279         entities.put("sub", "\u2282");
280         entities.put("sup", "\u2283");
281         entities.put("nsub", "\u2284");
282         entities.put("sube", "\u2286");
283         entities.put("supe", "\u2287");
284         entities.put("oplus", "\u2295");
285         entities.put("otimes", "\u2297");
286         entities.put("perp", "\u22a5");
287         entities.put("sdot", "\u22c5");
288         entities.put("lceil", "\u2308");
289         entities.put("rceil", "\u2309");
290         entities.put("lfloor", "\u230a");
291         entities.put("rfloor", "\u230b");
292         entities.put("lang", "\u2329");
293         entities.put("rang", "\u232a");
294         entities.put("loz", "\u25ca");
295         entities.put("spades", "\u2660");
296         entities.put("clubs", "\u2663");
297         entities.put("hearts", "\u2665");
298         entities.put("diams", "\u2666");
299         DEFAULT_ENTITIES = Collections.unmodifiableMap(entities);
300     }
301 
302     static class InputFactoryHolder {
303         static XMLInputFactory XML_INPUT_FACTORY;
304         static {
305             XMLInputFactory factory = XMLInputFactory.newFactory();
306             factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
307             XML_INPUT_FACTORY = factory;
308         }
309     }
310 
311     private boolean addDefaultEntities = true;
312 
313     private final ContentTransformer contentTransformer;
314 
315     public LifecycleStaxReader() {
316         this((s, f) -> s);
317     }
318 
319     public LifecycleStaxReader(ContentTransformer contentTransformer) {
320         this.contentTransformer = contentTransformer;
321     }
322 
323     /**
324      * Returns the {@link XMLInputFactory} used by this reader.
325      *
326      * @return the {@link XMLInputFactory} used by this reader.
327      */
328     public XMLInputFactory getXMLInputFactory() {
329         return InputFactoryHolder.XML_INPUT_FACTORY;
330     }
331 
332     /**
333      * Returns the state of the "add default entities" flag.
334      *
335      * @return boolean
336      */
337     public boolean getAddDefaultEntities() {
338         return addDefaultEntities;
339     } //-- boolean getAddDefaultEntities()
340 
341     /**
342      * Sets the state of the "add default entities" flag.
343      *
344      * @param addDefaultEntities a addDefaultEntities object.
345      */
346     public void setAddDefaultEntities(boolean addDefaultEntities) {
347         this.addDefaultEntities = addDefaultEntities;
348     } //-- void setAddDefaultEntities(boolean)
349 
350 
351     public LifecycleConfiguration read(Reader reader) throws XMLStreamException {
352         return read(reader, true);
353     }
354 
355     /**
356      * @param reader a reader object.
357      * @param strict a strict object.
358      * @throws XMLStreamException XMLStreamException if
359      * any.
360      * @return LifecycleConfiguration
361      */
362     public LifecycleConfiguration read(Reader reader, boolean strict) throws XMLStreamException {
363         StreamSource streamSource = new StreamSource(reader);
364         XMLInputFactory factory = getXMLInputFactory();
365         XMLStreamReader parser = factory.createXMLStreamReader(streamSource);
366     return read(parser, strict);
367     } //-- LifecycleConfiguration read(Reader, boolean)
368 
369     public LifecycleConfiguration read(InputStream in) throws XMLStreamException {
370         return read(in, true);
371     }
372 
373     /**
374      * Method read.
375      *
376      * @param in a in object.
377      * @param strict a strict object.
378      * @throws XMLStreamException XMLStreamException if
379      * any.
380      * @return LifecycleConfiguration
381      */
382     public LifecycleConfiguration read(InputStream in, boolean strict) throws XMLStreamException {
383         StreamSource streamSource = new StreamSource(in);
384         XMLInputFactory factory = getXMLInputFactory();
385         XMLStreamReader parser = factory.createXMLStreamReader(streamSource);
386         return read(parser, strict);
387     } //-- LifecycleConfiguration read(InputStream, boolean)
388 
389     /**
390      * Method read.
391      *
392      * @param parser a parser object.
393      * @param strict a strict object.
394      * @throws XMLStreamException XMLStreamException if
395      * any.
396      * @return LifecycleConfiguration
397      */
398     public LifecycleConfiguration read(XMLStreamReader parser, boolean strict) throws XMLStreamException {
399         LifecycleConfiguration lifecycleConfiguration = null;
400         int eventType = parser.getEventType();
401         boolean parsed = false;
402         while (eventType != XMLStreamReader.END_DOCUMENT) {
403             if (eventType == XMLStreamReader.START_ELEMENT) {
404                 if (strict && ! "lifecycles".equals(parser.getLocalName())) {
405                     throw new XMLStreamException("Expected root element 'lifecycles' but found '" + parser.getName() + "'", parser.getLocation(), null);
406                 } else if (parsed) {
407                     // fallback, already expected a XMLStreamException due to invalid XML
408                     throw new XMLStreamException("Duplicated tag: 'lifecycles'", parser.getLocation(), null);
409                 }
410                 lifecycleConfiguration = parseLifecycleConfiguration(parser, strict);
411                 parsed = true;
412             }
413             eventType = parser.next();
414         }
415         if (parsed) {
416             return lifecycleConfiguration;
417         }
418         throw new XMLStreamException("Expected root element 'lifecycles' but found no element at all: invalid XML document", parser.getLocation(), null);
419     } //-- LifecycleConfiguration read(XMLStreamReader, boolean)
420 
421     private LifecycleConfiguration parseLifecycleConfiguration(XMLStreamReader parser, boolean strict) throws XMLStreamException {
422         String tagName = parser.getLocalName();
423         LifecycleConfiguration.Builder lifecycleConfiguration = LifecycleConfiguration.newBuilder(true);
424         for (int i = parser.getAttributeCount() - 1; i >= 0; i--) {
425             String name = parser.getAttributeLocalName(i);
426             String ns = parser.getAttributeNamespace(i);
427             String value = parser.getAttributeValue(i);
428             if (W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(ns) || XML_NS_URI.equals(ns)) {
429                 // just ignore attributes with non-default namespace (for example: xsi and xml)
430             } else if ("xmlns".equals(name)) {
431                 // ignore xmlns attribute in root class, which is a reserved attribute name
432             } else {
433                 checkUnknownAttribute(parser, name, tagName, strict);
434             }
435         }
436         Set<String> parsed = new HashSet<>();
437         List<Lifecycle> lifecycles = new ArrayList<>();
438         while ((strict ? parser.nextTag() : nextTag(parser)) == XMLStreamReader.START_ELEMENT) {
439             String childName = checkDuplicate(parser.getLocalName(), parser, parsed);
440             switch (childName) {
441                 case "lifecycle": {
442                     lifecycles.add(parseLifecycle(parser, strict));
443                     break;
444                 }
445                 default: {
446                     checkUnknownElement(parser, strict);
447                     break;
448                 }
449             }
450         }
451         lifecycleConfiguration.lifecycles(lifecycles);
452         lifecycleConfiguration.namespaceUri(parser.getNamespaceURI());
453         lifecycleConfiguration.modelEncoding(parser.getEncoding());
454         return lifecycleConfiguration.build();
455     }
456 
457     private Lifecycle parseLifecycle(XMLStreamReader parser, boolean strict) throws XMLStreamException {
458         String tagName = parser.getLocalName();
459         Lifecycle.Builder lifecycle = Lifecycle.newBuilder(true);
460         for (int i = parser.getAttributeCount() - 1; i >= 0; i--) {
461             String name = parser.getAttributeLocalName(i);
462             String ns = parser.getAttributeNamespace(i);
463             String value = parser.getAttributeValue(i);
464             if (W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(ns) || XML_NS_URI.equals(ns)) {
465                 // just ignore attributes with non-default namespace (for example: xsi and xml)
466             } else {
467                 checkUnknownAttribute(parser, name, tagName, strict);
468             }
469         }
470         Set<String> parsed = new HashSet<>();
471         while ((strict ? parser.nextTag() : nextTag(parser)) == XMLStreamReader.START_ELEMENT) {
472             String childName = checkDuplicate(parser.getLocalName(), parser, parsed);
473             switch (childName) {
474                 case "id": {
475                     lifecycle.id(interpolatedTrimmed(nextText(parser, strict), "id"));
476                     break;
477                 }
478                 case "phases": {
479                     List<Phase> phases = new ArrayList<>();
480                     while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
481                         if ("phase".equals(parser.getLocalName())) {
482                             phases.add(parsePhase(parser, strict));
483                         } else {
484                             checkUnknownElement(parser, strict);
485                         }
486                     }
487                     lifecycle.phases(phases);
488                     break;
489                 }
490                 default: {
491                     checkUnknownElement(parser, strict);
492                     break;
493                 }
494             }
495         }
496         return lifecycle.build();
497     }
498 
499     private Phase parsePhase(XMLStreamReader parser, boolean strict) throws XMLStreamException {
500         String tagName = parser.getLocalName();
501         Phase.Builder phase = Phase.newBuilder(true);
502         for (int i = parser.getAttributeCount() - 1; i >= 0; i--) {
503             String name = parser.getAttributeLocalName(i);
504             String ns = parser.getAttributeNamespace(i);
505             String value = parser.getAttributeValue(i);
506             if (W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(ns) || XML_NS_URI.equals(ns)) {
507                 // just ignore attributes with non-default namespace (for example: xsi and xml)
508             } else if ("executionPoint".equals(name)) {
509                 phase.executionPoint(interpolatedTrimmed(value, "executionPoint"));
510             } else if ("priority".equals(name)) {
511                 phase.priority(getIntegerValue(interpolatedTrimmed(value, "priority"), "priority", parser, strict, 0));
512             } else {
513                 checkUnknownAttribute(parser, name, tagName, strict);
514             }
515         }
516         Set<String> parsed = new HashSet<>();
517         while ((strict ? parser.nextTag() : nextTag(parser)) == XMLStreamReader.START_ELEMENT) {
518             String childName = checkDuplicate(parser.getLocalName(), parser, parsed);
519             switch (childName) {
520                 case "id": {
521                     phase.id(interpolatedTrimmed(nextText(parser, strict), "id"));
522                     break;
523                 }
524                 case "executions": {
525                     List<Execution> executions = new ArrayList<>();
526                     while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
527                         if ("execution".equals(parser.getLocalName())) {
528                             executions.add(parseExecution(parser, strict));
529                         } else {
530                             checkUnknownElement(parser, strict);
531                         }
532                     }
533                     phase.executions(executions);
534                     break;
535                 }
536                 case "configuration": {
537                     phase.configuration(buildXmlNode(parser));
538                     break;
539                 }
540                 default: {
541                     checkUnknownElement(parser, strict);
542                     break;
543                 }
544             }
545         }
546         return phase.build();
547     }
548 
549     private Execution parseExecution(XMLStreamReader parser, boolean strict) throws XMLStreamException {
550         String tagName = parser.getLocalName();
551         Execution.Builder execution = Execution.newBuilder(true);
552         for (int i = parser.getAttributeCount() - 1; i >= 0; i--) {
553             String name = parser.getAttributeLocalName(i);
554             String ns = parser.getAttributeNamespace(i);
555             String value = parser.getAttributeValue(i);
556             if (W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(ns) || XML_NS_URI.equals(ns)) {
557                 // just ignore attributes with non-default namespace (for example: xsi and xml)
558             } else {
559                 checkUnknownAttribute(parser, name, tagName, strict);
560             }
561         }
562         Set<String> parsed = new HashSet<>();
563         while ((strict ? parser.nextTag() : nextTag(parser)) == XMLStreamReader.START_ELEMENT) {
564             String childName = checkDuplicate(parser.getLocalName(), parser, parsed);
565             switch (childName) {
566                 case "configuration": {
567                     execution.configuration(buildXmlNode(parser));
568                     break;
569                 }
570                 case "goals": {
571                     List<String> goals = new ArrayList<>();
572                     while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
573                         if ("goal".equals(parser.getLocalName())) {
574                             goals.add(interpolatedTrimmed(nextText(parser, strict), "goals"));
575                         } else {
576                             checkUnknownElement(parser, strict);
577                         }
578                     }
579                     execution.goals(goals);
580                     break;
581                 }
582                 default: {
583                     checkUnknownElement(parser, strict);
584                     break;
585                 }
586             }
587         }
588         return execution.build();
589     }
590 
591 
592     private String checkDuplicate(String tagName, XMLStreamReader parser, Set<String> parsed) throws XMLStreamException {
593         switch (tagName) {
594         case "lifecycle":
595             break;
596         default:
597             if (!parsed.add(tagName)) {
598                 throw new XMLStreamException("Duplicated tag: '" + tagName + "'", parser.getLocation(), null);
599             }
600         }
601         return tagName;
602     }
603 
604     /**
605      * Method checkUnknownAttribute.
606      *
607      * @param parser a parser object.
608      * @param strict a strict object.
609      * @param tagName a tagName object.
610      * @param attribute a attribute object.
611      * @throws XMLStreamException XMLStreamException if
612      * any.
613      * @throws IOException IOException if any.
614      */
615     private void checkUnknownAttribute(XMLStreamReader parser, String attribute, String tagName, boolean strict) throws XMLStreamException {
616         // strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
617         if (strict) {
618             throw new XMLStreamException("Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser.getLocation(), null);
619         }
620     } //-- void checkUnknownAttribute(XMLStreamReader, String, String, boolean)
621 
622     /**
623      * Method checkUnknownElement.
624      *
625      * @param parser a parser object.
626      * @param strict a strict object.
627      * @throws XMLStreamException XMLStreamException if
628      * any.
629      * @throws IOException IOException if any.
630      */
631     private void checkUnknownElement(XMLStreamReader parser, boolean strict) throws XMLStreamException {
632         if (strict) {
633             throw new XMLStreamException("Unrecognised tag: '" + parser.getName() + "'", parser.getLocation(), null);
634         }
635 
636         for (int unrecognizedTagCount = 1; unrecognizedTagCount > 0;) {
637             int eventType = nextTag(parser);
638             if (eventType == XMLStreamReader.START_ELEMENT) {
639                 unrecognizedTagCount++;
640             } else if (eventType == XMLStreamReader.END_ELEMENT) {
641                 unrecognizedTagCount--;
642             }
643         }
644     } //-- void checkUnknownElement(XMLStreamReader, boolean)
645 
646     /**
647      * Method getTrimmedValue.
648      *
649      * @param s a s object.
650      * @return String
651      */
652     private String getTrimmedValue(String s) {
653         if (s != null) {
654             s = s.trim();
655         }
656         return s;
657     } //-- String getTrimmedValue(String)
658 
659     /**
660      * Method interpolatedTrimmed.
661      *
662      * @param value a value object.
663      * @param context a context object.
664      * @return String
665      */
666     private String interpolatedTrimmed(String value, String context) {
667         return getTrimmedValue(contentTransformer.transform(value, context));
668     } //-- String interpolatedTrimmed(String, String)
669 
670     /**
671      * Method nextTag.
672      *
673      * @param parser a parser object.
674      * @throws IOException IOException if any.
675      * @throws XMLStreamException XMLStreamException if
676      * any.
677      * @return int
678      */
679     private int nextTag(XMLStreamReader parser) throws XMLStreamException {
680         while (true) {
681             int next = parser.next();
682             switch (next) {
683                 case XMLStreamReader.SPACE:
684                 case XMLStreamReader.COMMENT:
685                 case XMLStreamReader.PROCESSING_INSTRUCTION:
686                 case XMLStreamReader.CDATA:
687                 case XMLStreamReader.CHARACTERS:
688                     continue;
689                 case XMLStreamReader.START_ELEMENT:
690                 case XMLStreamReader.END_ELEMENT:
691                     return next;
692             }
693         }
694     } //-- int nextTag(XMLStreamReader)
695 
696     private String nextText(XMLStreamReader parser, boolean strict) throws XMLStreamException {
697         int eventType = parser.getEventType();
698         if (eventType != XMLStreamReader.START_ELEMENT) {
699             throw new XMLStreamException("parser must be on START_ELEMENT to read next text", parser.getLocation(), null);
700         }
701         eventType = parser.next();
702         StringBuilder result = new StringBuilder();
703         while (true) {
704             if (eventType == XMLStreamReader.CHARACTERS || eventType == XMLStreamReader.CDATA) {
705                 result.append(parser.getText());
706             } else if (eventType == XMLStreamReader.ENTITY_REFERENCE) {
707                 String val = null;
708                 if (strict) {
709                     throw new XMLStreamException("Entities are not supported in strict mode", parser.getLocation(), null);
710                 } else if (addDefaultEntities) {
711                     val = DEFAULT_ENTITIES.get(parser.getLocalName());
712                 }
713                 if (val != null) {
714                     result.append(val);
715                 } else {
716                     result.append("&").append(parser.getLocalName()).append(";");
717                 }
718             } else if (eventType != XMLStreamReader.COMMENT) {
719                 break;
720             }
721             eventType = parser.next();
722         }
723         if (eventType != XMLStreamReader.END_ELEMENT) {
724             throw new XMLStreamException(
725                 "TEXT must be immediately followed by END_ELEMENT and not " + eventType /*TODO: TYPES[eventType]*/, parser.getLocation(), null);
726         }
727         return result.toString();
728     }
729 
730     private XmlNode buildXmlNode(XMLStreamReader parser) throws XMLStreamException {
731         return XmlNodeStaxBuilder.build(parser);
732     }
733 
734     /**
735      * Method getIntegerValue.
736      *
737      * @param s a s object.
738      * @param strict a strict object.
739      * @param parser a parser object.
740      * @param attribute a attribute object.
741      * @throws XMLStreamException XMLStreamException if
742      * any.
743      * @return int
744      */
745     private int getIntegerValue(String s, String attribute, XMLStreamReader parser, boolean strict, int defaultValue) throws XMLStreamException {
746         if (s != null) {
747             try {
748                 return Integer.valueOf(s).intValue();
749             } catch (NumberFormatException nfe) {
750                 if (strict) {
751                     throw new XMLStreamException("Unable to parse element '" + attribute + "', must be an integer", parser.getLocation(), nfe);
752                 }
753             }
754         }
755         return defaultValue;
756     } //-- int getIntegerValue(String, String, XMLStreamReader, boolean)
757 
758     public static interface ContentTransformer {
759         /**
760          * Interpolate the value read from the xpp3 document
761          * @param source The source value
762          * @param fieldName A description of the field being interpolated. The implementation may use this to
763          *                           log stuff.
764          * @return The interpolated value.
765          */
766         String transform(String source, String fieldName);
767     }
768 
769 }