in src/com/intellij/idea/plugin/hybris/system/type/model/generator/DTDModelLoader.java [74:295]
private void processDTD(final String namespace, final DTD dtd, final Map<String, TypeDesc> jtMap, final Map<String, NamespaceDesc> nsdMap) {
final NamespaceDesc nsd = ensureNamespaceExists(namespace);
if (nsd.skip) {
return;
}
final ArrayList<String> resultQNames = new ArrayList<>();
final DTDElement[] elements = new DTDElement[dtd.elements.size()];
int ptr = 1;
final HashSet<DTDElement> visitedElements = new HashSet<>();
elements[0] = dtd.rootElement;
while (--ptr > -1) {
final DTDElement el = elements[ptr];
visitedElements.add(el);
final String typeName = model.toJavaTypeName(el.name, namespace);
final String typeQName = model.toJavaQualifiedTypeName(namespace, typeName, false);
if (resultQNames.contains(typeQName)) {
continue;
} else {
resultQNames.add(typeQName);
}
final TypeDesc td = new TypeDesc(el.name, namespace, typeName, TypeDesc.TypeEnum.CLASS);
boolean duplicates = false;
if ((el.content instanceof DTDAny) || (el.content instanceof DTDMixed)) {
final FieldDesc fd = new FieldDesc(FieldDesc.SIMPLE, "value", "String", null, "null", false);
fd.realIndex = td.fdMap.size();
td.fdMap.put(fd.name, fd);
}
for (Object o : el.attributes.keySet()) {
final String attrName = (String) o;
final DTDAttribute attr = (DTDAttribute) el.attributes.get(attrName);
if (attr.decl == DTDDecl.FIXED || "ID".equals(attr.type)) {
continue;
}
final boolean required = attr.decl == DTDDecl.REQUIRED;
final FieldDesc fd1 = new FieldDesc(
FieldDesc.ATTR,
Util.toJavaFieldName(attrName),
"String",
null,
"\"\"",
required
);
fd1.tagName = attrName;
fd1.documentation = "Attribute " + attrName + "";
fd1.realIndex = td.fdMap.size();
duplicates = Util.addToNameMap(td.fdMap, fd1, false) || duplicates;
}
final ArrayList<List<DTDItem>> choiceList = new ArrayList<>();
final LinkedList<Entry> plist = new LinkedList<>();
if (el.content instanceof DTDContainer) {
//if ((el.content instanceof DTDChoice) || (el.content instanceof DTDSequence)) {
plist.add(new Entry(el.content, false, true));
}
while (!plist.isEmpty()) {
final Entry pentry = plist.removeFirst();
final DTDItem p = pentry.p;
if (p instanceof final DTDName n) {
final DTDElement nel = (DTDElement) dtd.elements.get(n.value);
final String pName = n.value;
final FieldDesc fd1 = new FieldDesc(
FieldDesc.STR,
Util.toJavaFieldName(pName),
pName,
null,
"null",
pentry.required && (n.cardinal == DTDCardinal.ONEMANY || n.cardinal == DTDCardinal.NONE)
);
fd1.tagName = pName;
if (nel != null) {
fd1.documentation = parseDTDItemDocumentation(dtd, nel, "Type " + nel.name + " documentation");
}
if (nel == null) {
fd1.type = model.toJavaTypeName(fd1.tagName, namespace);
} else if (nel.content instanceof DTDEmpty || nel.content instanceof DTDAny) {
boolean hasAttrFields = false;
final boolean hasTextContents = nel.content instanceof DTDAny;
for (Object o : nel.attributes.values()) {
final DTDAttribute attr = (DTDAttribute) o;
if (attr.decl != DTDDecl.FIXED && !"ID".equals(attr.type)) {
hasAttrFields = true;
break;
}
}
if (hasAttrFields || hasTextContents) {
fd1.clType = FieldDesc.OBJ;
fd1.type = model.toJavaTypeName(fd1.tagName, namespace);
fd1.contentQualifiedName = model.toJavaQualifiedTypeName(namespace, fd1.name, false);
fd1.def = "null";
// next type
if (!visitedElements.contains(nel)) {
elements[ptr++] = nel;
}
} else {
fd1.clType = FieldDesc.BOOL;
fd1.type = "boolean";
fd1.def = "false";
}
} else if (nel.content instanceof DTDContainer) {
boolean hasAttrFields = false;
boolean hasTextField = false;
if ((nel.content instanceof DTDMixed) && ((DTDMixed) nel.content).getItemsVec().size() == 1) {
hasTextField = true;
for (Object o : nel.attributes.values()) {
final DTDAttribute attr = (DTDAttribute) o;
if (attr.decl != DTDDecl.FIXED && !"ID".equals(attr.type)) {
hasAttrFields = true;
break;
}
}
}
if (hasTextField && !hasAttrFields) {
fd1.clType = FieldDesc.STR;
fd1.type = "String";
fd1.def = "null";
} else {
fd1.clType = FieldDesc.OBJ;
fd1.type = model.toJavaTypeName(fd1.tagName, namespace);
fd1.contentQualifiedName = model.toJavaQualifiedTypeName(namespace, fd1.tagName, false);
// next type
if (!visitedElements.contains(nel)) {
elements[ptr++] = nel;
}
}
} else {
fd1.type = "ERROR:Name";
}
if ((pentry.many || n.cardinal.type >= 2) && fd1.clType != FieldDesc.BOOL) {
fd1.elementType = fd1.type;
fd1.elementName = fd1.name;
fd1.type = "List<" + fd1.elementType + '>';
fd1.name = Util.pluralize(fd1.name);
fd1.def = "new ArrayList(0)";
fd1.clType = -fd1.clType;
fd1.comment = "array of " + fd1.elementType;
}
fd1.realIndex = td.fdMap.size();
duplicates = Util.addToNameMap(td.fdMap, fd1, false) || duplicates;
} else if (p instanceof final DTDContainer cont) {
final boolean isChoice = cont instanceof DTDChoice;
// 0 - NONE, 1 - OPT, 2 - ZEROMANY, 3 - ONEMANY
final boolean required = !isChoice && pentry.required && p.cardinal != DTDCardinal.ZEROMANY && p.cardinal != DTDCardinal.OPTIONAL;
final boolean many = p.cardinal == DTDCardinal.ONEMANY || p.cardinal == DTDCardinal.ZEROMANY;
final List<DTDItem> l = cont.getItemsVec();
if (!many && isChoice) {
choiceList.add(l);
}
for (DTDItem aL : l) {
plist.add(new Entry(aL, many, required));
}
} else {
Util.logerr("unknown item " + p);
}
}
td.duplicates = duplicates;
td.documentation = parseDTDItemDocumentation(dtd, el, "Type " + el.name + " documentation");
jtMap.put(model.toJavaQualifiedTypeName(namespace, td.name, false), td);
int i = 0;
for (FieldDesc fd : td.fdMap.values()) {
fd.idx = i++;
}
for (List<DTDItem> l : choiceList) {
final ArrayList<DTDItem> clist = new ArrayList<>();
final LinkedList<DTDItem> elist = new LinkedList<>();
for (i = 0; i < l.size(); i++) {
elist.add(l.get(i));
}
while (!elist.isEmpty()) {
final DTDItem p = elist.removeFirst();
if (p instanceof DTDContainer) {
final List<DTDItem> l2 = ((DTDContainer) p).getItemsVec();
for (DTDItem aL2 : l2) {
elist.addFirst(aL2);
}
} else if (p instanceof DTDName) {
clist.add(p);
}
}
boolean choiceOpt = true;
final FieldDesc[] choice = new FieldDesc[clist.size()];
for (i = 0; i < choice.length; i++) {
final DTDName p = (DTDName) clist.get(i);
final String s = Util.toJavaFieldName(p.value);
FieldDesc fd = td.fdMap.get(s);
if (fd == null) {
fd = td.fdMap.get(Util.pluralize(s));
if (fd == null) {
Util.logerr("uknown choice element: " + s);
continue;
}
}
choice[i] = fd;
choice[i].choice = choice;
if (fd.required) {
choiceOpt = false;
}
}
for (i = 0; i < choice.length; i++) {
choice[i].choiceOpt = choiceOpt;
}
}
}
final List<DTDEntity> entList = dtd.getItemsByType(DTDEntity.class);
for (DTDEntity entity : entList) {
final String value = entity.value;
if (!value.startsWith("(") || !value.endsWith(")")) {
continue;
}
final String typeName = model.toJavaTypeName(entity.name, namespace);
final TypeDesc td = new TypeDesc(entity.name, namespace, typeName, TypeDesc.TypeEnum.ENUM);
final StringTokenizer st = new StringTokenizer(value, "(|)");
while (st.hasMoreTokens()) {
final String s = st.nextToken();
td.fdMap.put(s, new FieldDesc(Util.computeEnumConstantName(s, td.name), s));
}
td.documentation = parseDTDItemDocumentation(dtd, entity, "Type " + entity.name + " documentation");
jtMap.put(model.toJavaQualifiedTypeName(namespace, td.name, true), td);
}
}