+ throw new IllegalStateException("Cannot reload types", e);
+ }
+ }
+
+ private void collectTypes() {
+ types.clear();
+ // elements
+ XSNamedMap topLevelElements = xsModel.getComponents(XSConstants.ELEMENT_DECLARATION);
+ for (int i = 0; i < topLevelElements.getLength(); i++) {
+ XSElementDeclaration eDec = (XSElementDeclaration) topLevelElements.item(i);
+ collectElementDeclaration("", eDec);
+ }
+
+ // types
+ XSNamedMap topLevelTypes = xsModel.getComponents(XSConstants.TYPE_DEFINITION);
+ for (int i = 0; i < topLevelTypes.getLength(); i++) {
+ XSTypeDefinition tDef = (XSTypeDefinition) topLevelTypes.item(i);
+ collectType(tDef, null, null);
+ }
+
+ }
+
+ private void collectType(XSTypeDefinition tDef, String namespace, String nameHint) {
+ if (tDef.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
+ XSComplexTypeDefinition ctDef = (XSComplexTypeDefinition) tDef;
+ if (ctDef.getContentType() != XSComplexTypeDefinition.CONTENTTYPE_SIMPLE
+ || ctDef.getAttributeUses().getLength() > 0 || ctDef.getAttributeWildcard() != null) {
+ collectComplexType("", null, ctDef);
+ } else {
+ throw new IllegalArgumentException("Unsupported type " + tDef.getTypeCategory());
+ }
+ }
+ }
+
+ private void collectComplexType(String prefix, QName parent, XSComplexTypeDefinition ctDef) {
+ if (ctDef.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_SIMPLE) {
+
+ // content with attributes and a string value
+
+ XSSimpleTypeDefinition stDef = ctDef.getSimpleType();
+ // QName name = new QName(stDef.getNamespace(), stDef.getName());
+ // log.warn(prefix + "Simple " + ctDef + " - " + attributes);
+// System.err.println(prefix + "Simple from " + parent + " - " + attributes);
+//
+// if (parentAttributes != null) {
+// for (QName attr : attributes.keySet()) {
+// if (!parentAttributes.containsKey(attr))
+// System.err.println(prefix + " - " + attr + " not available in parent");
+//
+// }
+// }
+
+ } else if (ctDef.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_ELEMENT
+ || ctDef.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_MIXED) {
+ XSParticle p = ctDef.getParticle();
+
+ collectParticle(prefix, p, false);
+ } else if (ctDef.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_EMPTY) {
+ // Parent only contains attributes
+// if (parent != null)
+// System.err.println(prefix + "Empty from " + parent + " - " + attributes);
+// if (parentAttributes != null) {
+// for (QName attr : attributes.keySet()) {
+// if (!parentAttributes.containsKey(attr))
+// System.err.println(prefix + " - " + attr + " not available in parent");
+//
+// }
+// }
+// log.debug(prefix + "Empty " + ctDef.getNamespace() + ":" + ctDef.getName() + " - " + attributes);
+ } else {
+ throw new IllegalArgumentException("Unsupported type " + ctDef.getTypeCategory());
+ }
+ }
+
+ private void collectParticle(String prefix, XSParticle particle, boolean multipleFromAbove) {
+ boolean orderable = false;
+
+ XSTerm term = particle.getTerm();
+
+ if (particle.getMaxOccurs() == 0) {
+ return;
+ }
+
+ boolean mandatory = false;
+ if (particle.getMinOccurs() > 0) {
+ mandatory = true;
+ }
+
+ boolean multiple = false;
+ if (particle.getMaxOccurs() > 1 || particle.getMaxOccursUnbounded()) {
+ multiple = true;
+ }
+ if (!multiple && multipleFromAbove)
+ multiple = true;
+
+ if (term.getType() == XSConstants.ELEMENT_DECLARATION) {
+ XSElementDeclaration eDec = (XSElementDeclaration) term;
+
+ collectElementDeclaration(prefix, eDec);
+ // If this particle is a wildcard (an <xs:any> )then it
+ // is converted into a node def.
+ } else if (term.getType() == XSConstants.WILDCARD) {
+ // TODO can be anything
+
+ // If this particle is a model group (one of
+ // <xs:sequence>, <xs:choice> or <xs:all>) then
+ // it subparticles must be processed.
+ } else if (term.getType() == XSConstants.MODEL_GROUP) {
+ XSModelGroup mg = (XSModelGroup) term;
+
+ if (mg.getCompositor() == XSModelGroup.COMPOSITOR_SEQUENCE) {
+ orderable = true;
+ }
+ XSObjectList list = mg.getParticles();
+ for (int i = 0; i < list.getLength(); i++) {
+ XSParticle pp = (XSParticle) list.item(i);
+ collectParticle(prefix + " ", pp, multiple);
+ }
+ }
+ }
+
+ private void collectElementDeclaration(String prefix, XSElementDeclaration eDec) {
+ QName name = new QName(eDec.getNamespace(), eDec.getName());
+ XSTypeDefinition tDef = eDec.getTypeDefinition();
+
+ XSComplexTypeDefinition ctDef = null;
+ Map<QName, CrAttributeType> attributes = new HashMap<>();
+ if (tDef.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
+ XSSimpleTypeDefinition stDef = (XSSimpleTypeDefinition) tDef;
+// System.err.println(prefix + "Simple element " + name);
+ } else if (tDef.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
+ ctDef = (XSComplexTypeDefinition) tDef;
+ if (ctDef.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_SIMPLE
+ && ctDef.getAttributeUses().getLength() == 0 && ctDef.getAttributeWildcard() == null) {
+ XSSimpleTypeDefinition stDef = ctDef.getSimpleType();
+// System.err.println(prefix + "Simplified element " + name);
+ } else {
+ if (!types.containsKey(name)) {
+// System.out.println(prefix + "Element " + name);
+
+ XSObjectList list = ctDef.getAttributeUses();
+ for (int i = 0; i < list.getLength(); i++) {
+ XSAttributeUse au = (XSAttributeUse) list.item(i);
+ XSAttributeDeclaration ad = au.getAttrDeclaration();
+ QName attrName = new QName(ad.getNamespace(), ad.getName());
+ // Get the simple type def for this attribute
+ XSSimpleTypeDefinition std = ad.getTypeDefinition();
+ attributes.put(attrName, xsToCrType(std.getBuiltInKind()));
+// System.out.println(prefix + " - " + attrName + " = " + attributes.get(attrName));
+ }
+ // REGISTER
+ types.put(name, attributes);
+ if (ctDef != null)
+ collectComplexType(prefix + " ", name, ctDef);
+ }
+ }
+ }
+
+ }
+
+ private CrAttributeType xsToCrType(short kind) {
+ CrAttributeType propertyType;
+ switch (kind) {
+ case XSConstants.ANYSIMPLETYPE_DT:
+ case XSConstants.STRING_DT:
+ case XSConstants.ID_DT:
+ case XSConstants.ENTITY_DT:
+ case XSConstants.NOTATION_DT:
+ case XSConstants.NORMALIZEDSTRING_DT:
+ case XSConstants.TOKEN_DT:
+ case XSConstants.LANGUAGE_DT:
+ case XSConstants.NMTOKEN_DT:
+ propertyType = CrAttributeType.STRING;
+ break;
+ case XSConstants.BOOLEAN_DT:
+ propertyType = CrAttributeType.BOOLEAN;
+ break;
+ case XSConstants.DECIMAL_DT:
+ case XSConstants.FLOAT_DT:
+ case XSConstants.DOUBLE_DT:
+ propertyType = CrAttributeType.DOUBLE;
+ break;
+ case XSConstants.DURATION_DT:
+ case XSConstants.DATETIME_DT:
+ case XSConstants.TIME_DT:
+ case XSConstants.DATE_DT:
+ case XSConstants.GYEARMONTH_DT:
+ case XSConstants.GYEAR_DT:
+ case XSConstants.GMONTHDAY_DT:
+ case XSConstants.GDAY_DT:
+ case XSConstants.GMONTH_DT:
+ propertyType = CrAttributeType.DATE_TIME;
+ break;
+ case XSConstants.HEXBINARY_DT:
+ case XSConstants.BASE64BINARY_DT:
+ case XSConstants.ANYURI_DT:
+ propertyType = CrAttributeType.ANY_URI;
+ break;
+ case XSConstants.QNAME_DT:
+ case XSConstants.NAME_DT:
+ case XSConstants.NCNAME_DT:
+ // TODO support QName?
+ propertyType = CrAttributeType.STRING;
+ break;
+ case XSConstants.IDREF_DT:
+ // TODO support references?
+ propertyType = CrAttributeType.STRING;
+ break;
+ case XSConstants.INTEGER_DT:
+ case XSConstants.NONPOSITIVEINTEGER_DT:
+ case XSConstants.NEGATIVEINTEGER_DT:
+ case XSConstants.LONG_DT:
+ case XSConstants.INT_DT:
+ case XSConstants.SHORT_DT:
+ case XSConstants.BYTE_DT:
+ case XSConstants.NONNEGATIVEINTEGER_DT:
+ case XSConstants.UNSIGNEDLONG_DT:
+ case XSConstants.UNSIGNEDINT_DT:
+ case XSConstants.UNSIGNEDSHORT_DT:
+ case XSConstants.UNSIGNEDBYTE_DT:
+ case XSConstants.POSITIVEINTEGER_DT:
+ propertyType = CrAttributeType.LONG;
+ break;
+ case XSConstants.LISTOFUNION_DT:
+ case XSConstants.LIST_DT:
+ case XSConstants.UNAVAILABLE_DT:
+ propertyType = CrAttributeType.STRING;
+ break;
+ default:
+ propertyType = CrAttributeType.STRING;
+ break;