// find if a datatype validator is a list or has list datatype member. private boolean isListDatatype(XSSimpleType validator) { if (validator.getVariety() == XSSimpleType.VARIETY_LIST) return true; if (validator.getVariety() == XSSimpleType.VARIETY_UNION) { XSObjectList temp = validator.getMemberTypes(); for (int i = 0; i < temp.getLength(); i++) { if (((XSSimpleType) temp.item(i)).getVariety() == XSSimpleType.VARIETY_LIST) { return true; } } } return false; } // isListDatatype(XSSimpleTypeDecl):boolean
private XSSimpleType traverseSimpleTypeDecl( Element simpleTypeDecl, Object[] attrValues, XSDocumentInfo schemaDoc, SchemaGrammar grammar) { // get name and final values String name = (String) attrValues[XSAttributeChecker.ATTIDX_NAME]; XInt finalAttr = (XInt) attrValues[XSAttributeChecker.ATTIDX_FINAL]; int finalProperty = finalAttr == null ? schemaDoc.fFinalDefault : finalAttr.intValue(); // annotation?,(list|restriction|union) Element child = DOMUtil.getFirstChildElement(simpleTypeDecl); XSAnnotationImpl[] annotations = null; if (child != null) { // traverse annotation if any if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { XSAnnotationImpl annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc); if (annotation != null) annotations = new XSAnnotationImpl[] {annotation}; child = DOMUtil.getNextSiblingElement(child); } } // (list|restriction|union) if (child == null) { reportSchemaError( "s4s-elt-must-match.2", new Object[] { SchemaSymbols.ELT_SIMPLETYPE, "(annotation?, (restriction | list | union))" }, simpleTypeDecl); return errorType(name, schemaDoc.fTargetNamespace, XSConstants.DERIVATION_RESTRICTION); } // derivation type: restriction/list/union String varietyProperty = DOMUtil.getLocalName(child); short refType = XSConstants.DERIVATION_RESTRICTION; boolean restriction = false, list = false, union = false; if (varietyProperty.equals(SchemaSymbols.ELT_RESTRICTION)) { refType = XSConstants.DERIVATION_RESTRICTION; restriction = true; } else if (varietyProperty.equals(SchemaSymbols.ELT_LIST)) { refType = XSConstants.DERIVATION_LIST; list = true; } else if (varietyProperty.equals(SchemaSymbols.ELT_UNION)) { refType = XSConstants.DERIVATION_UNION; union = true; } else { reportSchemaError( "s4s-elt-must-match.1", new Object[] { SchemaSymbols.ELT_SIMPLETYPE, "(annotation?, (restriction | list | union))", varietyProperty }, simpleTypeDecl); return errorType(name, schemaDoc.fTargetNamespace, XSConstants.DERIVATION_RESTRICTION); } // nothing should follow this element Element nextChild = DOMUtil.getNextSiblingElement(child); if (nextChild != null) { reportSchemaError( "s4s-elt-must-match.1", new Object[] { SchemaSymbols.ELT_SIMPLETYPE, "(annotation?, (restriction | list | union))", DOMUtil.getLocalName(nextChild) }, nextChild); } // General Attribute Checking: get base/item/member types Object[] contentAttrs = fAttrChecker.checkAttributes(child, false, schemaDoc); QName baseTypeName = (QName) contentAttrs[ restriction ? XSAttributeChecker.ATTIDX_BASE : XSAttributeChecker.ATTIDX_ITEMTYPE]; Vector memberTypes = (Vector) contentAttrs[XSAttributeChecker.ATTIDX_MEMBERTYPES]; // content = {annotation?,simpleType?...} Element content = DOMUtil.getFirstChildElement(child); // check content (annotation?, ...) if (content != null) { // traverse annotation if any if (DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_ANNOTATION)) { XSAnnotationImpl annotation = traverseAnnotationDecl(content, contentAttrs, false, schemaDoc); if (annotation != null) { if (annotations == null) annotations = new XSAnnotationImpl[] {annotation}; else { XSAnnotationImpl[] tempArray = new XSAnnotationImpl[2]; tempArray[0] = annotations[0]; annotations = tempArray; annotations[1] = annotation; } } content = DOMUtil.getNextSiblingElement(content); } } // get base type from "base" attribute XSSimpleType baseValidator = null; if ((restriction || list) && baseTypeName != null) { baseValidator = findDTValidator(child, name, baseTypeName, refType, schemaDoc); // if its the built-in type, return null from here if (baseValidator == null && fIsBuiltIn) { fIsBuiltIn = false; return null; } } // get types from "memberTypes" attribute Vector dTValidators = null; XSSimpleType dv = null; XSObjectList dvs; if (union && memberTypes != null && memberTypes.size() > 0) { int size = memberTypes.size(); dTValidators = new Vector(size, 2); // for each qname in the list for (int i = 0; i < size; i++) { // get the type decl dv = findDTValidator( child, name, (QName) memberTypes.elementAt(i), XSConstants.DERIVATION_UNION, schemaDoc); if (dv != null) { // if it's a union, expand it if (dv.getVariety() == XSSimpleType.VARIETY_UNION) { dvs = dv.getMemberTypes(); for (int j = 0; j < dvs.getLength(); j++) dTValidators.addElement(dvs.item(j)); } else { dTValidators.addElement(dv); } } } } // when there is an error finding the base type of a restriction // we use anySimpleType as the base, then we should skip the facets, // because anySimpleType doesn't recognize any facet. boolean skipFacets = false; // check if there is a child "simpleType" if (content != null && DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_SIMPLETYPE)) { if (restriction || list) { // it's an error for both "base" and "simpleType" to appear if (baseTypeName != null) { reportSchemaError(list ? "src-simple-type.3.a" : "src-simple-type.2.a", null, content); } else { // traver this child to get the base type baseValidator = traverseLocal(content, schemaDoc, grammar); } // get the next element content = DOMUtil.getNextSiblingElement(content); } else if (union) { if (dTValidators == null) { dTValidators = new Vector(2, 2); } do { // traver this child to get the member type dv = traverseLocal(content, schemaDoc, grammar); if (dv != null) { // if it's a union, expand it if (dv.getVariety() == XSSimpleType.VARIETY_UNION) { dvs = dv.getMemberTypes(); for (int j = 0; j < dvs.getLength(); j++) dTValidators.addElement(dvs.item(j)); } else { dTValidators.addElement(dv); } } // get the next element content = DOMUtil.getNextSiblingElement(content); } while (content != null && DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_SIMPLETYPE)); } } else if ((restriction || list) && baseTypeName == null) { // it's an error if neither "base" nor "simpleType" appears reportSchemaError(list ? "src-simple-type.3.b" : "src-simple-type.2.b", null, child); // base can't be found, skip the facets. skipFacets = true; baseValidator = SchemaGrammar.fAnySimpleType; } else if (union && (memberTypes == null || memberTypes.size() == 0)) { // it's an error if "memberTypes" is empty and no "simpleType" appears reportSchemaError("src-union-memberTypes-or-simpleTypes", null, child); dTValidators = new Vector(1); dTValidators.addElement(SchemaGrammar.fAnySimpleType); } // error finding "base" or error traversing "simpleType". // don't need to report an error, since some error has been reported. if ((restriction || list) && baseValidator == null) { baseValidator = SchemaGrammar.fAnySimpleType; } // error finding "memberTypes" or error traversing "simpleType". // don't need to report an error, since some error has been reported. if (union && (dTValidators == null || dTValidators.size() == 0)) { dTValidators = new Vector(1); dTValidators.addElement(SchemaGrammar.fAnySimpleType); } // item type of list types can't have list content if (list && isListDatatype(baseValidator)) { reportSchemaError( "cos-st-restricts.2.1", new Object[] {name, baseValidator.getName()}, child); } // create the simple type based on the "base" type XSSimpleType newDecl = null; if (restriction) { newDecl = schemaFactory.createTypeRestriction( name, schemaDoc.fTargetNamespace, (short) finalProperty, baseValidator, annotations == null ? null : new XSObjectListImpl(annotations, annotations.length)); } else if (list) { newDecl = schemaFactory.createTypeList( name, schemaDoc.fTargetNamespace, (short) finalProperty, baseValidator, annotations == null ? null : new XSObjectListImpl(annotations, annotations.length)); } else if (union) { XSSimpleType[] memberDecls = new XSSimpleType[dTValidators.size()]; for (int i = 0; i < dTValidators.size(); i++) memberDecls[i] = (XSSimpleType) dTValidators.elementAt(i); newDecl = schemaFactory.createTypeUnion( name, schemaDoc.fTargetNamespace, (short) finalProperty, memberDecls, annotations == null ? null : new XSObjectListImpl(annotations, annotations.length)); } // now traverse facets, if it's derived by restriction if (restriction && content != null) { FacetInfo fi = traverseFacets(content, baseValidator, schemaDoc); content = fi.nodeAfterFacets; if (!skipFacets) { try { fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport); newDecl.applyFacets(fi.facetdata, fi.fPresentFacets, fi.fFixedFacets, fValidationState); } catch (InvalidDatatypeFacetException ex) { reportSchemaError(ex.getKey(), ex.getArgs(), child); } } } // now element should appear after this point if (content != null) { if (restriction) { reportSchemaError( "s4s-elt-must-match.1", new Object[] { SchemaSymbols.ELT_RESTRICTION, "(annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*))", DOMUtil.getLocalName(content) }, content); } else if (list) { reportSchemaError( "s4s-elt-must-match.1", new Object[] { SchemaSymbols.ELT_LIST, "(annotation?, (simpleType?))", DOMUtil.getLocalName(content) }, content); } else if (union) { reportSchemaError( "s4s-elt-must-match.1", new Object[] { SchemaSymbols.ELT_UNION, "(annotation?, (simpleType*))", DOMUtil.getLocalName(content) }, content); } } fAttrChecker.returnAttrArray(contentAttrs, schemaDoc); // return the new type return newDecl; }