From f08db756e0d291af4ac3ed8e3eaade63c214481e Mon Sep 17 00:00:00 2001 From: rbeninga Date: Tue, 28 Nov 2023 10:41:37 +0100 Subject: [PATCH] Fixes a serious problem which completely messed up getters and setters in case there are an attribute and element with same name in the schema: SchemaTypeCodePrinter.java#printStaticFields writes an array named PROPERTY_QNAME. It depends on the supplied argument Map qnameMap. But QName is not unique. If there is an attribute and element with same name, the second replaces the first when the Map is filled although the index is incremented for each of them. So, indices of all subsequent members are pointing to the wrong entry. Now SchemaProperty is used as key for above map instead of QName. SchemaProperty instances are unique. --- .../impl/schema/SchemaTypeCodePrinter.java | 59 +++++++++++-------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java index d884e3659..81f87645f 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java @@ -1415,16 +1415,7 @@ void printJSetValue(int javaType, String safeVarName, SchemaTypeImpl stype) thro emit(em.replace("#VARNAME#", safeVarName) + ";"); } - String getIdentifier(Map qnameMap, QName qName) { - return "PROPERTY_QNAME[" + qnameMap.get(qName) + "]"; - } - - String getSetIdentifier(Map qnameMap, QName qName, Map qsetMap) { - Integer ord = qsetMap.get(qName); - return ord == null ? getIdentifier(qnameMap, qName) : "PROPERTY_QSET["+ ord + "]"; - } - - void printStaticFields(SchemaProperty[] properties, Map qnameMap, Map qsetMap) throws IOException { + void printStaticFields(SchemaProperty[] properties, Map propMap) throws IOException { if (properties.length == 0) { return; } @@ -1435,7 +1426,7 @@ void printStaticFields(SchemaProperty[] properties, Map qnameMap indent(); for (SchemaProperty prop : properties) { final QName name = prop.getName(); - qnameMap.put(name, qnameMap.size()); + propMap.put(prop, new Identifier(propMap.size())); emit("new QName(\"" + name.getNamespaceURI() + "\", \"" + name.getLocalPart() + "\"),"); countQSet = Math.max(countQSet, (prop.acceptedNames() == null ? 0 : prop.acceptedNames().length)); } @@ -1446,10 +1437,10 @@ void printStaticFields(SchemaProperty[] properties, Map qnameMap if (countQSet > 1) { emit("private static final QNameSet[] PROPERTY_QSET = {"); for (SchemaProperty prop : properties) { - final QName name = prop.getName(); final QName[] qnames = prop.acceptedNames(); + int index = 0; if (qnames != null && qnames.length > 1) { - qsetMap.put(name, qsetMap.size()); + propMap.get(prop).setSetIndex(index++); emit("QNameSet.forArray( new QName[] { "); indent(); for (QName qname : qnames) { @@ -1638,11 +1629,11 @@ void printListGetterImpl(String propdesc, String propertyName, String wrappedTyp endBlock(); } - void printGetterImpls(SchemaProperty prop, Map qnameMap, Map qsetMap) + void printGetterImpls(SchemaProperty prop, Map propMap) throws IOException { final QName qName = prop.getName(); - final String identifier = getIdentifier(qnameMap, qName); - final String setIdentifier = getSetIdentifier(qnameMap, qName, qsetMap); + final String identifier = propMap.get(prop).getIdentifier(); + final String setIdentifier = propMap.get(prop).getSetIdentifier(); final boolean several = prop.extendsJavaArray(); final boolean nillable = prop.hasNillable() != SchemaProperty.NEVER; final String type = javaTypeForProperty(prop); @@ -1859,11 +1850,11 @@ void printGetterImpls(SchemaProperty prop, Map qnameMap, Map qnameMap, Map qsetMap, SchemaType sType) + void printSetterImpls(SchemaProperty prop, Map propMap, SchemaType sType) throws IOException { final QName qName = prop.getName(); - final String identifier = getIdentifier(qnameMap, qName); - final String setIdentifier = getSetIdentifier(qnameMap, qName, qsetMap); + final String identifier = propMap.get(prop).getIdentifier(); + final String setIdentifier = propMap.get(prop).getSetIdentifier(); final boolean several = prop.extendsJavaArray(); final boolean nillable = prop.hasNillable() != SchemaProperty.NEVER; final String type = javaTypeForProperty(prop); @@ -2277,15 +2268,14 @@ void printInnerTypeImpl( if (!sType.isSimpleType()) { SchemaProperty[] properties = getSchemaProperties(sType); - Map qnameMap = new HashMap<>(); - Map qsetMap = new HashMap<>(); - printStaticFields(properties, qnameMap, qsetMap); + Map propMap = new HashMap<>(); + printStaticFields(properties, propMap); for (SchemaProperty prop : properties) { - printGetterImpls(prop, qnameMap, qsetMap); + printGetterImpls(prop, propMap); if (!prop.isReadOnly()) { - printSetterImpls(prop, qnameMap, qsetMap, sType); + printSetterImpls(prop, propMap, sType); } } } @@ -2441,4 +2431,25 @@ public void printHolder(Writer writer, SchemaTypeSystem system, XmlOptions opt, outdent(); emit("}"); } + + private static class Identifier { + private final int getindex; + private Integer setindex = null; + + private Identifier(int index) { + this.getindex = index; + } + + public String getIdentifier() { + return "PROPERTY_QNAME[" + getindex + "]"; + } + + public String getSetIdentifier() { + return setindex == null ? getIdentifier() : "PROPERTY_QSET["+ setindex + "]"; + } + + public void setSetIndex(int setindex) { + this.setindex = setindex; + } + } }