use of org.jgroups.annotations.XmlElement in project JGroups by belaban.
the class XMLSchemaGenerator method createXMLTree.
private static Element createXMLTree(final Document xmldoc, Class<?> clazz, String pkgname) throws Exception {
Element classElement = xmldoc.createElement("xs:element");
String elementName = pkgname + "." + clazz.getSimpleName();
if (elementName.isEmpty()) {
throw new IllegalArgumentException("Cannot create empty attribute name for element xs:element, class is " + clazz);
}
elementName = elementName.replace(PROT_PACKAGE + ".", "");
classElement.setAttribute("name", elementName);
final Element complexType = xmldoc.createElement("xs:complexType");
classElement.appendChild(complexType);
// the protocol has its own subtree
XmlElement el = Util.getAnnotation(clazz, XmlElement.class);
if (el != null) {
Element choice = xmldoc.createElement("xs:choice");
choice.setAttribute("minOccurs", "0");
choice.setAttribute("maxOccurs", "unbounded");
complexType.appendChild(choice);
Element tmp = xmldoc.createElement("xs:element");
tmp.setAttribute("name", el.name());
tmp.setAttribute("type", el.type());
choice.appendChild(tmp);
}
Map<String, DelayingElementWriter> sortedElements = new TreeMap<>();
XmlAttribute xml_attr = Util.getAnnotation(clazz, XmlAttribute.class);
if (xml_attr != null) {
String[] attrs = xml_attr.attrs();
if (attrs.length > 0) {
// to weed out dupes
Set<String> set = new HashSet<>(Arrays.asList(attrs));
for (final String attr : set) {
sortedElements.put(attr, () -> {
Element attributeElement = xmldoc.createElement("xs:attribute");
attributeElement.setAttribute("name", attr);
attributeElement.setAttribute("type", "xs:string");
complexType.appendChild(attributeElement);
});
}
}
}
// iterate fields
for (Class<?> clazzInLoop = clazz; clazzInLoop != null; clazzInLoop = clazzInLoop.getSuperclass()) {
Field[] fields = clazzInLoop.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Property.class)) {
final String property;
final Property r = field.getAnnotation(Property.class);
boolean annotationRedefinesName = !r.name().isEmpty() && r.deprecatedMessage().isEmpty();
if (annotationRedefinesName) {
property = r.name();
} else {
property = field.getName();
}
if (property == null || property.isEmpty()) {
throw new IllegalArgumentException("Cannot create empty attribute name for element xs:attribute, field is " + field);
}
sortedElements.put(property, () -> {
Element attributeElement = xmldoc.createElement("xs:attribute");
attributeElement.setAttribute("name", property);
// Agreement with Bela Ban on Jan-20-2009 (Go Obama!!!) to treat all types as
// xs:string since we do not know where users are going to use
// replacement tokens in configuration files. Therefore, the type becomes
// indeterminate.
attributeElement.setAttribute("type", "xs:string");
complexType.appendChild(attributeElement);
Element annotationElement = xmldoc.createElement("xs:annotation");
attributeElement.appendChild(annotationElement);
Element documentationElement = xmldoc.createElement("xs:documentation");
documentationElement.setTextContent(r.description());
annotationElement.appendChild(documentationElement);
});
}
}
}
// iterate methods
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Property.class)) {
final Property annotation = method.getAnnotation(Property.class);
final String name;
if (annotation.name().length() < 1) {
name = Util.methodNameToAttributeName(method.getName());
} else {
name = annotation.name();
}
sortedElements.put(name, () -> {
Element attributeElement = xmldoc.createElement("xs:attribute");
attributeElement.setAttribute("name", name);
attributeElement.setAttribute("type", "xs:string");
complexType.appendChild(attributeElement);
String desc = annotation.description();
if (!desc.isEmpty()) {
Element annotationElement = xmldoc.createElement("xs:annotation");
attributeElement.appendChild(annotationElement);
Element documentationElement = xmldoc.createElement("xs:documentation");
documentationElement.setTextContent(annotation.description());
annotationElement.appendChild(documentationElement);
}
});
}
}
// write out ordered and duplicates weeded out elements
for (Map.Entry<String, DelayingElementWriter> entry : sortedElements.entrySet()) {
entry.getValue().writeElement();
}
return classElement;
}
Aggregations