blob: f4b5f03d938ddd10194426c4463213b89de87ad4 [file] [log] [blame]
#*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*#
#parse ( "common.vm" )
#
#set ( $package = "${packageToolV4}" )
#set ( $className = "${model.name}StaxReader" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
#set ( $rootXml = $Helper.xmlClassMetadata( $root ) )
#set ( $rootTag = $rootXml.tagName )
#set ( $rootUcapName = $Helper.capitalise( $root.name ) )
#set ( $rootLcapName = $Helper.uncapitalise( $root.name ) )
#
#set ( $needXmlContext = false )
#foreach ( $class in $model.allClasses )
#set ( $allFields = $Helper.xmlFields( $class ) )
#foreach ( $field in $allFields )
#if ( $Helper.xmlFieldMetadata( $field ).format )
#set ( $needXmlContext = true )
#end
#end
#end
#
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java
// =================== DO NOT EDIT THIS FILE ====================
// Generated by Modello Velocity from ${template}
// template, any modifications will be overwritten.
// ==============================================================
package ${package};
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.text.DateFormat;
#if ( $needXmlContext )
import java.util.ArrayDeque;
#end
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
#if ( $needXmlContext )
import java.util.Deque;
#end
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.maven.api.annotations.Generated;
#if ( $locationTracking )
import ${packageModelV4}.InputSource;
import ${packageModelV4}.InputLocation;
#end
#foreach ( $class in $model.allClasses )
import ${packageModelV4}.${class.name};
#end
import org.apache.maven.internal.xml.XmlNodeBuilder;
import org.apache.maven.api.xml.XmlNode;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
import static javax.xml.XMLConstants.XML_NS_URI;
@Generated
public class ${className} {
private static final Map<String, String> DEFAULT_ENTITIES;
static {
Map<String, String> entities = new HashMap<>();
entities.put("nbsp", "\u00a0");
entities.put("iexcl", "\u00a1");
entities.put("cent", "\u00a2");
entities.put("pound", "\u00a3");
entities.put("curren", "\u00a4");
entities.put("yen", "\u00a5");
entities.put("brvbar", "\u00a6");
entities.put("sect", "\u00a7");
entities.put("uml", "\u00a8");
entities.put("copy", "\u00a9");
entities.put("ordf", "\u00aa");
entities.put("laquo", "\u00ab");
entities.put("not", "\u00ac");
entities.put("shy", "\u00ad");
entities.put("reg", "\u00ae");
entities.put("macr", "\u00af");
entities.put("deg", "\u00b0");
entities.put("plusmn", "\u00b1");
entities.put("sup2", "\u00b2");
entities.put("sup3", "\u00b3");
entities.put("acute", "\u00b4");
entities.put("micro", "\u00b5");
entities.put("para", "\u00b6");
entities.put("middot", "\u00b7");
entities.put("cedil", "\u00b8");
entities.put("sup1", "\u00b9");
entities.put("ordm", "\u00ba");
entities.put("raquo", "\u00bb");
entities.put("frac14", "\u00bc");
entities.put("frac12", "\u00bd");
entities.put("frac34", "\u00be");
entities.put("iquest", "\u00bf");
entities.put("Agrave", "\u00c0");
entities.put("Aacute", "\u00c1");
entities.put("Acirc", "\u00c2");
entities.put("Atilde", "\u00c3");
entities.put("Auml", "\u00c4");
entities.put("Aring", "\u00c5");
entities.put("AElig", "\u00c6");
entities.put("Ccedil", "\u00c7");
entities.put("Egrave", "\u00c8");
entities.put("Eacute", "\u00c9");
entities.put("Ecirc", "\u00ca");
entities.put("Euml", "\u00cb");
entities.put("Igrave", "\u00cc");
entities.put("Iacute", "\u00cd");
entities.put("Icirc", "\u00ce");
entities.put("Iuml", "\u00cf");
entities.put("ETH", "\u00d0");
entities.put("Ntilde", "\u00d1");
entities.put("Ograve", "\u00d2");
entities.put("Oacute", "\u00d3");
entities.put("Ocirc", "\u00d4");
entities.put("Otilde", "\u00d5");
entities.put("Ouml", "\u00d6");
entities.put("times", "\u00d7");
entities.put("Oslash", "\u00d8");
entities.put("Ugrave", "\u00d9");
entities.put("Uacute", "\u00da");
entities.put("Ucirc", "\u00db");
entities.put("Uuml", "\u00dc");
entities.put("Yacute", "\u00dd");
entities.put("THORN", "\u00de");
entities.put("szlig", "\u00df");
entities.put("agrave", "\u00e0");
entities.put("aacute", "\u00e1");
entities.put("acirc", "\u00e2");
entities.put("atilde", "\u00e3");
entities.put("auml", "\u00e4");
entities.put("aring", "\u00e5");
entities.put("aelig", "\u00e6");
entities.put("ccedil", "\u00e7");
entities.put("egrave", "\u00e8");
entities.put("eacute", "\u00e9");
entities.put("ecirc", "\u00ea");
entities.put("euml", "\u00eb");
entities.put("igrave", "\u00ec");
entities.put("iacute", "\u00ed");
entities.put("icirc", "\u00ee");
entities.put("iuml", "\u00ef");
entities.put("eth", "\u00f0");
entities.put("ntilde", "\u00f1");
entities.put("ograve", "\u00f2");
entities.put("oacute", "\u00f3");
entities.put("ocirc", "\u00f4");
entities.put("otilde", "\u00f5");
entities.put("ouml", "\u00f6");
entities.put("divide", "\u00f7");
entities.put("oslash", "\u00f8");
entities.put("ugrave", "\u00f9");
entities.put("uacute", "\u00fa");
entities.put("ucirc", "\u00fb");
entities.put("uuml", "\u00fc");
entities.put("yacute", "\u00fd");
entities.put("thorn", "\u00fe");
entities.put("yuml", "\u00ff");
// ----------------------------------------------------------------------
// Special entities
// ----------------------------------------------------------------------
entities.put("OElig", "\u0152");
entities.put("oelig", "\u0153");
entities.put("Scaron", "\u0160");
entities.put("scaron", "\u0161");
entities.put("Yuml", "\u0178");
entities.put("circ", "\u02c6");
entities.put("tilde", "\u02dc");
entities.put("ensp", "\u2002");
entities.put("emsp", "\u2003");
entities.put("thinsp", "\u2009");
entities.put("zwnj", "\u200c");
entities.put("zwj", "\u200d");
entities.put("lrm", "\u200e");
entities.put("rlm", "\u200f");
entities.put("ndash", "\u2013");
entities.put("mdash", "\u2014");
entities.put("lsquo", "\u2018");
entities.put("rsquo", "\u2019");
entities.put("sbquo", "\u201a");
entities.put("ldquo", "\u201c");
entities.put("rdquo", "\u201d");
entities.put("bdquo", "\u201e");
entities.put("dagger", "\u2020");
entities.put("Dagger", "\u2021");
entities.put("permil", "\u2030");
entities.put("lsaquo", "\u2039");
entities.put("rsaquo", "\u203a");
entities.put("euro", "\u20ac");
// ----------------------------------------------------------------------
// Symbol entities
// ----------------------------------------------------------------------
entities.put("fnof", "\u0192");
entities.put("Alpha", "\u0391");
entities.put("Beta", "\u0392");
entities.put("Gamma", "\u0393");
entities.put("Delta", "\u0394");
entities.put("Epsilon", "\u0395");
entities.put("Zeta", "\u0396");
entities.put("Eta", "\u0397");
entities.put("Theta", "\u0398");
entities.put("Iota", "\u0399");
entities.put("Kappa", "\u039a");
entities.put("Lambda", "\u039b");
entities.put("Mu", "\u039c");
entities.put("Nu", "\u039d");
entities.put("Xi", "\u039e");
entities.put("Omicron", "\u039f");
entities.put("Pi", "\u03a0");
entities.put("Rho", "\u03a1");
entities.put("Sigma", "\u03a3");
entities.put("Tau", "\u03a4");
entities.put("Upsilon", "\u03a5");
entities.put("Phi", "\u03a6");
entities.put("Chi", "\u03a7");
entities.put("Psi", "\u03a8");
entities.put("Omega", "\u03a9");
entities.put("alpha", "\u03b1");
entities.put("beta", "\u03b2");
entities.put("gamma", "\u03b3");
entities.put("delta", "\u03b4");
entities.put("epsilon", "\u03b5");
entities.put("zeta", "\u03b6");
entities.put("eta", "\u03b7");
entities.put("theta", "\u03b8");
entities.put("iota", "\u03b9");
entities.put("kappa", "\u03ba");
entities.put("lambda", "\u03bb");
entities.put("mu", "\u03bc");
entities.put("nu", "\u03bd");
entities.put("xi", "\u03be");
entities.put("omicron", "\u03bf");
entities.put("pi", "\u03c0");
entities.put("rho", "\u03c1");
entities.put("sigmaf", "\u03c2");
entities.put("sigma", "\u03c3");
entities.put("tau", "\u03c4");
entities.put("upsilon", "\u03c5");
entities.put("phi", "\u03c6");
entities.put("chi", "\u03c7");
entities.put("psi", "\u03c8");
entities.put("omega", "\u03c9");
entities.put("thetasym", "\u03d1");
entities.put("upsih", "\u03d2");
entities.put("piv", "\u03d6");
entities.put("bull", "\u2022");
entities.put("hellip", "\u2026");
entities.put("prime", "\u2032");
entities.put("Prime", "\u2033");
entities.put("oline", "\u203e");
entities.put("frasl", "\u2044");
entities.put("weierp", "\u2118");
entities.put("image", "\u2111");
entities.put("real", "\u211c");
entities.put("trade", "\u2122");
entities.put("alefsym", "\u2135");
entities.put("larr", "\u2190");
entities.put("uarr", "\u2191");
entities.put("rarr", "\u2192");
entities.put("darr", "\u2193");
entities.put("harr", "\u2194");
entities.put("crarr", "\u21b5");
entities.put("lArr", "\u21d0");
entities.put("uArr", "\u21d1");
entities.put("rArr", "\u21d2");
entities.put("dArr", "\u21d3");
entities.put("hArr", "\u21d4");
entities.put("forall", "\u2200");
entities.put("part", "\u2202");
entities.put("exist", "\u2203");
entities.put("empty", "\u2205");
entities.put("nabla", "\u2207");
entities.put("isin", "\u2208");
entities.put("notin", "\u2209");
entities.put("ni", "\u220b");
entities.put("prod", "\u220f");
entities.put("sum", "\u2211");
entities.put("minus", "\u2212");
entities.put("lowast", "\u2217");
entities.put("radic", "\u221a");
entities.put("prop", "\u221d");
entities.put("infin", "\u221e");
entities.put("ang", "\u2220");
entities.put("and", "\u2227");
entities.put("or", "\u2228");
entities.put("cap", "\u2229");
entities.put("cup", "\u222a");
entities.put("int", "\u222b");
entities.put("there4", "\u2234");
entities.put("sim", "\u223c");
entities.put("cong", "\u2245");
entities.put("asymp", "\u2248");
entities.put("ne", "\u2260");
entities.put("equiv", "\u2261");
entities.put("le", "\u2264");
entities.put("ge", "\u2265");
entities.put("sub", "\u2282");
entities.put("sup", "\u2283");
entities.put("nsub", "\u2284");
entities.put("sube", "\u2286");
entities.put("supe", "\u2287");
entities.put("oplus", "\u2295");
entities.put("otimes", "\u2297");
entities.put("perp", "\u22a5");
entities.put("sdot", "\u22c5");
entities.put("lceil", "\u2308");
entities.put("rceil", "\u2309");
entities.put("lfloor", "\u230a");
entities.put("rfloor", "\u230b");
entities.put("lang", "\u2329");
entities.put("rang", "\u232a");
entities.put("loz", "\u25ca");
entities.put("spades", "\u2660");
entities.put("clubs", "\u2663");
entities.put("hearts", "\u2665");
entities.put("diams", "\u2666");
DEFAULT_ENTITIES = Collections.unmodifiableMap(entities);
}
private boolean addDefaultEntities = true;
#if ( $locationTracking )
private boolean addLocationInformation = true;
#end
private final ContentTransformer contentTransformer;
public ${className}() {
this((s, f) -> s);
}
public ${className}(ContentTransformer contentTransformer) {
this.contentTransformer = contentTransformer;
}
/**
* Returns the state of the "add default entities" flag.
*
* @return boolean
*/
public boolean getAddDefaultEntities() {
return addDefaultEntities;
} //-- boolean getAddDefaultEntities()
/**
* Sets the state of the "add default entities" flag.
*
* @param addDefaultEntities a addDefaultEntities object.
*/
public void setAddDefaultEntities(boolean addDefaultEntities) {
this.addDefaultEntities = addDefaultEntities;
} //-- void setAddDefaultEntities(boolean)
#if ( $locationTracking )
/**
* Returns the state of the "add location information" flag.
*
* @return boolean
*/
public boolean getAddLocationInformation() {
return addLocationInformation;
} //-- boolean getAddLocationInformation()
/**
* Sets the state of the "add location information" flag.
*
* @param addLocationInformation a addLocationInformation object.
*/
public void setAddLocationInformation(boolean addLocationInformation) {
this.addLocationInformation = addLocationInformation;
} //-- void setAddLocationInformation(boolean)
#end
public ${root.name} read(Reader reader) throws XMLStreamException {
#if ( $locationTracking )
return read(reader, true, null);
#else
return read(reader, true);
#end
}
/**
* @param reader a reader object.
* @param strict a strict object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return ${root.name}
*/
#if ( $locationTracking )
public ${root.name} read(Reader reader, boolean strict, InputSource source) throws XMLStreamException {
#else
public ${root.name} read(Reader reader, boolean strict) throws XMLStreamException {
#end
XMLInputFactory factory = new com.ctc.wstx.stax.WstxInputFactory();
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
#if ( $locationTracking )
StreamSource streamSource = new StreamSource(reader, source != null ? source.getLocation() : null);
#else
StreamSource streamSource = new StreamSource(reader);
#end
XMLStreamReader parser = factory.createXMLStreamReader(streamSource);
#if ( $locationTracking )
return read(parser, strict, source);
#else
return read(parser, strict);
#end
} //-- ${root.name} read(Reader, boolean)
public ${root.name} read(InputStream in) throws XMLStreamException {
#if ( $locationTracking )
return read(in, true, null);
#else
return read(in, true);
#end
}
/**
* Method read.
*
* @param in a in object.
* @param strict a strict object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return ${root.name}
*/
#if ( $locationTracking )
public ${root.name} read(InputStream in, boolean strict, InputSource source) throws XMLStreamException {
#else
public ${root.name} read(InputStream in, boolean strict) throws XMLStreamException {
#end
XMLInputFactory factory = new com.ctc.wstx.stax.WstxInputFactory();
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
#if ( $locationTracking )
StreamSource streamSource = new StreamSource(in, source != null ? source.getLocation() : null);
#else
StreamSource streamSource = new StreamSource(in);
#end
XMLStreamReader parser = factory.createXMLStreamReader(streamSource);
#if ( $locationTracking )
return read(parser, strict, source);
#else
return read(parser, strict);
#end
} //-- ${root.name} read(InputStream, boolean)
/**
* Method read.
*
* @param parser a parser object.
* @param strict a strict object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return ${root.name}
*/
#if ( $locationTracking )
public ${root.name} read(XMLStreamReader parser, boolean strict, InputSource source) throws XMLStreamException {
#else
public ${root.name} read(XMLStreamReader parser, boolean strict) throws XMLStreamException {
#end
#if ( $needXmlContext )
Deque<Object> context = new ArrayDeque<>();
#end
$rootUcapName $rootLcapName = null;
int eventType = parser.getEventType();
boolean parsed = false;
while (eventType != XMLStreamReader.END_DOCUMENT) {
if (eventType == XMLStreamReader.START_ELEMENT) {
if (strict && ! "${rootTag}".equals(parser.getLocalName())) {
throw new XMLStreamException("Expected root element '${rootTag}' but found '" + parser.getName() + "'", parser.getLocation(), null);
} else if (parsed) {
// fallback, already expected a XMLStreamException due to invalid XML
throw new XMLStreamException("Duplicated tag: '${rootTag}'", parser.getLocation(), null);
}
#if ( $locationTracking )
$rootLcapName = parse${rootUcapName}(parser, strict, source);
#elseif ( $needXmlContext )
$rootLcapName = parse${rootUcapName}(parser, strict, context);
#else
$rootLcapName = parse${rootUcapName}(parser, strict);
#end
parsed = true;
}
eventType = parser.next();
}
if (parsed) {
return $rootLcapName;
}
throw new XMLStreamException("Expected root element '${rootTag}' but found no element at all: invalid XML document", parser.getLocation(), null);
} //-- ${root.name} read(XMLStreamReader, boolean)
#foreach ( $class in $model.allClasses )
#if ( $class.name != "InputSource" && $class.name != "InputLocation" )
#set ( $classUcapName = $Helper.capitalise( $class.name ) )
#set ( $classLcapName = $Helper.uncapitalise( $class.name ) )
#set ( $ancestors = $Helper.ancestors( $class ) )
#set ( $allFields = $Helper.xmlFields( $class ) )
#if ( $locationTracking )
private ${classUcapName} parse${classUcapName}(XMLStreamReader parser, boolean strict, InputSource source) throws XMLStreamException {
#elseif ( $needXmlContext )
private ${classUcapName} parse${classUcapName}(XMLStreamReader parser, boolean strict, Deque<Object> context) throws XMLStreamException {
#else
private ${classUcapName} parse${classUcapName}(XMLStreamReader parser, boolean strict) throws XMLStreamException {
#end
String tagName = parser.getLocalName();
${classUcapName}.Builder ${classLcapName} = ${classUcapName}.newBuilder(true);
#if ( $locationTracking )
if (addLocationInformation) {
${classLcapName}.location("", new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source));
}
#end
for (int i = parser.getAttributeCount() - 1; i >= 0; i--) {
String name = parser.getAttributeLocalName(i);
String ns = parser.getAttributeNamespace(i);
String value = parser.getAttributeValue(i);
if (W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(ns) || XML_NS_URI.equals(ns)) {
// just ignore attributes with non-default namespace (for example: xsi and xml)
#if ( $class == $root )
} else if ("xmlns".equals(name)) {
// ignore xmlns attribute in root class, which is a reserved attribute name
#end
#foreach ( $field in $allFields )
#if ( $Helper.xmlFieldMetadata( $field ).attribute )
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
#set ( $fieldCapName = $Helper.capitalise( $field.name ) )
} else if ("$fieldTagName".equals(name)) {
#if ( $locationTracking )
if (addLocationInformation) {
${classLcapName}.location(name, new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source));
}
#end
#if ( $field.type == "String" )
${classLcapName}.${field.name}(interpolatedTrimmed(value, "$fieldTagName"));
#elseif ( $field.type == "boolean" || $field.type == "Boolean" )
${classLcapName}.${field.name}(getBooleanValue(interpolatedTrimmed(value, "$fieldTagName"), "$fieldTagName", parser, ${field.defaultValue}));
#else
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
#end
#end
#end
} else {
checkUnknownAttribute(parser, name, tagName, strict);
}
}
Set<String> parsed = new HashSet<>();
#foreach ( $field in $allFields )
#if ( $Helper.isFlatItems( $field ) )
List<$field.to> ${field.name} = new ArrayList<>();
#end
#end
#if ( $needXmlContext )
context.addLast( ${classLcapName} );
#end
while ((strict ? parser.nextTag() : nextTag(parser)) == XMLStreamReader.START_ELEMENT) {
String childName = checkDuplicate(parser.getLocalName(), parser, parsed);
#if ( $locationTracking )
int line = addLocationInformation ? parser.getLocation().getLineNumber() : -1;
int column = addLocationInformation ? parser.getLocation().getColumnNumber() : -1;
Map<Object, InputLocation> locations = null;
#end
switch (childName) {
#set( $ift = "if" )
#foreach ( $field in $allFields )
#if ( ! $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).transient && ! $Helper.xmlFieldMetadata( $field ).format )
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
#if ( ! $fieldTagName )
#set ( $fieldTagName = $field.name )
#end
#if ( $Helper.isFlatItems( $field ) )
#set ( $fieldTagName = $Helper.singular( $fieldTagName ) )
#end
#set ( $fieldCapName = $Helper.capitalise($field.name))
case "${fieldTagName}": {
#if ( $field.type == "String" )
${classLcapName}.${field.name}(interpolatedTrimmed(nextText(parser, strict), "${fieldTagName}"));
break;
#elseif ( $field.type == "boolean" || $field.type == "Boolean" )
${classLcapName}.${field.name}(getBooleanValue(interpolatedTrimmed(nextText(parser, strict), "${fieldTagName}"), "${fieldTagName}", parser, ${field.defaultValue}));
break;
#elseif ( $field.type == "int" )
${classLcapName}.${field.name}(getIntegerValue(interpolatedTrimmed(nextText(parser, strict), "${fieldTagName}"), "${fieldTagName}", parser, strict, ${field.defaultValue}));
break;
#elseif ( $field.type == "DOM" )
#if ( $locationTracking )
${classLcapName}.${field.name}(buildXmlNode(parser, source));
#else
${classLcapName}.${field.name}(buildXmlNode(parser));
#end
break;
#elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
List<String> ${field.name} = new ArrayList<>();
#if ( $locationTracking )
locations = new HashMap<>();
#end
while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
if ("${Helper.singular($fieldTagName)}".equals(parser.getLocalName())) {
#if ( $locationTracking )
if (addLocationInformation) {
locations.put(Integer.valueOf(locations.size()), new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source));
}
#end
${field.name}.add(interpolatedTrimmed(nextText(parser, strict), "${fieldTagName}"));
} else {
checkUnknownElement(parser, strict);
}
}
${classLcapName}.${field.name}(${field.name});
break;
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Map<String, String> ${field.name} = new LinkedHashMap<>();
#if ( $locationTracking )
locations = new HashMap<>();
#end
while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
String key = parser.getLocalName();
String value = nextText(parser, strict).trim();
#if ( $locationTracking )
if (addLocationInformation) {
locations.put(key, new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source));
}
#end
${field.name}.put(key, value);
}
${classLcapName}.${field.name}(${field.name});
break;
#elseif ( $field.to && $field.multiplicity == "1" )
#if ( $locationTracking )
${classLcapName}.${field.name}(parse${field.toClass.name}(parser, strict, source));
#elseif ( $needXmlContext )
${classLcapName}.${field.name}(parse${field.toClass.name}(parser, strict, context));
#else
${classLcapName}.${field.name}(parse${field.toClass.name}(parser, strict));
#end
break;
#elseif ( $field.to && $field.multiplicity == "*" && $Helper.isFlatItems( $field ) )
${field.name}.add(parse${field.toClass.name}(parser, strict));
break;
#elseif ( $field.to && $field.multiplicity == "*" )
List<$field.to> ${field.name} = new ArrayList<>();
while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
if ("${Helper.singular($fieldTagName)}".equals(parser.getLocalName())) {
#if ( $locationTracking )
${field.name}.add(parse${field.toClass.name}(parser, strict, source));
#elseif ( $needXmlContext )
${field.name}.add(parse${field.toClass.name}(parser, strict, context));
#else
${field.name}.add(parse${field.toClass.name}(parser, strict));
#end
} else {
checkUnknownElement(parser, strict);
}
}
${classLcapName}.${field.name}(${field.name});
break;
#else
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
break;
#end
}
#set( $ift = "else if" )
#end
#end
default: {
checkUnknownElement(parser, strict);
break;
}
}
#if ( $locationTracking )
if (addLocationInformation) {
${classLcapName}.location(childName, new InputLocation(line, column, source, locations));
}
#end
}
#if ( $needXmlContext )
context.removeLast();
#end
#foreach ( $field in $allFields )
#if ( $Helper.isFlatItems( $field ) )
${classLcapName}.${field.name}(${field.name});
#end
#end
#foreach ( $field in $allFields )
#if ( $Helper.xmlFieldMetadata( $field ).format )
${classLcapName}.${field.name}($Helper.xmlFieldMetadata( $field ).format);
#end
#end
#if ( $class == $root )
${classLcapName}.namespaceUri(parser.getNamespaceURI());
${classLcapName}.modelEncoding(parser.getEncoding());
#end
return ${classLcapName}.build();
}
#end
#end
private String checkDuplicate(String tagName, XMLStreamReader parser, Set<String> parsed) throws XMLStreamException {
#set( $aliases = { } )
#set( $flats = { } )
#foreach( $class in $model.allClasses )
#foreach ( $field in $class.getFields($version) )
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
#if ( ! $fieldTagName )
#set ( $fieldTagName = $field.name )
#end
#if ( $field.alias )
#set ( $dummy = $aliases.put( $field.alias, $fieldTagName ) )
#end
#if ( $Helper.isFlatItems( $field ) )
#set ( $fieldTagName = $Helper.singular($fieldTagName) )
#set ( $dummy = $flats.put( $fieldTagName, "" ) )
#end
#end
#end
#if ( ! ${aliases.isEmpty()} )
switch (tagName) {
#foreach( $entry in $aliases.entrySet() )
case "${entry.key}":
tagName = "${entry.value}";
break;
#end
}
#end
#if ( ! ${flats.isEmpty()} )
switch (tagName) {
#foreach( $entry in $flats.entrySet() )
case "${entry.key}":
#end
break;
default:
if (!parsed.add(tagName)) {
throw new XMLStreamException("Duplicated tag: '" + tagName + "'", parser.getLocation(), null);
}
}
#end
return tagName;
}
/**
* Method checkUnknownAttribute.
*
* @param parser a parser object.
* @param strict a strict object.
* @param tagName a tagName object.
* @param attribute a attribute object.
* @throws XMLStreamException XMLStreamException if
* any.
* @throws IOException IOException if any.
*/
private void checkUnknownAttribute(XMLStreamReader parser, String attribute, String tagName, boolean strict) throws XMLStreamException {
// strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
if (strict) {
throw new XMLStreamException("Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser.getLocation(), null);
}
} //-- void checkUnknownAttribute(XMLStreamReader, String, String, boolean)
/**
* Method checkUnknownElement.
*
* @param parser a parser object.
* @param strict a strict object.
* @throws XMLStreamException XMLStreamException if
* any.
* @throws IOException IOException if any.
*/
private void checkUnknownElement(XMLStreamReader parser, boolean strict) throws XMLStreamException {
if (strict) {
throw new XMLStreamException("Unrecognised tag: '" + parser.getName() + "'", parser.getLocation(), null);
}
for (int unrecognizedTagCount = 1; unrecognizedTagCount > 0;) {
int eventType = nextTag(parser);
if (eventType == XMLStreamReader.START_ELEMENT) {
unrecognizedTagCount++;
} else if (eventType == XMLStreamReader.END_ELEMENT) {
unrecognizedTagCount--;
}
}
} //-- void checkUnknownElement(XMLStreamReader, boolean)
/**
* Method getTrimmedValue.
*
* @param s a s object.
* @return String
*/
private String getTrimmedValue(String s) {
if (s != null) {
s = s.trim();
}
return s;
} //-- String getTrimmedValue(String)
/**
* Method interpolatedTrimmed.
*
* @param value a value object.
* @param context a context object.
* @return String
*/
private String interpolatedTrimmed(String value, String context) {
return getTrimmedValue(contentTransformer.transform(value, context));
} //-- String interpolatedTrimmed(String, String)
/**
* Method nextTag.
*
* @param parser a parser object.
* @throws IOException IOException if any.
* @throws XMLStreamException XMLStreamException if
* any.
* @return int
*/
private int nextTag(XMLStreamReader parser) throws XMLStreamException {
while (true) {
int next = parser.next();
switch (next) {
case XMLStreamReader.SPACE:
case XMLStreamReader.COMMENT:
case XMLStreamReader.PROCESSING_INSTRUCTION:
case XMLStreamReader.CDATA:
case XMLStreamReader.CHARACTERS:
continue;
case XMLStreamReader.START_ELEMENT:
case XMLStreamReader.END_ELEMENT:
return next;
}
}
} //-- int nextTag(XMLStreamReader)
private String nextText(XMLStreamReader parser, boolean strict) throws XMLStreamException {
int eventType = parser.getEventType();
if (eventType != XMLStreamReader.START_ELEMENT) {
throw new XMLStreamException("parser must be on START_ELEMENT to read next text", parser.getLocation(), null);
}
eventType = parser.next();
StringBuilder result = new StringBuilder();
while (true) {
if (eventType == XMLStreamReader.CHARACTERS || eventType == XMLStreamReader.CDATA) {
result.append(parser.getText());
} else if (eventType == XMLStreamReader.ENTITY_REFERENCE) {
String val = null;
if (strict) {
throw new XMLStreamException("Entities are not supported in strict mode", parser.getLocation(), null);
} else if (addDefaultEntities) {
val = DEFAULT_ENTITIES.get(parser.getLocalName());
}
if (val != null) {
result.append(val);
} else {
result.append("&").append(parser.getLocalName()).append(";");
}
} else if (eventType != XMLStreamReader.COMMENT) {
break;
}
eventType = parser.next();
}
if (eventType != XMLStreamReader.END_ELEMENT) {
throw new XMLStreamException(
"TEXT must be immediately followed by END_ELEMENT and not " + eventType /*TODO: TYPES[eventType]*/, parser.getLocation(), null);
}
return result.toString();
}
#if ( $locationTracking )
private XmlNode buildXmlNode(XMLStreamReader parser, InputSource source) throws XMLStreamException {
return XmlNodeBuilder.build(parser,
addLocationInformation
? p -> new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source)
: null);
}
#else
private XmlNode buildXmlNode(XMLStreamReader parser) throws XMLStreamException {
return XmlNodeBuilder.build(parser);
}
#end
#foreach ( $class in $model.allClasses )
#foreach ( $field in $class.getFields($version) )
#if ( $field.type == "boolean" || $field.type == "Boolean" )
#set ( $hasBooleanField = true )
#elseif ( $field.type == "int" || $field.type == "Integer" )
#set ( $hasIntegerField = true )
#end
#end
#end
#if ( $hasBooleanField )
/**
* Method getBooleanValue.
*
* @param s a s object.
* @param defaultValue a defaultValue object.
* @param parser a parser object.
* @param attribute a attribute object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return boolean
*/
private boolean getBooleanValue(String s, String attribute, XMLStreamReader parser, boolean defaultValue) throws XMLStreamException {
if (s != null && s.length() != 0) {
return Boolean.valueOf(s).booleanValue();
}
return defaultValue;
} //-- boolean getBooleanValue(String, String, XMLStreamReader, String)
#end
#if ( $hasIntegerField )
/**
* Method getIntegerValue.
*
* @param s a s object.
* @param strict a strict object.
* @param parser a parser object.
* @param attribute a attribute object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return int
*/
private int getIntegerValue(String s, String attribute, XMLStreamReader parser, boolean strict, int defaultValue) throws XMLStreamException {
if (s != null) {
try {
return Integer.valueOf(s).intValue();
} catch (NumberFormatException nfe) {
if (strict) {
throw new XMLStreamException("Unable to parse element '" + attribute + "', must be an integer", parser.getLocation(), nfe);
}
}
}
return defaultValue;
} //-- int getIntegerValue(String, String, XMLStreamReader, boolean)
#end
public static interface ContentTransformer {
/**
* Interpolate the value read from the xpp3 document
* @param source The source value
* @param fieldName A description of the field being interpolated. The implementation may use this to
* log stuff.
* @return The interpolated value.
*/
String transform(String source, String fieldName);
}
}