diff options
34 files changed, 589 insertions, 74 deletions
diff --git a/build/xsdc.go b/build/xsdc.go index d336b53..0546ec4 100644 --- a/build/xsdc.go +++ b/build/xsdc.go @@ -52,6 +52,11 @@ var ( CommandDeps: []string{"${xsdcCmd}", "${config.SoongZipCmd}"}, Description: "xsdc C++ ${in} => ${out}", }, "pkgName", "outDir") + + xsdConfigRule = pctx.StaticRule("xsdConfigRule", blueprint.RuleParams{ + Command: "cp -f ${in} ${output}", + Description: "copy the xsd file: ${in} => ${output}", + }, "output") ) type xsdConfigProperties struct { @@ -71,8 +76,13 @@ type xsdConfig struct { genOutputs_h android.WritablePath docsPath android.Path + + xsdConfigPath android.OptionalPath + genOutputs android.Paths } +var _ android.SourceFileProducer = (*xsdConfig)(nil) + type ApiToCheck struct { Api_file *string Removed_api_file *string @@ -99,7 +109,7 @@ func (module *xsdConfig) GeneratedSourceFiles() android.Paths { } func (module *xsdConfig) Srcs() android.Paths { - return android.Paths{module.genOutputs_j} + return append(module.genOutputs, module.genOutputs_j) } func (module *xsdConfig) GeneratedDeps() android.Paths { @@ -114,6 +124,24 @@ func (module *xsdConfig) DepsMutator(ctx android.BottomUpMutatorContext) { android.ExtractSourcesDeps(ctx, module.properties.Srcs) } +func (module *xsdConfig) generateXsdConfig(ctx android.ModuleContext) { + if !module.xsdConfigPath.Valid() { + return + } + + output := android.PathForModuleGen(ctx, module.Name()+".xsd") + module.genOutputs = append(module.genOutputs, output) + + ctx.ModuleBuild(pctx, android.ModuleBuildParams{ + Rule: xsdConfigRule, + Input: module.xsdConfigPath.Path(), + Output: output, + Args: map[string]string{ + "output": output.String(), + }, + }) +} + func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) { if len(module.properties.Srcs) != 1 { ctx.PropertyErrorf("srcs", "xsd_config must be one src") @@ -129,8 +157,9 @@ func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) xsdFile := srcFiles[0] pkgName := *module.properties.Package_name + filenameStem := strings.Replace(pkgName, ".", "_", -1) - module.genOutputs_j = android.PathForModuleGen(ctx, "java", "xsdcgen.srcjar") + module.genOutputs_j = android.PathForModuleGen(ctx, "java", filenameStem+"_xsdcgen.srcjar") ctx.Build(pctx, android.BuildParams{ Rule: xsdcJavaRule, @@ -143,9 +172,8 @@ func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) }, }) - pkgName = strings.Replace(pkgName, ".", "_", -1) - module.genOutputs_c = android.PathForModuleGen(ctx, "cpp", pkgName+".cpp") - module.genOutputs_h = android.PathForModuleGen(ctx, "cpp", "include/"+pkgName+".h") + module.genOutputs_c = android.PathForModuleGen(ctx, "cpp", filenameStem+".cpp") + module.genOutputs_h = android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+".h") module.genOutputDir = android.PathForModuleGen(ctx, "cpp", "include") ctx.Build(pctx, android.BuildParams{ @@ -160,6 +188,8 @@ func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) "outDir": android.PathForModuleGen(ctx, "cpp").String(), }, }) + module.xsdConfigPath = android.ExistentPathForSource(ctx, xsdFile.String()) + module.generateXsdConfig(ctx) } func xsdConfigMutator(mctx android.TopDownMutatorContext) { diff --git a/src/com/android/xsdc/Main.java b/src/com/android/xsdc/Main.java index b0fe084..b8f6dd3 100644 --- a/src/com/android/xsdc/Main.java +++ b/src/com/android/xsdc/Main.java @@ -105,8 +105,7 @@ public class Main { File includeDir = new File(Paths.get(outDir, "include").toString()); includeDir.mkdirs(); FileSystem fs = new FileSystem(new File(outDir)); - CppCodeGenerator cppCodeGenerator = new CppCodeGenerator(xmlSchema, - packageName.replace(".", "_")); + CppCodeGenerator cppCodeGenerator = new CppCodeGenerator(xmlSchema, packageName); cppCodeGenerator.print(fs); } } diff --git a/src/com/android/xsdc/XmlSchema.java b/src/com/android/xsdc/XmlSchema.java index bcc862b..a941791 100644 --- a/src/com/android/xsdc/XmlSchema.java +++ b/src/com/android/xsdc/XmlSchema.java @@ -25,12 +25,18 @@ public class XmlSchema { final private Map<String, XsdElement> elementMap; final private Map<String, XsdType> typeMap; final private Map<String, XsdAttribute> attributeMap; + final private Map<String, XsdAttributeGroup> attributeGroupMap; + final private Map<String, XsdGroup> groupMap; XmlSchema(Map<String, XsdElement> elementMap, Map<String, XsdType> typeMap, - Map<String, XsdAttribute> attributeMap) { + Map<String, XsdAttribute> attributeMap, + Map<String, XsdAttributeGroup> attributeGroupMap, + Map<String, XsdGroup> groupMap) { this.elementMap = Collections.unmodifiableMap(elementMap); this.typeMap = Collections.unmodifiableMap(typeMap); this.attributeMap = Collections.unmodifiableMap(attributeMap); + this.attributeGroupMap = Collections.unmodifiableMap(attributeGroupMap); + this.groupMap = Collections.unmodifiableMap(groupMap); } public Map<String, XsdElement> getElementMap() { @@ -44,4 +50,12 @@ public class XmlSchema { public Map<String, XsdAttribute> getAttributeMap() { return attributeMap; } + + public Map<String, XsdAttributeGroup> getAttributeGroupMap() { + return attributeGroupMap; + } + + public Map<String, XsdGroup> getGroupMap() { + return groupMap; + } } diff --git a/src/com/android/xsdc/XsdHandler.java b/src/com/android/xsdc/XsdHandler.java index 7737e37..0bb2f83 100644 --- a/src/com/android/xsdc/XsdHandler.java +++ b/src/com/android/xsdc/XsdHandler.java @@ -55,12 +55,14 @@ public class XsdHandler extends DefaultHandler { private Locator locator; private boolean documentationFlag; private boolean enumerationFlag; + private List<XsdTag> enumTags; public XsdHandler() { stateStack = new Stack<>(); namespaces = new HashMap<>(); documentationFlag = false; enumerationFlag = false; + enumTags = new ArrayList<>(); } public XmlSchema getSchema() { @@ -136,6 +138,9 @@ public class XsdHandler extends DefaultHandler { case "attribute": stateStack.peek().tags.add(makeAttribute(state)); break; + case "attributeGroup": + stateStack.peek().tags.add(makeAttributeGroup(state)); + break; case "complexType": stateStack.peek().tags.add(makeComplexType(state)); break; @@ -178,6 +183,9 @@ public class XsdHandler extends DefaultHandler { stateStack.peek().tags.add(makeEnumeration(state)); enumerationFlag = true; break; + case "group": + stateStack.peek().tags.add(makeGroup(state)); + break; case "fractionDigits": case "length": case "maxExclusive": @@ -223,19 +231,26 @@ public class XsdHandler extends DefaultHandler { Map<String, XsdElement> elementMap = new LinkedHashMap<>(); Map<String, XsdType> typeMap = new LinkedHashMap<>(); Map<String, XsdAttribute> attrMap = new LinkedHashMap<>(); + Map<String, XsdAttributeGroup> attrGroupMap = new LinkedHashMap<>(); + Map<String, XsdGroup> groupMap = new LinkedHashMap<>(); + state.tags.addAll(enumTags); for (XsdTag tag : state.tags) { if (tag == null) continue; if (tag instanceof XsdElement) { elementMap.put(tag.getName(), (XsdElement) tag); } else if (tag instanceof XsdAttribute) { attrMap.put(tag.getName(), (XsdAttribute) tag); + } else if (tag instanceof XsdAttributeGroup) { + attrGroupMap.put(tag.getName(), (XsdAttributeGroup) tag); } else if (tag instanceof XsdType) { typeMap.put(tag.getName(), (XsdType) tag); + } else if (tag instanceof XsdGroup) { + groupMap.put(tag.getName(), (XsdGroup) tag); } } - return new XmlSchema(elementMap, typeMap, attrMap); + return new XmlSchema(elementMap, typeMap, attrMap, attrGroupMap, groupMap); } private XsdElement makeElement(State state) throws XsdParserException { @@ -300,6 +315,42 @@ public class XsdHandler extends DefaultHandler { return setDeprecated(new XsdAttribute(name, ref, type), state.deprecated); } + private XsdAttributeGroup makeAttributeGroup(State state) throws XsdParserException { + String name = state.attributeMap.get("name"); + QName ref = parseQName(state.attributeMap.get("ref")); + + List<XsdAttribute> attributes = new ArrayList<>(); + List<XsdAttributeGroup> attributeGroups = new ArrayList<>(); + + for (XsdTag tag : state.tags) { + if (tag == null) continue; + if (tag instanceof XsdAttribute) { + attributes.add((XsdAttribute) tag); + } else if (tag instanceof XsdAttributeGroup) { + attributeGroups.add((XsdAttributeGroup) tag); + } + } + + return setDeprecated(new XsdAttributeGroup(name, ref, attributes, attributeGroups), + state.deprecated); + } + + private XsdGroup makeGroup(State state) throws XsdParserException { + String name = state.attributeMap.get("name"); + QName ref = parseQName(state.attributeMap.get("ref")); + + List<XsdElement> elements = new ArrayList<>(); + + for (XsdTag tag: state.tags) { + if (tag == null) continue; + if (tag instanceof XsdElement) { + elements.add((XsdElement) tag); + } + } + + return setDeprecated(new XsdGroup(name, ref, elements), state.deprecated); + } + private XsdComplexType makeComplexType(State state) throws XsdParserException { String name = state.attributeMap.get("name"); String isAbstract = state.attributeMap.get("abstract"); @@ -313,19 +364,26 @@ public class XsdHandler extends DefaultHandler { } List<XsdAttribute> attributes = new ArrayList<>(); + List<XsdAttributeGroup> attributeGroups = new ArrayList<>(); List<XsdElement> elements = new ArrayList<>(); XsdComplexType type = null; + XsdGroup group = null; for (XsdTag tag : state.tags) { if (tag == null) continue; if (tag instanceof XsdAttribute) { attributes.add((XsdAttribute) tag); + } else if (tag instanceof XsdAttributeGroup) { + attributeGroups.add((XsdAttributeGroup) tag); + } else if (tag instanceof XsdGroup) { + group = (XsdGroup) tag; } else if (tag instanceof XsdElement) { elements.add((XsdElement) tag); } else if (tag instanceof XsdComplexContent) { XsdComplexContent child = (XsdComplexContent) tag; type = setDeprecated(new XsdComplexContent(name, child.getBase(), - child.getAttributes(), child.getElements()), state.deprecated); + child.getAttributes(), child.getAttributeGroups(), + child.getElements(), child.getGroup()), state.deprecated); } else if (tag instanceof XsdSimpleContent) { XsdSimpleContent child = (XsdSimpleContent) tag; type = setDeprecated(new XsdSimpleContent(name, child.getBase(), @@ -334,7 +392,7 @@ public class XsdHandler extends DefaultHandler { } return (type != null) ? type : setDeprecated(new XsdComplexContent(name, null, attributes, - elements), state.deprecated); + attributeGroups, elements, group), state.deprecated); } private XsdComplexContent makeComplexContent(State state) throws XsdParserException { @@ -349,7 +407,8 @@ public class XsdHandler extends DefaultHandler { if (tag instanceof XsdGeneralExtension) { XsdGeneralExtension extension = (XsdGeneralExtension) tag; content = new XsdComplexContent(null, extension.getBase(), - extension.getAttributes(), extension.getElements()); + extension.getAttributes(), extension.getAttributeGroups(), + extension.getElements(), extension.getGroup()); } else if (tag instanceof XsdGeneralRestriction) { XsdGeneralRestriction restriction = (XsdGeneralRestriction) tag; XsdType base = restriction.getBase(); @@ -357,10 +416,11 @@ public class XsdHandler extends DefaultHandler { XsdConstants.XSD_NAMESPACE)) { // restriction of base 'xsd:anyType' is equal to complex content definition content = new XsdComplexContent(null, null, restriction.getAttributes(), - restriction.getElements()); + restriction.getAttributeGroups(), restriction.getElements(), + restriction.getGroup()); } else { // otherwise ignore restrictions - content = new XsdComplexContent(null, base, null, null); + content = new XsdComplexContent(null, base, null, null, null, null); } } } @@ -394,35 +454,47 @@ public class XsdHandler extends DefaultHandler { type = new XsdType(null, base); } List<XsdAttribute> attributes = new ArrayList<>(); + List<XsdAttributeGroup> attributeGroups = new ArrayList<>(); List<XsdElement> elements = new ArrayList<>(); + XsdGroup group = null; for (XsdTag tag : state.tags) { if (tag == null) continue; if (tag instanceof XsdAttribute) { attributes.add((XsdAttribute) tag); + } else if (tag instanceof XsdAttributeGroup) { + attributeGroups.add((XsdAttributeGroup) tag); } else if (tag instanceof XsdElement) { elements.add((XsdElement) tag); + } else if (tag instanceof XsdGroup) { + group = (XsdGroup) tag; } } - return setDeprecated(new XsdGeneralRestriction(type, attributes, elements), - state.deprecated); + return setDeprecated(new XsdGeneralRestriction(type, attributes, attributeGroups, + elements, group), state.deprecated); } private XsdGeneralExtension makeGeneralExtension(State state) throws XsdParserException { QName base = parseQName(state.attributeMap.get("base")); List<XsdAttribute> attributes = new ArrayList<>(); + List<XsdAttributeGroup> attributeGroups = new ArrayList<>(); List<XsdElement> elements = new ArrayList<>(); + XsdGroup group = null; for (XsdTag tag : state.tags) { if (tag == null) continue; if (tag instanceof XsdAttribute) { attributes.add((XsdAttribute) tag); + } else if (tag instanceof XsdAttributeGroup) { + attributeGroups.add((XsdAttributeGroup) tag); } else if (tag instanceof XsdElement) { elements.add((XsdElement) tag); + } else if (tag instanceof XsdGroup) { + group = (XsdGroup) tag; } } - return setDeprecated(new XsdGeneralExtension(new XsdType(null, base), attributes, elements), - state.deprecated); + return setDeprecated(new XsdGeneralExtension(new XsdType(null, base), attributes, + attributeGroups, elements, group), state.deprecated); } private XsdSimpleType makeSimpleType(State state) throws XsdParserException { @@ -435,8 +507,13 @@ public class XsdHandler extends DefaultHandler { } else if (tag instanceof XsdGeneralRestriction) { type = new XsdRestriction(name, ((XsdGeneralRestriction) tag).getBase(), null); } else if (tag instanceof XsdEnumRestriction) { + if (name == null) { + throw new XsdParserException( + "The name of simpleType for enumeration must be set."); + } type = new XsdRestriction(name, ((XsdEnumRestriction) tag).getBase(), ((XsdEnumRestriction) tag).getEnums()); + enumTags.add(type); } else if (tag instanceof XsdUnion) { type = new XsdUnion(name, ((XsdUnion) tag).getMemberTypes()); } @@ -475,7 +552,7 @@ public class XsdHandler extends DefaultHandler { return setDeprecated(new XsdUnion(null, memberTypes), state.deprecated); } - private static List<XsdElement> makeSequence(State state) throws XsdParserException { + private static List<XsdTag> makeSequence(State state) throws XsdParserException { String minOccurs = state.attributeMap.get("minOccurs"); String maxOccurs = state.attributeMap.get("maxOccurs"); @@ -484,7 +561,7 @@ public class XsdHandler extends DefaultHandler { "minOccurs, maxOccurs options of a sequence is not supported"); } - List<XsdElement> elements = new ArrayList<>(); + List<XsdTag> elementsAndGroup = new ArrayList<>(); for (XsdTag tag : state.tags) { if (tag == null) continue; if (tag instanceof XsdElement) { @@ -492,15 +569,17 @@ public class XsdHandler extends DefaultHandler { || Integer.parseInt(maxOccurs) > 1)) { ((XsdElement)tag).setMultiple(true); } - elements.add((XsdElement) tag); + elementsAndGroup.add(tag); + } else if (tag instanceof XsdGroup) { + elementsAndGroup.add(tag); } } - return elements; + return elementsAndGroup; } - private static List<XsdElement> makeChoice(State state) throws XsdParserException { + private static List<XsdTag> makeChoice(State state) throws XsdParserException { String maxOccurs = state.attributeMap.get("maxOccurs"); - List<XsdElement> elements = new ArrayList<>(); + List<XsdTag> elementsAndGroup = new ArrayList<>(); for (XsdTag tag : state.tags) { if (tag == null) continue; @@ -510,11 +589,14 @@ public class XsdHandler extends DefaultHandler { ((XsdElement)tag).setMultiple(true); } XsdElement element = (XsdElement)tag; - elements.add(setDeprecated(new XsdChoice(element.getName(), element.getRef(), - element.getType(), element.isMultiple()), element.isDeprecated())); + elementsAndGroup.add((XsdTag) setDeprecated(new XsdChoice(element.getName(), + element.getRef(), element.getType(), element.isMultiple()), + element.isDeprecated())); + } else if (tag instanceof XsdGroup) { + elementsAndGroup.add(tag); } } - return elements; + return elementsAndGroup; } private static List<XsdElement> makeAll(State state) throws XsdParserException { diff --git a/src/com/android/xsdc/cpp/CppCodeGenerator.java b/src/com/android/xsdc/cpp/CppCodeGenerator.java index 7a2ca5a..f7ef86b 100644 --- a/src/com/android/xsdc/cpp/CppCodeGenerator.java +++ b/src/com/android/xsdc/cpp/CppCodeGenerator.java @@ -35,16 +35,16 @@ import javax.xml.namespace.QName; public class CppCodeGenerator { private XmlSchema xmlSchema; - private String fileName; + private String pkgName; private Map<String, CppSimpleType> cppSimpleTypeMap; private CodeWriter cppFile; private CodeWriter headerFile; private boolean hasAttr; - public CppCodeGenerator(XmlSchema xmlSchema, String fileName) + public CppCodeGenerator(XmlSchema xmlSchema, String pkgName) throws CppCodeGeneratorException { this.xmlSchema = xmlSchema; - this.fileName = fileName; + this.pkgName = pkgName; // class naming validation { @@ -92,11 +92,14 @@ public class CppCodeGenerator { public void print(FileSystem fs) throws CppCodeGeneratorException, IOException { // cpp file, headr file init - cppFile = new CodeWriter(fs.getPrintWriter(fileName + ".cpp")); - headerFile = new CodeWriter(fs.getPrintWriter("include/" + fileName + ".h")); - - headerFile.printf("#ifndef %s_H\n", fileName.toUpperCase()); - headerFile.printf("#define %s_H\n\n", fileName.toUpperCase()); + String cppFileName = pkgName.replace(".", "_") + ".cpp"; + String hFileName = pkgName.replace(".", "_") + ".h"; + cppFile = new CodeWriter(fs.getPrintWriter(cppFileName)); + headerFile = new CodeWriter(fs.getPrintWriter("include/" + hFileName)); + + String headerMacro = hFileName.toUpperCase().replace(".", "_"); + headerFile.printf("#ifndef %s\n", headerMacro); + headerFile.printf("#define %s\n\n", headerMacro); headerFile.printf("#include <libxml/parser.h>\n"); headerFile.printf("#include <libxml/xinclude.h>\n\n"); headerFile.printf("#include <map>\n"); @@ -104,15 +107,21 @@ public class CppCodeGenerator { headerFile.printf("#include <string>\n"); headerFile.printf("#include <vector>\n\n"); - cppFile.printf("#define LOG_TAG \"%s\"\n\n", fileName); + cppFile.printf("#define LOG_TAG \"%s\"\n\n", pkgName); cppFile.printf("#include <android/log.h>\n"); cppFile.printf("#include <android-base/strings.h>\n\n"); cppFile.printf("#include <libxml/parser.h>\n"); cppFile.printf("#include <libxml/xinclude.h>\n\n"); - cppFile.printf("#include \"%s.h\"\n\n",fileName); + cppFile.printf("#include \"%s\"\n\n", hFileName); List<String> namespace = new java.util.ArrayList<>(); - for (String token : fileName.split("_")) { + for (String token : pkgName.split("\\.")) { + if (token.isEmpty()) { + continue; + } + if (Character.isDigit(token.charAt(0))) { + token = "_" + token; + } namespace.add(token); headerFile.printf("namespace %s {\n", token); cppFile.printf("namespace %s {\n", token); @@ -148,7 +157,7 @@ public class CppCodeGenerator { cppFile.printf("} // %s\n", token); } - headerFile.printf("#endif // %s_H\n",fileName.toUpperCase().replace(".", "_")); + headerFile.printf("#endif // %s\n", headerMacro); cppFile.close(); headerFile.close(); } @@ -160,9 +169,13 @@ public class CppCodeGenerator { List<XsdEnumeration> enums = restrictionType.getEnums(); for (XsdEnumeration tag : enums) { - headerFile.printf("%s,\n", Utils.toEnumName(tag.getValue())); + String value = tag.getValue(); + if ("".equals(value)) { + value = "EMPTY"; + } + headerFile.printf("%s,\n", Utils.toEnumName(value)); cppFile.printf("{ \"%s\", %s::%s },\n", tag.getValue(), name, - Utils.toEnumName(tag.getValue())); + Utils.toEnumName(value)); } headerFile.printf("UNKNOWN\n};\n\n"); cppFile.printf("};\n\n"); @@ -209,7 +222,11 @@ public class CppCodeGenerator { // parse types for elements and attributes List<CppType> elementTypes = new ArrayList<>(); - for (XsdElement element : complexType.getElements()) { + List<XsdElement> elements = new ArrayList<>(); + elements.addAll(getAllElements(complexType.getGroup())); + elements.addAll(complexType.getElements()); + + for (XsdElement element : elements) { CppType cppType; XsdElement elementValue = resolveElement(element); if (element.getRef() == null && element.getType().getRef() == null @@ -227,7 +244,13 @@ public class CppCodeGenerator { elementTypes.add(cppType); } List<CppSimpleType> attributeTypes = new ArrayList<>(); - for (XsdAttribute attribute : complexType.getAttributes()) { + List<XsdAttribute> attributes = new ArrayList(); + for (XsdAttributeGroup attributeGroup : complexType.getAttributeGroups()) { + attributes.addAll(getAllAttributes(resolveAttributeGroup(attributeGroup))); + } + attributes.addAll(complexType.getAttributes()); + + for (XsdAttribute attribute : attributes) { XsdType type = resolveAttribute(attribute).getType(); attributeTypes.add(parseSimpleType(type, false)); } @@ -237,7 +260,7 @@ public class CppCodeGenerator { headerFile.printf("private:\n"); for (int i = 0; i < elementTypes.size(); ++i) { CppType type = elementTypes.get(i); - XsdElement element = complexType.getElements().get(i); + XsdElement element = elements.get(i); XsdElement elementValue = resolveElement(element); String typeName = element.isMultiple() || type instanceof CppComplexType ? String.format("std::vector<%s>", type.getName()) : type.getName(); @@ -246,7 +269,7 @@ public class CppCodeGenerator { } for (int i = 0; i < attributeTypes.size(); ++i) { CppType type = attributeTypes.get(i); - XsdAttribute attribute = resolveAttribute(complexType.getAttributes().get(i)); + XsdAttribute attribute = resolveAttribute(attributes.get(i)); headerFile.printf("%s %s;\n", type.getName(), Utils.toVariableName(attribute.getName())); } @@ -259,7 +282,7 @@ public class CppCodeGenerator { headerFile.printf("public:\n"); for (int i = 0; i < elementTypes.size(); ++i) { CppType type = elementTypes.get(i); - XsdElement element = complexType.getElements().get(i); + XsdElement element = elements.get(i); XsdElement elementValue = resolveElement(element); printGetterAndSetter(nameScope + name, type, Utils.toVariableName(getElementName(elementValue)), @@ -268,7 +291,7 @@ public class CppCodeGenerator { } for (int i = 0; i < attributeTypes.size(); ++i) { CppType type = attributeTypes.get(i); - XsdAttribute attribute = resolveAttribute(complexType.getAttributes().get(i)); + XsdAttribute attribute = resolveAttribute(attributes.get(i)); printGetterAndSetter(nameScope + name, type, Utils.toVariableName(attribute.getName()), false, false); } @@ -341,8 +364,8 @@ public class CppCodeGenerator { if (type instanceof CppSimpleType) { cppFile.printf("auto xmlValue = make_xmlUnique(xmlNodeListGetString("); cppFile.printf("child->doc, child->xmlChildrenNode, 1));\n"); - cppFile.printf("if (xmlValue == nullptr) {\ncontinue;\n}\n"); - cppFile.printf("raw = reinterpret_cast<const char*>(xmlValue.get());\n"); + cppFile.printf("if (xmlValue == nullptr) {\nraw = \"\";\n} else {\n"); + cppFile.printf("raw = reinterpret_cast<const char*>(xmlValue.get());\n}\n"); } cppFile.print(type.getParsingExpression()); @@ -436,7 +459,7 @@ public class CppCodeGenerator { + "}\n\n"); } - String className = Utils.toClassName(fileName); + String className = Utils.toClassName(pkgName); boolean isMultiRootElement = xmlSchema.getElementMap().values().size() > 1; for (XsdElement element : xmlSchema.getElementMap().values()) { @@ -494,10 +517,35 @@ public class CppCodeGenerator { } } } + elements.addAll(getAllElements(complexType.getGroup())); elements.addAll(complexType.getElements()); + for (XsdAttributeGroup attributeGroup : complexType.getAttributeGroups()) { + attributes.addAll(getAllAttributes(resolveAttributeGroup(attributeGroup))); + } attributes.addAll(complexType.getAttributes()); } + private List<XsdAttribute> getAllAttributes(XsdAttributeGroup attributeGroup) + throws CppCodeGeneratorException{ + List<XsdAttribute> attributes = new ArrayList<>(); + for (XsdAttributeGroup attrGroup : attributeGroup.getAttributeGroups()) { + attributes.addAll(getAllAttributes(resolveAttributeGroup(attrGroup))); + } + attributes.addAll(attributeGroup.getAttributes()); + return attributes; + } + + private List<XsdElement> getAllElements(XsdGroup group) throws CppCodeGeneratorException { + List<XsdElement> elements = new ArrayList<>(); + if (group == null) { + return elements; + } + elements.addAll(getAllElements(resolveGroup(group))); + elements.addAll(group.getElements()); + return elements; + } + + private String getBaseName(XsdComplexType complexType) throws CppCodeGeneratorException { if (complexType.getBase() == null) return null; if (complexType.getBase().getRef().getNamespaceURI().equals(XsdConstants.XSD_NAMESPACE)) { @@ -621,6 +669,14 @@ public class CppCodeGenerator { throw new CppCodeGeneratorException(String.format("no element named : %s", name)); } + private XsdGroup resolveGroup(XsdGroup group) throws CppCodeGeneratorException { + if (group.getRef() == null) return null; + String name = group.getRef().getLocalPart(); + XsdGroup ret = xmlSchema.getGroupMap().get(name); + if (ret != null) return ret; + throw new CppCodeGeneratorException(String.format("no group named : %s", name)); + } + private XsdAttribute resolveAttribute(XsdAttribute attribute) throws CppCodeGeneratorException { if (attribute.getRef() == null) return attribute; @@ -630,6 +686,15 @@ public class CppCodeGenerator { throw new CppCodeGeneratorException(String.format("no attribute named : %s", name)); } + private XsdAttributeGroup resolveAttributeGroup(XsdAttributeGroup attributeGroup) + throws CppCodeGeneratorException { + if (attributeGroup.getRef() == null) return attributeGroup; + String name = attributeGroup.getRef().getLocalPart(); + XsdAttributeGroup ret = xmlSchema.getAttributeGroupMap().get(name); + if (ret != null) return ret; + throw new CppCodeGeneratorException(String.format("no attribute group named : %s", name)); + } + private XsdType getType(String name) throws CppCodeGeneratorException { XsdType type = xmlSchema.getTypeMap().get(name); if (type != null) return type; @@ -643,7 +708,8 @@ public class CppCodeGenerator { } private boolean hasAttribute(XsdComplexType complexType) throws CppCodeGeneratorException { - if (complexType.getAttributes().size() > 0) { + if (complexType.getAttributes().size() > 0 || + complexType.getAttributeGroups().size() > 0) { return true; } boolean results = false; diff --git a/src/com/android/xsdc/cpp/Utils.java b/src/com/android/xsdc/cpp/Utils.java index b76a835..c612fc6 100644 --- a/src/com/android/xsdc/cpp/Utils.java +++ b/src/com/android/xsdc/cpp/Utils.java @@ -61,12 +61,12 @@ class Utils { String lowered = Character.isDigit(trimmed.charAt(0)) ? "_" + trimmed : lowerize(trimmed); // always starts with a lowercase or underscore character. - return (keywordSet.contains(trimmed)) ? "_" + lowered : lowered; + return (keywordSet.contains(lowered)) ? "_" + lowered : lowered; } static String toClassName(String name) throws CppCodeGeneratorException { String trimmed = toCamelCase( - name.replaceAll("[^A-Za-z0-9_-]", "").replaceAll("-","_").split("_")); + name.replaceAll("[^A-Za-z0-9_-]", "").replaceAll("[\\.-]", "_").split("_")); if (trimmed.isEmpty() || Character.isDigit(trimmed.charAt(0))) { throw new CppCodeGeneratorException( String.format("cannot convert to a class name : %s", name)); @@ -81,6 +81,6 @@ class Utils { String.format("cannot convert to a variable name : %s", name)); } String enumName = Character.isDigit(trimmed.charAt(0)) ? "_" + trimmed : trimmed; - return (keywordSet.contains(trimmed)) ? "_" + enumName : enumName; + return (keywordSet.contains(enumName)) ? "_" + enumName : enumName; } } diff --git a/src/com/android/xsdc/java/JavaCodeGenerator.java b/src/com/android/xsdc/java/JavaCodeGenerator.java index 29223c3..88a1141 100644 --- a/src/com/android/xsdc/java/JavaCodeGenerator.java +++ b/src/com/android/xsdc/java/JavaCodeGenerator.java @@ -127,7 +127,11 @@ public class JavaCodeGenerator { if (tag.isDeprecated()) { out.printf("@java.lang.Deprecated\n"); } - out.printf("\n%s(\"%s\"),", Utils.toEnumName(tag.getValue()), tag.getValue()); + String value = tag.getValue(); + if ("".equals(value)) { + value = "EMPTY"; + } + out.printf("\n%s(\"%s\"),", Utils.toEnumName(value), tag.getValue()); } out.printf(";\n\n"); out.printf("private final String rawName;\n\n"); @@ -165,7 +169,11 @@ public class JavaCodeGenerator { // parse types for elements and attributes List<JavaType> elementTypes = new ArrayList<>(); - for (XsdElement element : complexType.getElements()) { + List<XsdElement> elements = new ArrayList<>(); + elements.addAll(getAllElements(complexType.getGroup())); + elements.addAll(complexType.getElements()); + + for (XsdElement element : elements) { JavaType javaType; XsdElement elementValue = resolveElement(element); if (element.getRef() == null && element.getType().getRef() == null @@ -183,7 +191,13 @@ public class JavaCodeGenerator { elementTypes.add(javaType); } List<JavaSimpleType> attributeTypes = new ArrayList<>(); - for (XsdAttribute attribute : complexType.getAttributes()) { + List<XsdAttribute> attributes = new ArrayList<>(); + for (XsdAttributeGroup attributeGroup : complexType.getAttributeGroups()) { + attributes.addAll(getAllAttributes(resolveAttributeGroup(attributeGroup))); + } + attributes.addAll(complexType.getAttributes()); + + for (XsdAttribute attribute : attributes) { XsdType type = resolveAttribute(attribute).getType(); attributeTypes.add(parseSimpleType(type, false)); } @@ -191,7 +205,7 @@ public class JavaCodeGenerator { // print member variables for (int i = 0; i < elementTypes.size(); ++i) { JavaType type = elementTypes.get(i); - XsdElement element = complexType.getElements().get(i); + XsdElement element = elements.get(i); XsdElement elementValue = resolveElement(element); String typeName = element.isMultiple() ? String.format("java.util.List<%s>", type.getNullableName()) : type.getName(); @@ -200,7 +214,7 @@ public class JavaCodeGenerator { } for (int i = 0; i < attributeTypes.size(); ++i) { JavaType type = attributeTypes.get(i); - XsdAttribute attribute = resolveAttribute(complexType.getAttributes().get(i)); + XsdAttribute attribute = resolveAttribute(attributes.get(i)); out.printf("private %s %s;\n", type.getName(), Utils.toVariableName(attribute.getName())); } @@ -211,14 +225,14 @@ public class JavaCodeGenerator { // print getters and setters for (int i = 0; i < elementTypes.size(); ++i) { JavaType type = elementTypes.get(i); - XsdElement element = complexType.getElements().get(i); + XsdElement element = elements.get(i); XsdElement elementValue = resolveElement(element); printGetterAndSetter(out, type, Utils.toVariableName(getElementName(elementValue)), element.isMultiple(), element.isDeprecated()); } for (int i = 0; i < attributeTypes.size(); ++i) { JavaType type = attributeTypes.get(i); - XsdAttribute attribute = resolveAttribute(complexType.getAttributes().get(i)); + XsdAttribute attribute = resolveAttribute(attributes.get(i)); printGetterAndSetter(out, type, Utils.toVariableName(attribute.getName()), false, attribute.isDeprecated()); } @@ -277,7 +291,10 @@ public class JavaCodeGenerator { out.print("instance.setValue(value);\n" + "}\n"); } else if (!allElements.isEmpty()) { - out.print("while (parser.next() != org.xmlpull.v1.XmlPullParser.END_TAG) {\n" + out.print("int outerDepth = parser.getDepth();\n" + + "int type;\n" + + "while ((type=parser.next()) != org.xmlpull.v1.XmlPullParser.END_DOCUMENT\n" + + " && type != org.xmlpull.v1.XmlPullParser.END_TAG) {\n" + "if (parser.getEventType() != org.xmlpull.v1.XmlPullParser.START_TAG) " + "continue;\n" + "String tagName = parser.getName();\n"); @@ -304,6 +321,9 @@ public class JavaCodeGenerator { + "XmlParser.skip(parser);\n" + "}\n" + "}\n"); + out.printf("if (type != org.xmlpull.v1.XmlPullParser.END_TAG) {\n" + + "throw new javax.xml.datatype.DatatypeConfigurationException(\"%s is not closed\");\n" + + "}\n", name); } else { out.print("XmlParser.skip(parser);\n"); } @@ -425,10 +445,34 @@ public class JavaCodeGenerator { } } } + elements.addAll(getAllElements(complexType.getGroup())); elements.addAll(complexType.getElements()); + for (XsdAttributeGroup attributeGroup : complexType.getAttributeGroups()) { + attributes.addAll(getAllAttributes(resolveAttributeGroup(attributeGroup))); + } attributes.addAll(complexType.getAttributes()); } + private List<XsdAttribute> getAllAttributes(XsdAttributeGroup attributeGroup) + throws JavaCodeGeneratorException { + List<XsdAttribute> attributes = new ArrayList<>(); + for (XsdAttributeGroup attrGroup : attributeGroup.getAttributeGroups()) { + attributes.addAll(getAllAttributes(resolveAttributeGroup(attrGroup))); + } + attributes.addAll(attributeGroup.getAttributes()); + return attributes; + } + + private List<XsdElement> getAllElements(XsdGroup group) throws JavaCodeGeneratorException { + List<XsdElement> elements = new ArrayList<>(); + if (group == null) { + return elements; + } + elements.addAll(getAllElements(resolveGroup(group))); + elements.addAll(group.getElements()); + return elements; + } + private String getBaseName(XsdComplexType complexType) throws JavaCodeGeneratorException { if (complexType.getBase() == null) return null; if (complexType.getBase().getRef().getNamespaceURI().equals(XsdConstants.XSD_NAMESPACE)) { @@ -553,6 +597,14 @@ public class JavaCodeGenerator { throw new JavaCodeGeneratorException(String.format("no element named : %s", name)); } + private XsdGroup resolveGroup(XsdGroup group) throws JavaCodeGeneratorException { + if (group.getRef() == null) return null; + String name = group.getRef().getLocalPart(); + XsdGroup ret = xmlSchema.getGroupMap().get(name); + if (ret != null) return ret; + throw new JavaCodeGeneratorException(String.format("no group named : %s", name)); + } + private XsdAttribute resolveAttribute(XsdAttribute attribute) throws JavaCodeGeneratorException { if (attribute.getRef() == null) return attribute; @@ -562,6 +614,15 @@ public class JavaCodeGenerator { throw new JavaCodeGeneratorException(String.format("no attribute named : %s", name)); } + private XsdAttributeGroup resolveAttributeGroup(XsdAttributeGroup attributeGroup) + throws JavaCodeGeneratorException { + if (attributeGroup.getRef() == null) return attributeGroup; + String name = attributeGroup.getRef().getLocalPart(); + XsdAttributeGroup ret = xmlSchema.getAttributeGroupMap().get(name); + if (ret != null) return ret; + throw new JavaCodeGeneratorException(String.format("no attribute group named : %s", name)); + } + private XsdType getType(String name) throws JavaCodeGeneratorException { XsdType type = xmlSchema.getTypeMap().get(name); if (type != null) return type; diff --git a/src/com/android/xsdc/java/Utils.java b/src/com/android/xsdc/java/Utils.java index 673f0a3..4d825e9 100644 --- a/src/com/android/xsdc/java/Utils.java +++ b/src/com/android/xsdc/java/Utils.java @@ -58,7 +58,7 @@ class Utils { String lowered = Character.isDigit(trimmed.charAt(0)) ? "_" + trimmed : lowerize(trimmed); // always starts with a lowercase or underscore character. - return (keywordSet.contains(trimmed)) ? "_" + lowered : lowered; + return (keywordSet.contains(lowered)) ? "_" + lowered : lowered; } static String toClassName(String name) throws JavaCodeGeneratorException { @@ -79,7 +79,7 @@ class Utils { } String enumName = Character.isDigit(trimmed.charAt(0)) ? "_" + trimmed : trimmed; - return (keywordSet.contains(trimmed)) ? "_" + enumName : enumName; + return (keywordSet.contains(enumName)) ? "_" + enumName : enumName; } } diff --git a/src/com/android/xsdc/tag/XsdAttributeGroup.java b/src/com/android/xsdc/tag/XsdAttributeGroup.java new file mode 100644 index 0000000..6c8f853 --- /dev/null +++ b/src/com/android/xsdc/tag/XsdAttributeGroup.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed 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. + */ + +package com.android.xsdc.tag; + +import com.android.xsdc.XsdParserException; + +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.QName; + +public class XsdAttributeGroup extends XsdTag { + final private List<XsdAttribute> attributes; + final private List<XsdAttributeGroup> attributeGroups; + + public XsdAttributeGroup(String name, QName ref, + List<XsdAttribute> attributes, + List<XsdAttributeGroup> attributeGroups) throws XsdParserException { + super(name, ref); + if (name == null && ref == null) { + throw new XsdParserException("name and ref cannot be both null"); + } + this.attributes = Collections.unmodifiableList(attributes); + this.attributeGroups = Collections.unmodifiableList(attributeGroups); + } + + public List<XsdAttribute> getAttributes() { + return attributes; + } + + public List<XsdAttributeGroup> getAttributeGroups() { + return attributeGroups; + } +} diff --git a/src/com/android/xsdc/tag/XsdComplexContent.java b/src/com/android/xsdc/tag/XsdComplexContent.java index 485fdba..aa9de87 100644 --- a/src/com/android/xsdc/tag/XsdComplexContent.java +++ b/src/com/android/xsdc/tag/XsdComplexContent.java @@ -21,7 +21,7 @@ import java.util.List; public class XsdComplexContent extends XsdComplexType { public XsdComplexContent(String name, XsdType base, List<XsdAttribute> attributes, - List<XsdElement> elements) { - super(name, base, attributes, elements); + List<XsdAttributeGroup> attributeGroups, List<XsdElement> elements, XsdGroup group) { + super(name, base, attributes, attributeGroups, elements, group); } } diff --git a/src/com/android/xsdc/tag/XsdComplexType.java b/src/com/android/xsdc/tag/XsdComplexType.java index 4b662cc..a7e0311 100644 --- a/src/com/android/xsdc/tag/XsdComplexType.java +++ b/src/com/android/xsdc/tag/XsdComplexType.java @@ -23,16 +23,22 @@ import java.util.List; public abstract class XsdComplexType extends XsdType { final private XsdType base; final private List<XsdAttribute> attributes; + final private List<XsdAttributeGroup> attributeGroups; final private List<XsdElement> elements; + final private XsdGroup group; XsdComplexType(String name, XsdType base, List<XsdAttribute> attributes, - List<XsdElement> elements) { + List<XsdAttributeGroup> attributeGroups, + List<XsdElement> elements, XsdGroup group) { super(name, null); this.base = base; this.attributes = Collections.unmodifiableList( attributes != null ? attributes : new ArrayList<>()); + this.attributeGroups = Collections.unmodifiableList( + attributeGroups != null ? attributeGroups : new ArrayList<>()); this.elements = Collections.unmodifiableList( elements != null ? elements : new ArrayList<>()); + this.group = group; } public XsdType getBase() { @@ -43,7 +49,15 @@ public abstract class XsdComplexType extends XsdType { return attributes; } + public List<XsdAttributeGroup> getAttributeGroups() { + return attributeGroups; + } + public List<XsdElement> getElements() { return elements; } + + public XsdGroup getGroup() { + return group; + } } diff --git a/src/com/android/xsdc/tag/XsdGeneralExtension.java b/src/com/android/xsdc/tag/XsdGeneralExtension.java index 1f49659..24043e4 100644 --- a/src/com/android/xsdc/tag/XsdGeneralExtension.java +++ b/src/com/android/xsdc/tag/XsdGeneralExtension.java @@ -22,14 +22,19 @@ import java.util.List; public class XsdGeneralExtension extends XsdTag { final private XsdType base; final private List<XsdAttribute> attributes; + final private List<XsdAttributeGroup> attributeGroups; final private List<XsdElement> elements; + final private XsdGroup group; public XsdGeneralExtension(XsdType base, List<XsdAttribute> attributes, - List<XsdElement> elements) { + List<XsdAttributeGroup> attributeGroups, + List<XsdElement> elements, XsdGroup group) { super(null, null); this.base = base; this.attributes = Collections.unmodifiableList(attributes); + this.attributeGroups = Collections.unmodifiableList(attributeGroups); this.elements = Collections.unmodifiableList(elements); + this.group = group; } public XsdType getBase() { @@ -40,7 +45,15 @@ public class XsdGeneralExtension extends XsdTag { return attributes; } + public List<XsdAttributeGroup> getAttributeGroups() { + return attributeGroups; + } + public List<XsdElement> getElements() { return elements; } + + public XsdGroup getGroup() { + return group; + } } diff --git a/src/com/android/xsdc/tag/XsdGeneralRestriction.java b/src/com/android/xsdc/tag/XsdGeneralRestriction.java index d9e27e2..6583622 100644 --- a/src/com/android/xsdc/tag/XsdGeneralRestriction.java +++ b/src/com/android/xsdc/tag/XsdGeneralRestriction.java @@ -22,14 +22,19 @@ import java.util.List; public class XsdGeneralRestriction extends XsdTag { final private XsdType base; final private List<XsdAttribute> attributes; + final private List<XsdAttributeGroup> attributeGroups; final private List<XsdElement> elements; + final private XsdGroup group; public XsdGeneralRestriction(XsdType base, List<XsdAttribute> attributes, - List<XsdElement> elements) { + List<XsdAttributeGroup> attributeGroups, + List<XsdElement> elements, XsdGroup group) { super(null, null); this.base = base; this.attributes = Collections.unmodifiableList(attributes); + this.attributeGroups = Collections.unmodifiableList(attributeGroups); this.elements = Collections.unmodifiableList(elements); + this.group = group; } public XsdType getBase() { @@ -40,7 +45,15 @@ public class XsdGeneralRestriction extends XsdTag { return attributes; } + public List<XsdAttributeGroup> getAttributeGroups() { + return attributeGroups; + } + public List<XsdElement> getElements() { return elements; } + + public XsdGroup getGroup() { + return group; + } } diff --git a/src/com/android/xsdc/tag/XsdGroup.java b/src/com/android/xsdc/tag/XsdGroup.java new file mode 100644 index 0000000..dd8f008 --- /dev/null +++ b/src/com/android/xsdc/tag/XsdGroup.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed 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. + */ + +package com.android.xsdc.tag; + +import com.android.xsdc.XsdParserException; + +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.QName; + +public class XsdGroup extends XsdTag { + final private List<XsdElement> elements; + + public XsdGroup(String name, QName ref, List<XsdElement> elements) + throws XsdParserException { + super(name, ref); + if (name == null && ref == null) { + throw new XsdParserException("name and ref cannot be both null"); + } + this.elements = Collections.unmodifiableList(elements); + } + + public List<XsdElement> getElements() { + return elements; + } +} diff --git a/src/com/android/xsdc/tag/XsdSimpleContent.java b/src/com/android/xsdc/tag/XsdSimpleContent.java index 94214de..cefa60e 100644 --- a/src/com/android/xsdc/tag/XsdSimpleContent.java +++ b/src/com/android/xsdc/tag/XsdSimpleContent.java @@ -20,6 +20,6 @@ import java.util.List; public class XsdSimpleContent extends XsdComplexType { public XsdSimpleContent(String name, XsdType base, List<XsdAttribute> attributes) { - super(name, base, attributes, null); + super(name, base, attributes, null, null, null); } } diff --git a/tests/Android.bp b/tests/Android.bp index 429948b..afd6150 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -15,6 +15,8 @@ cc_test_host { "main.cpp", ], generated_sources: [ + "xsdc_attr_group_simple_tests", + "xsdc_group_tests", "xsdc_nested_type_tests", "xsdc_predefined_types_tests", "xsdc_purchase_simple_tests", @@ -23,6 +25,8 @@ cc_test_host { "xsdc_simple_type_tests", ], generated_headers: [ + "xsdc_attr_group_simple_tests", + "xsdc_group_tests", "xsdc_nested_type_tests", "xsdc_predefined_types_tests", "xsdc_purchase_simple_tests", diff --git a/tests/main.cpp b/tests/main.cpp index 41b3811..fa9d82c 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -24,6 +24,8 @@ #include "predefined_types.h" #include "reference.h" #include "simple_type.h" +#include "attr_group_simple.h" +#include "group.h" using namespace std; @@ -44,7 +46,8 @@ TEST_F(XmlTest, Simpletype) { EXPECT_EQ(simple.getListInt()[i], i + 1); } EXPECT_EQ(*simple.getFirstUnionTest(), "100"); - EXPECT_EQ(simple.getYesOrNo(), EnumType::YES); + EXPECT_EQ(simple.getYesOrNo()[0], EnumType::YES); + EXPECT_EQ(simple.getYesOrNo()[1], EnumType::EMPTY); } TEST_F(XmlTest, Predefinedtypes) { @@ -199,6 +202,25 @@ TEST_F(XmlTest, Simplecomplexcontent) { EXPECT_EQ(subAddress.getChoice1_optional(), "Temp"); } +TEST_F(XmlTest, Attrgroupsimple) { + using namespace attr::group::simple; + Student student = *read("resources/attr_group_simple.xml"); + + EXPECT_EQ(student.getName(), "Jun"); + EXPECT_EQ(student.getCity(), "Mountain View"); + EXPECT_EQ(student.getState(), "CA"); + EXPECT_EQ(student.getRoad(), "Street 101"); +} + +TEST_F(XmlTest, Group) { + using namespace group; + Student student = *read("resources/group.xml"); + + EXPECT_EQ(student.getCity(), "Mountain View"); + EXPECT_EQ(student.getState(), "CA"); + EXPECT_EQ(student.getRoad(), "Street 101"); +} + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/tests/resources/attr_group_simple.xml b/tests/resources/attr_group_simple.xml new file mode 100644 index 0000000..fb3bfc8 --- /dev/null +++ b/tests/resources/attr_group_simple.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Student State="CA" city="Mountain View" road="Street 101"> + <Name>Jun</Name> +</Student> diff --git a/tests/resources/attr_group_simple/Android.bp b/tests/resources/attr_group_simple/Android.bp new file mode 100644 index 0000000..fe62b55 --- /dev/null +++ b/tests/resources/attr_group_simple/Android.bp @@ -0,0 +1,7 @@ + +xsd_config { + name: "xsdc_attr_group_simple_tests", + srcs: ["attr_group_simple.xsd"], + package_name: "attr.group.simple", +} + diff --git a/tests/resources/attr_group_simple/api/current.txt b/tests/resources/attr_group_simple/api/current.txt new file mode 100644 index 0000000..20aefda --- /dev/null +++ b/tests/resources/attr_group_simple/api/current.txt @@ -0,0 +1,24 @@ +// Signature format: 2.0 +package attr.group.simple { + + public class Student { + ctor public Student(); + method public String getCity(); + method public String getName(); + method public String getRoad(); + method public String getState(); + method public void setCity(String); + method public void setName(String); + method public void setRoad(String); + method public void setState(String); + } + + public class XmlParser { + ctor public XmlParser(); + method public static attr.group.simple.Student read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + } + +} + diff --git a/tests/resources/attr_group_simple/api/last_current.txt b/tests/resources/attr_group_simple/api/last_current.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/resources/attr_group_simple/api/last_current.txt diff --git a/tests/resources/attr_group_simple/api/last_removed.txt b/tests/resources/attr_group_simple/api/last_removed.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/resources/attr_group_simple/api/last_removed.txt diff --git a/tests/resources/attr_group_simple/api/removed.txt b/tests/resources/attr_group_simple/api/removed.txt new file mode 100644 index 0000000..d802177 --- /dev/null +++ b/tests/resources/attr_group_simple/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/tests/resources/attr_group_simple/attr_group_simple.xsd b/tests/resources/attr_group_simple/attr_group_simple.xsd new file mode 100644 index 0000000..7f94e31 --- /dev/null +++ b/tests/resources/attr_group_simple/attr_group_simple.xsd @@ -0,0 +1,18 @@ +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="attr_group_simple" elementFormDefault="qualified"> + <xs:attributeGroup name="address"> + <xs:attribute name="State" type="xs:string"/> + <xs:attribute name="city" type="xs:string"/> + </xs:attributeGroup> + <xs:attributeGroup name="homeAddress"> + <xs:attributeGroup ref="address"/> + <xs:attribute name="road" type="xs:string"/> + </xs:attributeGroup> + <xs:element name="Student"> + <xs:complexType> + <xs:sequence> + <xs:element name="Name" type="xs:string"/> + </xs:sequence> + <xs:attributeGroup ref="homeAddress"/> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/tests/resources/group.xml b/tests/resources/group.xml new file mode 100644 index 0000000..9a51ab6 --- /dev/null +++ b/tests/resources/group.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Student> + <State>CA</State> + <city>Mountain View</city> + <road>Street 101</road> +</Student> diff --git a/tests/resources/group/Android.bp b/tests/resources/group/Android.bp new file mode 100644 index 0000000..21e7242 --- /dev/null +++ b/tests/resources/group/Android.bp @@ -0,0 +1,7 @@ + +xsd_config { + name: "xsdc_group_tests", + srcs: ["group.xsd"], + package_name: "group", +} + diff --git a/tests/resources/group/api/current.txt b/tests/resources/group/api/current.txt new file mode 100644 index 0000000..c79d293 --- /dev/null +++ b/tests/resources/group/api/current.txt @@ -0,0 +1,22 @@ +// Signature format: 2.0 +package group { + + public class Student { + ctor public Student(); + method public String getCity(); + method public String getRoad(); + method public String getState(); + method public void setCity(String); + method public void setRoad(String); + method public void setState(String); + } + + public class XmlParser { + ctor public XmlParser(); + method public static group.Student read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + } + +} + diff --git a/tests/resources/group/api/last_current.txt b/tests/resources/group/api/last_current.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/resources/group/api/last_current.txt diff --git a/tests/resources/group/api/last_removed.txt b/tests/resources/group/api/last_removed.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/resources/group/api/last_removed.txt diff --git a/tests/resources/group/api/removed.txt b/tests/resources/group/api/removed.txt new file mode 100644 index 0000000..d802177 --- /dev/null +++ b/tests/resources/group/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/tests/resources/group/group.xsd b/tests/resources/group/group.xsd new file mode 100644 index 0000000..2bef1a3 --- /dev/null +++ b/tests/resources/group/group.xsd @@ -0,0 +1,18 @@ +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="attr_group_simple" elementFormDefault="qualified"> + <xs:group name="address1"> + <xs:sequence> + <xs:element name="State" type="xs:string"/> + <xs:element name="city" type="xs:string"/> + </xs:sequence> + </xs:group> + <xs:group name="address2" ref="address1"> + <xs:sequence> + <xs:element name="road" type="xs:string"/> + </xs:sequence> + </xs:group> + <xs:element name="Student"> + <xs:complexType> + <xs:group ref="address2"/> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/tests/resources/simple_type.xml b/tests/resources/simple_type.xml index bd8d19a..16da47c 100644 --- a/tests/resources/simple_type.xml +++ b/tests/resources/simple_type.xml @@ -3,4 +3,5 @@ <listInt>1 2 3 4 5</listInt> <union-test>100</union-test> <yesOrNo>YES</yesOrNo> + <yesOrNo></yesOrNo> </simple-types> diff --git a/tests/resources/simple_type/api/current.txt b/tests/resources/simple_type/api/current.txt index c42010e..e61f1fa 100644 --- a/tests/resources/simple_type/api/current.txt +++ b/tests/resources/simple_type/api/current.txt @@ -3,6 +3,7 @@ package simple.type { public enum EnumType { method public String getRawName(); + enum_constant public static final simple.type.EnumType EMPTY; enum_constant public static final simple.type.EnumType NO; enum_constant @Deprecated public static final simple.type.EnumType YES; } @@ -18,10 +19,9 @@ package simple.type { ctor public SimpleTypes(); method public java.util.List<java.lang.Integer> getListInt(); method public java.util.List<java.lang.String> getUnionTest(); - method public simple.type.EnumType getYesOrNo(); + method public java.util.List<simple.type.EnumType> getYesOrNo(); method public void setListInt(java.util.List<java.lang.Integer>); method public void setUnionTest(java.util.List<java.lang.String>); - method public void setYesOrNo(simple.type.EnumType); } public class SingleChoice { diff --git a/tests/resources/simple_type/simple_type.xsd b/tests/resources/simple_type/simple_type.xsd index dbd96a4..23a46b4 100644 --- a/tests/resources/simple_type/simple_type.xsd +++ b/tests/resources/simple_type/simple_type.xsd @@ -22,6 +22,7 @@ <xs:annotation name="Deprecated"/> </xs:enumeration> <xs:enumeration value="NO"/> + <xs:enumeration value=""/> </xs:restriction> </xs:simpleType> <xs:element name="simple-types"> @@ -29,7 +30,7 @@ <xs:sequence> <xs:element name="listInt" type="restrictedInts"/> <xs:element name="union-test" type="unionOfListAndInteger"/> - <xs:element name="yesOrNo" type="enumType"/> + <xs:element name="yesOrNo" type="enumType" maxOccurs="2"/> </xs:sequence> </xs:complexType> </xs:element> |