aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/xsdc.go40
-rw-r--r--src/com/android/xsdc/Main.java3
-rw-r--r--src/com/android/xsdc/XmlSchema.java16
-rw-r--r--src/com/android/xsdc/XsdHandler.java120
-rw-r--r--src/com/android/xsdc/cpp/CppCodeGenerator.java114
-rw-r--r--src/com/android/xsdc/cpp/Utils.java6
-rw-r--r--src/com/android/xsdc/java/JavaCodeGenerator.java77
-rw-r--r--src/com/android/xsdc/java/Utils.java4
-rw-r--r--src/com/android/xsdc/tag/XsdAttributeGroup.java47
-rw-r--r--src/com/android/xsdc/tag/XsdComplexContent.java4
-rw-r--r--src/com/android/xsdc/tag/XsdComplexType.java16
-rw-r--r--src/com/android/xsdc/tag/XsdGeneralExtension.java15
-rw-r--r--src/com/android/xsdc/tag/XsdGeneralRestriction.java15
-rw-r--r--src/com/android/xsdc/tag/XsdGroup.java40
-rw-r--r--src/com/android/xsdc/tag/XsdSimpleContent.java2
-rw-r--r--tests/Android.bp4
-rw-r--r--tests/main.cpp24
-rw-r--r--tests/resources/attr_group_simple.xml4
-rw-r--r--tests/resources/attr_group_simple/Android.bp7
-rw-r--r--tests/resources/attr_group_simple/api/current.txt24
-rw-r--r--tests/resources/attr_group_simple/api/last_current.txt0
-rw-r--r--tests/resources/attr_group_simple/api/last_removed.txt0
-rw-r--r--tests/resources/attr_group_simple/api/removed.txt1
-rw-r--r--tests/resources/attr_group_simple/attr_group_simple.xsd18
-rw-r--r--tests/resources/group.xml6
-rw-r--r--tests/resources/group/Android.bp7
-rw-r--r--tests/resources/group/api/current.txt22
-rw-r--r--tests/resources/group/api/last_current.txt0
-rw-r--r--tests/resources/group/api/last_removed.txt0
-rw-r--r--tests/resources/group/api/removed.txt1
-rw-r--r--tests/resources/group/group.xsd18
-rw-r--r--tests/resources/simple_type.xml1
-rw-r--r--tests/resources/simple_type/api/current.txt4
-rw-r--r--tests/resources/simple_type/simple_type.xsd3
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>