SchemaVisitor { {{ private String[] nsPrefixes; private Stack elementStack, typeStack; private Stack attrCountStack; private boolean redefineMode; private GlobalAttrGroup currentAttrGroup; private String errors = ""; }} before Schema {{ elementStack = new Stack(); typeStack = new Stack(); attrCountStack = new Stack(); redefineMode = false; currentAttrGroup = null; nsPrefixes = host.get_attrs().getAllAttributeNames("xmlns", null); // Make a dummy registration of the name "choice" so that it becomes // unavailable as a unique name Utils.registerName("TYPE", "choice"); }} before IncludeSchema {{ String xsdIncludeFileName = host.get_attrs().getAttributeValue(null, "schemaLocation"); if (xsdIncludeFileName.equals("")) { errors = errors + "\n" + "No schemaLocation specified in Include element"; return; } try { Schema.readDefinition(xsdIncludeFileName, def); } catch (Exception e) { errors = errors + "\n" + "Error in processing included schema-definition (" + e.getMessage() + ")"; } }} before ImportSchema {{ String xsdImportFileName = host.get_attrs().getAttributeValue(null, "schemaLocation"); if (xsdImportFileName.equals("")) { errors = errors + "\n" + "No schemaLocation specified in Import element"; return; } try { Schema.readDefinition(xsdImportFileName, def); } catch (Exception e) { errors = errors + "\n" + "Error in processing imported schema-definition (" + e.getMessage() + ")"; } }} before RedefineSchema {{ String xsdRedefineFileName = host.get_attrs().getAttributeValue(null, "schemaLocation"); if (xsdRedefineFileName.equals("")) { errors = errors + "\n" + "No schemaLocation specified in Redefine element"; return; } try { Schema.readDefinition(xsdRedefineFileName, def); redefineMode = true; } catch (Exception e) { errors = errors + "\n" + "Error in processing redefined schema-definition (" + e.getMessage() + ")"; } }} after RedefineSchema {{ redefineMode = false; }} before Element {{ String name, type; // If it's a reference to another element, then lookup its type name = host.get_attrs().getAttributeValue(null, "ref"); if (!name.equals("")) // it's a reference { type = getTypeOfElement(removeNSPrefix(name)); if (type.equals("")) // which is not expected to be true { errors = errors + "\n" + "Global element " + name + " not defined before its reference"; type = "Unknown"; } } else // it's a new element definition { name = host.get_attrs().getAttributeValue(null, "name"); type = host.get_attrs().getAttributeValue(null, "type"); if (!type.equals("")) type = resolveXMLTypeName(type); else type = Utils.getUniqueName("TYPE", name + "Type"); } Boolean nillable_flag = null; String nillable_flag_attr = host.get_attrs().getAttributeValue(null, "nillable"); if (nillable_flag_attr.equalsIgnoreCase("true")) nillable_flag = new Boolean(true); // If this element is directly under the "schema" element, add it as a // global element. // Otherwise it must be a "part" under the current type definition if (elementStack.empty() && typeStack.empty()) { Utils.registerName("ELEMENT", name); DataElement newElement = new DataElement(); newElement.set_name(name); newElement.set_type(type); newElement.set_nillable_flag(nillable_flag); // A global element may also be declared as "abstract" String abstract_ind = host.get_attrs().getAttributeValue(null, "abstract"); if (abstract_ind.equalsIgnoreCase("true")) newElement.set_abstract_ind(new Boolean(true)); def.get_global_elements().put(name, newElement); if (def.get_root_element() == null) def.set_root_element(newElement); elementStack.push(newElement); } else { DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; ElementClassPart newClassPart = new ElementClassPart(); newClassPart.set_name(name); newClassPart.set_type(type); newClassPart.set_nillable_flag(nillable_flag); Constraint cons = new Constraint(); cons.min_occurs = 1; cons.max_occurs = 1; String occurrence; occurrence = host.get_attrs().getAttributeValue(null, "minOccurs"); if (!occurrence.equals("")) cons.min_occurs = Integer.parseInt(occurrence); occurrence = host.get_attrs().getAttributeValue(null, "maxOccurs"); if (occurrence.equals("unbounded")) cons.max_occurs = Integer.MAX_VALUE; // represents unbounded else if (!occurrence.equals("")) cons.max_occurs = Integer.parseInt(occurrence); cons.fixed_value = host.get_attrs().getAttributeValue(null, "fixed"); cons.default_value = host.get_attrs().getAttributeValue(null, "default"); if ((cons.min_occurs == 0) && (cons.default_value.equals(""))) cons.default_value = cons.fixed_value; if (cons.fixed_value.equals("")) cons.fixed_value = null; if (cons.default_value.equals("")) cons.default_value = null; // If the element is within an "All" group, then forcibly set the // min and max-occurs attributes to 0 and 1, respectively if (currentClass.get_category().equals("ALL-GROUP")) { cons.min_occurs = 0; cons.max_occurs = 1; } // If the part is optional or a list, then make sure that the type // used is not a primitive data type if ((cons.min_occurs != 1) || (cons.max_occurs != 1)) { type = Utils.convertToObjectType(type); newClassPart.set_type(type); } // If it's going to be a list, we need to add an intermediate // list container class if (cons.max_occurs > 1) { // The current element will contain a list of the intermediate // class and all the constraining facets defined on the part // will be transferred to the part of the intermediate list unit // // e.g. if the schema has: // // // // ... // // // // // // // // // then the resulting classes in the CD will be: // Store = " Cities "" ... // Cities = ">" List(CityListUnit). // CityListUnit = " City "". // // & the check for max. 20 items will be defined in CityListUnit // // From the example, the current element here is "city" String listUnitName = name + "ListUnit"; DataClass listUnitClass = new DataClass(); listUnitClass.set_name(listUnitName); listUnitClass.set_category("LISTUNIT"); listUnitClass.set_abstract_ind(false); listUnitClass.set_subclasses(String_List.parse("")); listUnitClass.set_attr_parts(AttrClassPart_List.parse("")); listUnitClass.set_element_parts(ElementClassPart_List.parse("")); Constraint listCons = new Constraint(); listCons.min_occurs = cons.min_occurs; listCons.max_occurs = cons.max_occurs; cons.min_occurs = 1; cons.max_occurs = 1; newClassPart.set_constraint(cons); addElementToClass(listUnitClass, newClassPart); // Before adding the list unit class to the list of types, check // if there already exists another listUnitClass exactly // matching this definition if (! matchingClassExists(listUnitClass)) { listUnitName = Utils.getUniqueName("TYPE", listUnitName); listUnitClass.set_name(listUnitName); Utils.registerName("TYPE", listUnitName); def.get_types().addElement(listUnitClass); } ElementClassPart listClassPart = new ElementClassPart(); listClassPart.set_name(listUnitName); listClassPart.set_type(listUnitName); listClassPart.set_constraint(listCons); addElementToClass(currentClass, listClassPart); } else // not a list part { newClassPart.set_constraint(cons); addElementToClass(currentClass, newClassPart); } elementStack.push(newClassPart); } }} after Element {{ elementStack.pop(); }} before Attribute {{ String name, type; // If it's a reference to another attribute, then lookup its type name = host.get_attrs().getAttributeValue(null, "ref"); if (!name.equals("")) // it's a reference { type = getTypeOfAttribute(removeNSPrefix(name)); if (type.equals("")) // which is not expected to be true { errors = errors + "\n" + "Global attribute " + name + " not defined before its reference"; type = "Unknown"; } } else // it's a new attribute definition { name = host.get_attrs().getAttributeValue(null, "name"); type = host.get_attrs().getAttributeValue(null, "type"); if (!type.equals("")) type = resolveXMLTypeName(type); else type = Utils.getUniqueName("TYPE", name + "Type"); } // If this attribute is directly under the "schema" element, add it as a // global attribute. // Otherwise it must be a "part" under the current type definition or // the current attribute-group definition if (elementStack.empty() && typeStack.empty() && (currentAttrGroup == null)) { Utils.registerName("ATTRIBUTE", name); DataElement newAttribute = new DataElement(); newAttribute.set_name(name); newAttribute.set_type(type); def.get_global_attributes().put(name, newAttribute); } else { AttrClassPart newClassPart = new AttrClassPart(); newClassPart.set_name(name); newClassPart.set_type(type); Constraint cons = new Constraint(); cons.min_occurs = 0; cons.max_occurs = 1; cons.fixed_value = ""; cons.default_value = ""; String occurrence; occurrence = host.get_attrs().getAttributeValue(null, "use"); if (occurrence.equals("prohibited")) cons.max_occurs = 0; else if (occurrence.equals("required")) { cons.min_occurs = 1; cons.fixed_value = host.get_attrs().getAttributeValue(null, "fixed"); } else if (occurrence.equals("fixed")) { cons.fixed_value = host.get_attrs().getAttributeValue(null, "fixed"); cons.default_value = cons.fixed_value; } else if (occurrence.equals("default")) cons.default_value = host.get_attrs().getAttributeValue(null, "default"); if (cons.fixed_value.equals("")) cons.fixed_value = null; if (cons.default_value.equals("")) cons.default_value = null; newClassPart.set_constraint(cons); // If the part is optional or a list, then make sure that the type // used is not a primitive data type if ((cons.min_occurs != 1) || (cons.max_occurs != 1)) { type = Utils.convertToObjectType(type); newClassPart.set_type(type); } if (currentAttrGroup != null) currentAttrGroup.get_attributes().addElement(newClassPart); else { DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass != null) // which should always be true currentClass.get_attr_parts().addElement(newClassPart); if (! ((cons.min_occurs == 0) && (cons.max_occurs == 0))) { int attrCount = ((Integer) attrCountStack.pop()).intValue(); attrCountStack.push(new Integer(attrCount+1)); } } } }} before AttributeGroup {{ // If it's a reference to an already defined attrGroup, then copy the // attributes belonging to the group into the current entity (which can // be another attribute group or a complexType) String name = host.get_attrs().getAttributeValue(null, "ref"); if (! name.equals("")) // it's a reference { name = removeNSPrefix(name); GlobalAttrGroup refGroup = (GlobalAttrGroup) def.get_global_attribute_groups().get(name); if (refGroup == null) // which is not expected to be true { errors = errors + "\n" + "Attribute group " + name + " not defined before its reference"; return; } else { DataClass currentClass; if (currentAttrGroup != null) // the ref. is from another group currentClass = null; else // the ref. is from a complexType definition { currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; } for (Enumeration attrs = refGroup.get_attributes().elements(); attrs.hasMoreElements(); ) { AttrClassPart attr = (AttrClassPart) attrs.nextElement(); if (currentAttrGroup != null) currentAttrGroup.get_attributes().addElement(attr); else { currentClass.get_attr_parts().addElement(attr); if (! ((attr.get_constraint().min_occurs == 0) && (attr.get_constraint().max_occurs == 0))) { int attrCount = ((Integer) attrCountStack.pop()).intValue(); attrCountStack.push(new Integer(attrCount+1)); } } } } } else // it's a new attribute-group definition { name = host.get_attrs().getAttributeValue(null, "name"); // If this is under the "redefine" element and it's re-defining an // existing attribute-group with the same name, then make it the // current attribute-group and remove the previously defined // attributes under it GlobalAttrGroup prevDef = (GlobalAttrGroup) def.get_global_attribute_groups().get(name); if (redefineMode && (prevDef != null)) currentAttrGroup = prevDef; else { currentAttrGroup = new GlobalAttrGroup(); currentAttrGroup.set_name(name); def.get_global_attribute_groups().put(name, currentAttrGroup); } currentAttrGroup.set_attributes(AttrClassPart_List.parse("")); } }} after AttributeGroup {{ currentAttrGroup = null; }} before ElementGroup {{ // If it's a reference to an already defined group, then create an // element class part with the same name as the group and with the type // set to the class representing the group String name = host.get_attrs().getAttributeValue(null, "ref"); if (! name.equals("")) // it's a reference { name = removeNSPrefix(name); String groupClassName = (String) def.get_global_groups().get(name); if (groupClassName == null) // which is not expected to be true { errors = errors + "\n" + "Group " + name + " not defined before its reference"; return; } else { DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; ElementClassPart newClassPart = new ElementClassPart(); newClassPart.set_name(name); newClassPart.set_type(groupClassName); Constraint cons = new Constraint(); cons.min_occurs = 1; cons.max_occurs = 1; String occurrence; occurrence = host.get_attrs().getAttributeValue(null, "minOccurs"); if (!occurrence.equals("")) cons.min_occurs = Integer.parseInt(occurrence); occurrence = host.get_attrs().getAttributeValue(null, "maxOccurs"); if (occurrence.equals("unbounded")) cons.max_occurs = Integer.MAX_VALUE; // represents unbounded else if (!occurrence.equals("")) cons.max_occurs = Integer.parseInt(occurrence); cons.group_part_flag = new Boolean(true); newClassPart.set_constraint(cons); addElementToClass(currentClass, newClassPart); } } else // it's a new group definition { name = host.get_attrs().getAttributeValue(null, "name"); String groupClassName; DataClass groupClass = null; // If this is under the "redefine" element and it's re-defining an // existing element-group with the same name, then use the // previously created class to represent the group-elements if (redefineMode) { String prevGroupClassName = (String) def.get_global_groups().get(name); if (prevGroupClassName != null) { for (Enumeration elems = def.get_types().elements(); elems.hasMoreElements(); ) { DataClass c = (DataClass) elems.nextElement(); if (c.get_name().equals(prevGroupClassName)) { groupClass = c; groupClassName = c.get_name(); break; } } } } if (groupClass == null) { groupClassName = Utils.getUniqueName("TYPE", name + "Group"); Utils.registerName("TYPE", groupClassName); def.get_global_groups().put(name, groupClassName); groupClass = new DataClass(); groupClass.set_name(groupClassName); groupClass.set_category("GROUP"); groupClass.set_abstract_ind(false); groupClass.set_subclasses(String_List.parse("")); def.get_types().addElement(groupClass); } groupClass.set_attr_parts(AttrClassPart_List.parse("")); groupClass.set_element_parts(ElementClassPart_List.parse("")); typeStack.push(groupClass); attrCountStack.push(new Integer(0)); } }} after ElementGroup {{ // If it was a new group definition, then pop the dataclass representing // it from the typeStack if (host.get_attrs().getAttributeValue(null, "ref").equals("")) { typeStack.pop(); attrCountStack.pop(); } }} before AllGroup {{ DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass != null) // which should always be true currentClass.set_category("ALL-GROUP"); }} before ChoiceGroup {{ DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which is not expected to be true return; // Convert the choice group to a DataClass, and add an element class- // part (of that type) to the current class to hold the place of the // "Choice" group String groupClassName = Utils.getUniqueName("TYPE", currentClass.get_name() + "Choice"); Utils.registerName("TYPE", groupClassName); // First, add an element-class-part to the current class that will // hold the place of this group ElementClassPart newClassPart = new ElementClassPart(); newClassPart.set_name(groupClassName); newClassPart.set_type(groupClassName); Constraint cons = new Constraint(); cons.min_occurs = 1; cons.max_occurs = 1; String occurrence; occurrence = host.get_attrs().getAttributeValue(null, "minOccurs"); if (!occurrence.equals("")) cons.min_occurs = Integer.parseInt(occurrence); occurrence = host.get_attrs().getAttributeValue(null, "maxOccurs"); if (occurrence.equals("unbounded")) cons.max_occurs = Integer.MAX_VALUE; // represents unbounded else if (!occurrence.equals("")) cons.max_occurs = Integer.parseInt(occurrence); cons.group_part_flag = new Boolean(true); newClassPart.set_constraint(cons); addElementToClass(currentClass, newClassPart); // And, create a dataclass to represent the group DataClass groupClass = new DataClass(); groupClass.set_name(groupClassName); groupClass.set_category("CHOICE-GROUP"); groupClass.set_abstract_ind(true); groupClass.set_subclasses(String_List.parse("")); groupClass.set_attr_parts(AttrClassPart_List.parse("")); groupClass.set_element_parts(ElementClassPart_List.parse("")); def.get_types().addElement(groupClass); typeStack.push(groupClass); attrCountStack.push(new Integer(0)); }} after ChoiceGroup {{ // Pop the dataclass representing the choice-group from the typeStack DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass != null) // which should always be true { typeStack.pop(); attrCountStack.pop(); } }} before SequenceGroup {{ DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which is not expected to be true return; // If this group is defined under another "Choice" group or if it is // defined to be a list part, then it is converted to a DataClass, and // an element-class-part (of that type) is added to the current class to // hold the place of the "Sequence" group Constraint cons = new Constraint(); cons.min_occurs = 1; cons.max_occurs = 1; String occurrence; occurrence = host.get_attrs().getAttributeValue(null, "minOccurs"); if (!occurrence.equals("")) cons.min_occurs = Integer.parseInt(occurrence); occurrence = host.get_attrs().getAttributeValue(null, "maxOccurs"); if (occurrence.equals("unbounded")) cons.max_occurs = Integer.MAX_VALUE; // represents unbounded else if (!occurrence.equals("")) cons.max_occurs = Integer.parseInt(occurrence); if (((currentClass.get_category().equals("CHOICE-GROUP"))) || (cons.max_occurs > 1)) { String groupClassName = Utils.getUniqueName("TYPE", currentClass.get_name() + "Seq"); Utils.registerName("TYPE", groupClassName); // First, add an element-class-part to the current class that will // hold the place of this group ElementClassPart newClassPart = new ElementClassPart(); newClassPart.set_name(groupClassName); newClassPart.set_type(groupClassName); cons.group_part_flag = new Boolean(true); newClassPart.set_constraint(cons); addElementToClass(currentClass, newClassPart); // Now, create a dataclass to represent the group DataClass groupClass = new DataClass(); groupClass.set_name(groupClassName); groupClass.set_category("SEQ-GROUP"); groupClass.set_abstract_ind(false); groupClass.set_subclasses(String_List.parse("")); groupClass.set_attr_parts(AttrClassPart_List.parse("")); groupClass.set_element_parts(ElementClassPart_List.parse("")); def.get_types().addElement(groupClass); typeStack.push(groupClass); attrCountStack.push(new Integer(0)); } }} after SequenceGroup {{ // If this group was converted to a class, then pop the dataclass // representing it from the typeStack DataClass currentClass = (DataClass) typeStack.peek(); if ((currentClass != null) && (currentClass.get_category().equals("SEQ-GROUP"))) { typeStack.pop(); attrCountStack.pop(); } }} before TypeDef {{ // If this is a global type, then it must have a name, otherwise it's // anonymous and name it after the enclosing element String name; DataClass newType = null; if (elementStack.empty()) { name = host.get_attrs().getAttributeValue(null, "name"); // If this is under the "redefine" element then the existing type // defintion with that name has to be replaced by the new definition if (redefineMode) { for (Enumeration elems = def.get_types().elements(); elems.hasMoreElements(); ) { DataClass c = (DataClass) elems.nextElement(); if (c.get_name().equals(name)) { newType = c; break; } } } } else name = ((DataItem) elementStack.peek()).get_type(); Utils.registerName("TYPE", name); if (newType == null) { newType = new DataClass(); newType.set_name(name); newType.set_category(""); newType.set_abstract_ind(false); newType.set_subclasses(String_List.parse("")); newType.set_attr_parts(AttrClassPart_List.parse("")); newType.set_element_parts(ElementClassPart_List.parse("")); def.get_types().addElement(newType); } typeStack.push(newType); attrCountStack.push(new Integer(0)); }} after TypeDef {{ typeStack.pop(); attrCountStack.pop(); }} before ComplexType {{ DataClass currentType = (DataClass) typeStack.peek(); currentType.set_category("COMPLEX"); String abstract_ind = host.get_attrs().getAttributeValue(null, "abstract"); currentType.set_abstract_ind( Boolean.valueOf(abstract_ind).booleanValue()); }} before SimpleType {{ ((DataClass) typeStack.peek()).set_category("SIMPLE"); }} before TypeDerivation {{ DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; String baseType = removeNSPrefix( host.get_attrs().getAttributeValue(null, "base")); // If this is under the "redefine" element and it's deriving from the // existing type with the same name, then nothing needs to be done here if (redefineMode && baseType.equals(currentClass.get_name())) return; if (Utils.isBuiltInXMLType(baseType)) { baseType = resolveXMLTypeName(baseType); ElementClassPart newClassPart = new ElementClassPart(); newClassPart.set_name("value"); newClassPart.set_type(baseType); Constraint cons = new Constraint(); cons.min_occurs = 1; cons.max_occurs = 1; newClassPart.set_constraint(cons); addElementToClass(currentClass, newClassPart); } else { DataClass baseClass = findDataClass(baseType); if (baseClass == null) // which is not expected to be true { errors = errors + "\n" + "Base type " + baseType + " not defined before its reference"; return; } currentClass.set_superclass(baseType); currentClass.set_superclass_abstract_ind( new Boolean(baseClass.get_abstract_ind())); } }} before Extension {{ DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; String baseType = removeNSPrefix( host.get_attrs().getAttributeValue(null, "base")); // If this is under the "redefine" element and it's extending the // existing type with the same name, then nothing needs to be done here // because the "base" class-parts are already part of the current class if (redefineMode && baseType.equals(currentClass.get_name())) return; if (!Utils.isBuiltInXMLType(baseType)) { DataClass baseClass = findDataClass(baseType); if (baseClass == null) // which is not expected to be true return; // Copy all parts (attributes and elements) from the base class // into the derived class - to create a flattened structure for (Enumeration attrs = baseClass.get_attr_parts().elements(); attrs.hasMoreElements(); ) { AttrClassPart a = (AttrClassPart) attrs.nextElement(); currentClass.get_attr_parts().addElement(a); if (! ((a.get_constraint().min_occurs == 0) && (a.get_constraint().max_occurs == 0))) { int attrCount = ((Integer) attrCountStack.pop()).intValue(); attrCountStack.push(new Integer(attrCount+1)); } } for (Enumeration elems = baseClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); addElementToClass(currentClass, e); } } }} before Restriction {{ DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; String baseType = removeNSPrefix( host.get_attrs().getAttributeValue(null, "base")); // If this is under the "redefine" element and it's restricting the // existing type with the same name, then the "base" class-parts are // already part of the current class. So, for restriction of a simple // type, noting should be done here; but for restriction of a complex // type, the class-parts have to be removed (because they will all be // specified again). if (!Utils.isBuiltInXMLType(baseType)) { DataClass baseClass; if (redefineMode && baseType.equals(currentClass.get_name())) baseClass = currentClass; else { baseClass = findDataClass(baseType); if (baseClass == null) // which is not expected to be true return; } if (baseClass.get_category().equals("SIMPLE")) { if (redefineMode && (baseClass == currentClass)) return; // Copy all parts (attributes and elements) from the base class // into the derived class - to create a flattened structure for (Enumeration attrs = baseClass.get_attr_parts().elements(); attrs.hasMoreElements(); ) { AttrClassPart a = (AttrClassPart) attrs.nextElement(); currentClass.get_attr_parts().addElement(a); if (! ((a.get_constraint().min_occurs == 0) && (a.get_constraint().max_occurs == 0))) { int attrCount = ((Integer) attrCountStack.pop()).intValue(); attrCountStack.push(new Integer(attrCount+1)); } } for (Enumeration elems = baseClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); addElementToClass(currentClass, e); } } else // it's a restriction of a complexType { if (redefineMode && (baseClass == currentClass)) { currentClass.set_attr_parts(AttrClassPart_List.parse("")); currentClass.set_element_parts(ElementClassPart_List.parse("")); } } } }} after TypeDerivation {{ // Add this class to the list of subclasses for the base class (if any) DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; String baseType = removeNSPrefix( host.get_attrs().getAttributeValue(null, "base")); // If this is under the "redefine" element and it's extending the // existing type with the same name, then nothing needs to be done here // because the "base" and current classes are the same if (redefineMode && baseType.equals(currentClass.get_name())) return; if (!Utils.isBuiltInXMLType(baseType)) { DataClass baseClass = findDataClass(baseType); if (baseClass == null) // which is not expected to be true return; // If the superclass is abstract, compute the lookahead needed to // correctly identify the current concrete class for parsing and // include that in the subclass list for the superclass; // otherwise just use the classname String classSpecifier; if ((currentClass.get_superclass_abstract_ind() != null) && (currentClass.get_superclass_abstract_ind().booleanValue())) { int attrCount = ((Integer) attrCountStack.peek()).intValue(); classSpecifier = "lookahead {" + "{" + ((attrCount+1)*3) + "}" + "} " + currentClass.get_name(); } else classSpecifier = currentClass.get_name(); baseClass.subclasses.addElement(classSpecifier); } }} // Constraining facets are defined only for simpleTypes; so just pick the // first (which also happens to be the only) element, and update its // constraint with the respective value in each case before Duration {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_duration(value); }} before Encoding {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_encoding(value); }} before EnumerationSpec {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; value = "" + value + ""; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) { if (cons.get_enum_values() == null) cons.set_enum_values(value); else cons.set_enum_values(cons.get_enum_values() + value); } }} before LengthSpec {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_length(new Integer(value)); }} before MaxLength {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_max_length(new Integer(value)); }} before MinLength {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_min_length(new Integer(value)); }} before MaxExclusive {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) { cons.set_max_value(value); cons.set_max_included(new Boolean(false)); } }} before MaxInclusive {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) { cons.set_max_value(value); cons.set_max_included(new Boolean(true)); } }} before MinExclusive {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) { cons.set_min_value(value); cons.set_min_included(new Boolean(false)); } }} before MinInclusive {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) { cons.set_min_value(value); cons.set_min_included(new Boolean(true)); } }} before Pattern {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_pattern(value); }} before Period {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_period(value); }} before TotalDigits {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_total_digits(new Integer(value)); }} before FractionDigits {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_fraction_digits(new Integer(value)); }} before Whitespace {{ String value = host.get_attrs().getAttributeValue(null, "value"); if (value.equals("")) return; DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; Constraint cons = null; for (Enumeration elems = currentClass.get_element_parts().elements(); elems.hasMoreElements(); ) { ElementClassPart e = (ElementClassPart) elems.nextElement(); cons = e.get_constraint(); break; } if (cons != null) cons.set_whitespace(value); }} before ListVariety {{ DataClass currentClass = (DataClass) typeStack.peek(); if (currentClass == null) // which should never be true return; String unitType = host.get_attrs().getAttributeValue(null, "itemType"); if (!unitType.equals("")) unitType = Utils.convertToObjectType(resolveXMLTypeName(unitType)); else unitType = currentClass.get_name() + "Item"; ElementClassPart newClassPart = new ElementClassPart(); newClassPart.set_name("value"); newClassPart.set_type(unitType); Constraint cons = new Constraint(); cons.min_occurs = 0; cons.max_occurs = Integer.MAX_VALUE; newClassPart.set_constraint(cons); addElementToClass(currentClass, newClassPart); elementStack.push(newClassPart); }} after ListVariety {{ elementStack.pop(); }} before UnionVariety {{ // NOT IMPLEMENTED }} public String getErrors() {{ return errors; }} public String[] getNamespacePrefix() {{ return nsPrefixes; }} private String getTypeOfElement(String name) {{ DataElement element = (DataElement) def.get_global_elements().get(name); if (element != null) return element.get_type(); return ""; }} private String getTypeOfAttribute(String name) {{ DataElement element = (DataElement) def.get_global_attributes().get(name); if (element != null) return element.get_type(); return ""; }} private String removeNSPrefix(String itemName) {{ return itemName.substring(itemName.indexOf(':')+1, itemName.length()); }} private String resolveXMLTypeName(String XMLType) {{ Utils.TypeInfo typeinfo = Utils.resolveXMLTypeName(removeNSPrefix(XMLType)); if ((typeinfo.category == Utils.BUILT_IN_NON_JAVA_TYPE) && (!def.get_types().contains(typeinfo.classDef))) { def.get_types().addElement(typeinfo.classDef); } if ((typeinfo.listUnitClassDef != null) && (!def.get_types().contains(typeinfo.listUnitClassDef))) { def.get_types().addElement(typeinfo.listUnitClassDef); } return typeinfo.typeName; }} private DataClass findDataClass(String className) {{ for (Enumeration elems = def.get_types().elements(); elems.hasMoreElements(); ) { DataClass c = (DataClass) elems.nextElement(); if (c.get_name().equals(className)) return c; } return null; }} private void addElementToClass(DataClass currentClass, ElementClassPart classPart) {{ if (currentClass != null) { if ((currentClass.get_category().equals("CHOICE-GROUP"))) { String choiceClassName = Utils.getUniqueName("TYPE", "choice"); Utils.registerName("TYPE", choiceClassName); // Create a dataclass (as a sub-class of the current class) to // contain the choice-element currentClass.get_subclasses().addElement(choiceClassName); DataClass choiceClass = new DataClass(); choiceClass.set_name(choiceClassName); choiceClass.set_category("GROUP"); choiceClass.set_abstract_ind(false); choiceClass.set_superclass(currentClass.get_name()); choiceClass.set_superclass_abstract_ind( new Boolean(currentClass.get_abstract_ind())); choiceClass.set_subclasses(String_List.parse("")); choiceClass.set_attr_parts(AttrClassPart_List.parse("")); choiceClass.set_element_parts(ElementClassPart_List.parse("")); // Add the choice-element to this class, instead of directly // adding it to the current class classPart.get_constraint().min_occurs = 1; classPart.get_constraint().max_occurs = 1; choiceClass.get_element_parts().addElement(classPart); def.get_types().addElement(choiceClass); } else currentClass.get_element_parts().addElement(classPart); } }} private boolean matchingClassExists(DataClass newClass) {{ DataClass oldClass = null; // first check, if another class with this name exists at all for (Enumeration elems = def.get_types().elements(); elems.hasMoreElements(); ) { DataClass c = (DataClass) elems.nextElement(); if (c.get_name().equals(newClass.get_name())) { oldClass = c; break; } } if (oldClass == null) return false; // Check if the category matches if (! oldClass.get_category().equals(newClass.get_category())) return false; Vector oldClassParts; Vector newClassParts; // Check if the attribute-definitions match oldClassParts = new Vector(); for (Enumeration elems = oldClass.get_attr_parts().elements(); elems.hasMoreElements(); ) { oldClassParts.add((AttrClassPart) elems.nextElement()); } newClassParts = new Vector(); for (Enumeration elems = newClass.get_attr_parts().elements(); elems.hasMoreElements(); ) { newClassParts.add((AttrClassPart) elems.nextElement()); } if (oldClassParts.size() != newClassParts.size()) return false; for (int i = 0; i < oldClassParts.size(); i++) { AttrClassPart oldC, newC; oldC = (AttrClassPart) oldClassParts.get(i); newC = (AttrClassPart) newClassParts.get(i); if ((! oldC.get_name().equals(newC.get_name())) || (! oldC.get_type().equals(newC.get_type()))) return false; } // Check if the element-definitions match oldClassParts = new Vector(); for (Enumeration elems = oldClass.get_element_parts().elements(); elems.hasMoreElements(); ) { oldClassParts.add((ElementClassPart) elems.nextElement()); } newClassParts = new Vector(); for (Enumeration elems = newClass.get_element_parts().elements(); elems.hasMoreElements(); ) { newClassParts.add((ElementClassPart) elems.nextElement()); } if (oldClassParts.size() != newClassParts.size()) return false; for (int i = 0; i < oldClassParts.size(); i++) { ElementClassPart oldC, newC; oldC = (ElementClassPart) oldClassParts.get(i); newC = (ElementClassPart) newClassParts.get(i); if ((! oldC.get_name().equals(newC.get_name())) || (! oldC.get_type().equals(newC.get_type()))) return false; } return true; }} } TypeDef { public abstract AttrValue_List get_attrs(); } TypeDerivation { public abstract AttrValue_List get_attrs(); }