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