SchemaVisitor { {{ private String[] nsPrefixes; private Stack elementStack, typeStack; }} public void start() {{ elementStack = new Stack(); typeStack = new Stack(); }} public void before(Schema host) {{ nsPrefixes = host.get_attrs().getAllAttributeNames("xmlns", null); }} public void after(Schema host) {{ }} public void before(Element host) {{ String name, type; // If it's a reference to another element, then it needs special // processing name = host.get_attrs().getAttributeValue(null, "ref"); if (!name.equals("")) type = getTypeOfElement(name); else { name = host.get_attrs().getAttributeValue(null, "name"); type = host.get_attrs().getAttributeValue(null, "type"); if (!type.equals("")) type = resolveXMLTypeName(type); else type = name + "Type"; } // 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()) { DataElement newElement = new DataElement(); newElement.set_name(name); newElement.set_type(type); def.get_global_elements().put(name, newElement); if (def.get_root_element() == null) def.set_root_element(newElement); elementStack.push(newElement); } else { ElementClassPart newClassPart = new ElementClassPart(); newClassPart.set_name(name); newClassPart.set_type(type); Constraint cons = new Constraint(); cons.min_occurs = 1; cons.max_occurs = 1; String facet; facet = host.get_attrs().getAttributeValue(null, "minOccurs"); if (!facet.equals("")) cons.min_occurs = Integer.parseInt(facet); facet = host.get_attrs().getAttributeValue(null, "maxOccurs"); if (facet.equals("unbounded")) cons.max_occurs = Integer.MAX_VALUE; // represents unbounded else if (!facet.equals("")) cons.max_occurs = Integer.parseInt(facet); // 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 = Lookup.useObjectType(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("")); listUnitClass.set_part_constraints(GroupConstraint_List.parse("")); def.get_types().addElement(listUnitClass); ElementClassPart listClassPart = new ElementClassPart(); listClassPart.set_name(listUnitName); listClassPart.set_type(listUnitName); Constraint listCons = new Constraint(); listCons.min_occurs = cons.min_occurs; listCons.max_occurs = cons.max_occurs; listClassPart.set_constraint(listCons); cons.min_occurs = 1; cons.max_occurs = 1; newClassPart.set_constraint(cons); listUnitClass.get_element_parts().addElement(newClassPart); DataClass currentType = (DataClass) typeStack.peek(); if (currentType != null) // which should always be true currentType.get_element_parts().addElement(listClassPart); } else // not a list part { newClassPart.set_constraint(cons); DataClass currentType = (DataClass) typeStack.peek(); if (currentType != null) // which should always be true currentType.get_element_parts().addElement(newClassPart); } elementStack.push(newClassPart); } }} public void after(Element host) {{ elementStack.pop(); }} public void before(Attribute host) {{ String name, type; // If it's a reference to another attribute, then it needs special // processing name = host.get_attrs().getAttributeValue(null, "ref"); if (!name.equals("")) type = getTypeOfAttribute(name); else { name = host.get_attrs().getAttributeValue(null, "name"); type = host.get_attrs().getAttributeValue(null, "type"); if (!type.equals("")) type = resolveXMLTypeName(type); else 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 if (elementStack.empty() && typeStack.empty()) { 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; String facet; facet = host.get_attrs().getAttributeValue(null, "minOccurs"); if (!facet.equals("")) cons.min_occurs = Integer.parseInt(facet); facet = host.get_attrs().getAttributeValue(null, "maxOccurs"); if (facet.equals("unbounded")) cons.max_occurs = Integer.MAX_VALUE; // represents unbounded else if (!facet.equals("")) cons.max_occurs = Integer.parseInt(facet); 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 = Lookup.useObjectType(type); newClassPart.set_type(type); } DataClass currentType = (DataClass) typeStack.peek(); if (currentType != null) // which should always be true currentType.get_attr_parts().addElement(newClassPart); } }} public void before(AttributeGroup host) {{ }} public void before(ElementGroup host) {{ }} public void before(TypeDef host) {{ // 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; if (elementStack.empty()) name = host.get_attrs().getAttributeValue(null, "name"); else name = ((DataItem) elementStack.peek()).get_type(); DataClass 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("")); newType.set_part_constraints(GroupConstraint_List.parse("")); def.get_types().addElement(newType); typeStack.push(newType); }} public void after(TypeDef host) {{ typeStack.pop(); }} public void before(ComplexType host) {{ ((DataClass) typeStack.peek()).set_category("COMPLEX"); }} public void after(ComplexType host) {{ }} public void before(SimpleType host) {{ ((DataClass) typeStack.peek()).set_category("SIMPLE"); }} public void after(SimpleType host) {{ }} 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) {{ Lookup.TypeInfo typeinfo = Lookup.resolveXMLTypeName(removeNSPrefix(XMLType)); if ((typeinfo.category == Lookup.BUILT_IN_NON_JAVA_TYPE) && (!def.get_types().contains(typeinfo.classDef))) { def.get_types().addElement(typeinfo.classDef); } return typeinfo.typeName; }} } TypeDef { public abstract AttrValue_List get_attrs(); }