// 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;
  }
예제 #3
0
 /** Optional. Annotation. */
 public XSAnnotation getAnnotation() {
   return (fAnnotations != null) ? (XSAnnotation) fAnnotations.item(0) : null;
 }