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