0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package org.apache.xerces.impl.dv.xs;
0019:
0020: import java.util.StringTokenizer;
0021: import java.util.Vector;
0022:
0023: import org.apache.xerces.impl.Constants;
0024: import org.apache.xerces.impl.dv.DatatypeException;
0025: import org.apache.xerces.impl.dv.InvalidDatatypeFacetException;
0026: import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
0027: import org.apache.xerces.impl.dv.ValidatedInfo;
0028: import org.apache.xerces.impl.dv.ValidationContext;
0029: import org.apache.xerces.impl.dv.XSFacets;
0030: import org.apache.xerces.impl.dv.XSSimpleType;
0031: import org.apache.xerces.impl.xpath.regex.RegularExpression;
0032: import org.apache.xerces.impl.xs.SchemaSymbols;
0033: import org.apache.xerces.impl.xs.util.ShortListImpl;
0034: import org.apache.xerces.impl.xs.util.StringListImpl;
0035: import org.apache.xerces.impl.xs.util.XSObjectListImpl;
0036: import org.apache.xerces.util.XMLChar;
0037: import org.apache.xerces.xni.NamespaceContext;
0038: import org.apache.xerces.xs.ShortList;
0039: import org.apache.xerces.xs.StringList;
0040: import org.apache.xerces.xs.XSAnnotation;
0041: import org.apache.xerces.xs.XSConstants;
0042: import org.apache.xerces.xs.XSFacet;
0043: import org.apache.xerces.xs.XSMultiValueFacet;
0044: import org.apache.xerces.xs.XSNamespaceItem;
0045: import org.apache.xerces.xs.XSObjectList;
0046: import org.apache.xerces.xs.XSSimpleTypeDefinition;
0047: import org.apache.xerces.xs.XSTypeDefinition;
0048: import org.apache.xerces.xs.datatypes.ObjectList;
0049: import org.w3c.dom.TypeInfo;
0050:
0051: /**
0052: * @xerces.internal
0053: *
0054: * @author Sandy Gao, IBM
0055: * @author Neeraj Bajaj, Sun Microsystems, inc.
0056: *
0057: * @version $Id: XSSimpleTypeDecl.java 548093 2007-06-17 18:36:08Z mrglavas $
0058: */
0059: public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo {
0060:
0061: static final short DV_STRING = PRIMITIVE_STRING;
0062: static final short DV_BOOLEAN = PRIMITIVE_BOOLEAN;
0063: static final short DV_DECIMAL = PRIMITIVE_DECIMAL;
0064: static final short DV_FLOAT = PRIMITIVE_FLOAT;
0065: static final short DV_DOUBLE = PRIMITIVE_DOUBLE;
0066: static final short DV_DURATION = PRIMITIVE_DURATION;
0067: static final short DV_DATETIME = PRIMITIVE_DATETIME;
0068: static final short DV_TIME = PRIMITIVE_TIME;
0069: static final short DV_DATE = PRIMITIVE_DATE;
0070: static final short DV_GYEARMONTH = PRIMITIVE_GYEARMONTH;
0071: static final short DV_GYEAR = PRIMITIVE_GYEAR;
0072: static final short DV_GMONTHDAY = PRIMITIVE_GMONTHDAY;
0073: static final short DV_GDAY = PRIMITIVE_GDAY;
0074: static final short DV_GMONTH = PRIMITIVE_GMONTH;
0075: static final short DV_HEXBINARY = PRIMITIVE_HEXBINARY;
0076: static final short DV_BASE64BINARY = PRIMITIVE_BASE64BINARY;
0077: static final short DV_ANYURI = PRIMITIVE_ANYURI;
0078: static final short DV_QNAME = PRIMITIVE_QNAME;
0079: static final short DV_PRECISIONDECIMAL = PRIMITIVE_PRECISIONDECIMAL;
0080: static final short DV_NOTATION = PRIMITIVE_NOTATION;
0081:
0082: static final short DV_ANYSIMPLETYPE = 0;
0083: static final short DV_ID = DV_NOTATION + 1;
0084: static final short DV_IDREF = DV_NOTATION + 2;
0085: static final short DV_ENTITY = DV_NOTATION + 3;
0086: static final short DV_INTEGER = DV_NOTATION + 4;
0087: static final short DV_LIST = DV_NOTATION + 5;
0088: static final short DV_UNION = DV_NOTATION + 6;
0089: static final short DV_YEARMONTHDURATION = DV_NOTATION + 7;
0090: static final short DV_DAYTIMEDURATION = DV_NOTATION + 8;
0091: static final short DV_ANYATOMICTYPE = DV_NOTATION + 9;
0092:
0093: static final TypeValidator[] fDVs = { new AnySimpleDV(),
0094: new StringDV(), new BooleanDV(), new DecimalDV(),
0095: new FloatDV(), new DoubleDV(), new DurationDV(),
0096: new DateTimeDV(), new TimeDV(), new DateDV(),
0097: new YearMonthDV(), new YearDV(), new MonthDayDV(),
0098: new DayDV(), new MonthDV(), new HexBinaryDV(),
0099: new Base64BinaryDV(), new AnyURIDV(),
0100: new QNameDV(),
0101: new PrecisionDecimalDV(), // XML Schema 1.1 type
0102: new QNameDV(), // notation use the same one as qname
0103: new IDDV(), new IDREFDV(), new EntityDV(), new IntegerDV(),
0104: new ListDV(), new UnionDV(), new YearMonthDurationDV(), // XML Schema 1.1 type
0105: new DayTimeDurationDV(), // XML Schema 1.1 type
0106: new AnyAtomicDV() // XML Schema 1.1 type
0107: };
0108:
0109: static final short NORMALIZE_NONE = 0;
0110: static final short NORMALIZE_TRIM = 1;
0111: static final short NORMALIZE_FULL = 2;
0112: static final short[] fDVNormalizeType = { NORMALIZE_NONE, //AnySimpleDV(),
0113: NORMALIZE_FULL, //StringDV(),
0114: NORMALIZE_TRIM, //BooleanDV(),
0115: NORMALIZE_TRIM, //DecimalDV(),
0116: NORMALIZE_TRIM, //FloatDV(),
0117: NORMALIZE_TRIM, //DoubleDV(),
0118: NORMALIZE_TRIM, //DurationDV(),
0119: NORMALIZE_TRIM, //DateTimeDV(),
0120: NORMALIZE_TRIM, //TimeDV(),
0121: NORMALIZE_TRIM, //DateDV(),
0122: NORMALIZE_TRIM, //YearMonthDV(),
0123: NORMALIZE_TRIM, //YearDV(),
0124: NORMALIZE_TRIM, //MonthDayDV(),
0125: NORMALIZE_TRIM, //DayDV(),
0126: NORMALIZE_TRIM, //MonthDV(),
0127: NORMALIZE_TRIM, //HexBinaryDV(),
0128: NORMALIZE_NONE, //Base64BinaryDV(), // Base64 know how to deal with spaces
0129: NORMALIZE_TRIM, //AnyURIDV(),
0130: NORMALIZE_TRIM, //QNameDV(),
0131: NORMALIZE_TRIM, //PrecisionDecimalDV() (Schema 1.1)
0132: NORMALIZE_TRIM, //QNameDV(), // notation
0133: NORMALIZE_TRIM, //IDDV(),
0134: NORMALIZE_TRIM, //IDREFDV(),
0135: NORMALIZE_TRIM, //EntityDV(),
0136: NORMALIZE_TRIM, //IntegerDV(),
0137: NORMALIZE_FULL, //ListDV(),
0138: NORMALIZE_NONE, //UnionDV(),
0139: NORMALIZE_TRIM, //YearMonthDurationDV() (Schema 1.1)
0140: NORMALIZE_TRIM, //DayTimeDurationDV() (Schema 1.1)
0141: NORMALIZE_NONE, //AnyAtomicDV() (Schema 1.1)
0142: };
0143:
0144: static final short SPECIAL_PATTERN_NONE = 0;
0145: static final short SPECIAL_PATTERN_NMTOKEN = 1;
0146: static final short SPECIAL_PATTERN_NAME = 2;
0147: static final short SPECIAL_PATTERN_NCNAME = 3;
0148:
0149: static final String[] SPECIAL_PATTERN_STRING = { "NONE", "NMTOKEN",
0150: "Name", "NCName" };
0151:
0152: static final String[] WS_FACET_STRING = { "preserve", "replace",
0153: "collapse" };
0154:
0155: static final String URI_SCHEMAFORSCHEMA = "http://www.w3.org/2001/XMLSchema";
0156: static final String ANY_TYPE = "anyType";
0157:
0158: // XML Schema 1.1 type constants
0159: public static final short YEARMONTHDURATION_DT = 46;
0160: public static final short DAYTIMEDURATION_DT = 47;
0161: public static final short PRECISIONDECIMAL_DT = 48;
0162: public static final short ANYATOMICTYPE_DT = 49;
0163:
0164: // DOM Level 3 TypeInfo Derivation Method constants
0165: static final int DERIVATION_ANY = 0;
0166: static final int DERIVATION_RESTRICTION = 1;
0167: static final int DERIVATION_EXTENSION = 2;
0168: static final int DERIVATION_UNION = 4;
0169: static final int DERIVATION_LIST = 8;
0170:
0171: static final ValidationContext fEmptyContext = new ValidationContext() {
0172: public boolean needFacetChecking() {
0173: return true;
0174: }
0175:
0176: public boolean needExtraChecking() {
0177: return false;
0178: }
0179:
0180: public boolean needToNormalize() {
0181: return true;
0182: }
0183:
0184: public boolean useNamespaces() {
0185: return true;
0186: }
0187:
0188: public boolean isEntityDeclared(String name) {
0189: return false;
0190: }
0191:
0192: public boolean isEntityUnparsed(String name) {
0193: return false;
0194: }
0195:
0196: public boolean isIdDeclared(String name) {
0197: return false;
0198: }
0199:
0200: public void addId(String name) {
0201: }
0202:
0203: public void addIdRef(String name) {
0204: }
0205:
0206: public String getSymbol(String symbol) {
0207: return symbol.intern();
0208: }
0209:
0210: public String getURI(String prefix) {
0211: return null;
0212: }
0213: };
0214:
0215: // this will be true if this is a static XSSimpleTypeDecl
0216: // and hence must remain immutable (i.e., applyFacets
0217: // may not be permitted to have any effect).
0218: private boolean fIsImmutable = false;
0219:
0220: private XSSimpleTypeDecl fItemType;
0221: private XSSimpleTypeDecl[] fMemberTypes;
0222: // The most specific built-in type kind.
0223: private short fBuiltInKind;
0224:
0225: private String fTypeName;
0226: private String fTargetNamespace;
0227: private short fFinalSet = 0;
0228: private XSSimpleTypeDecl fBase;
0229: private short fVariety = -1;
0230: private short fValidationDV = -1;
0231:
0232: private short fFacetsDefined = 0;
0233: private short fFixedFacet = 0;
0234:
0235: //for constraining facets
0236: private short fWhiteSpace = 0;
0237: private int fLength = -1;
0238: private int fMinLength = -1;
0239: private int fMaxLength = -1;
0240: private int fTotalDigits = -1;
0241: private int fFractionDigits = -1;
0242: private Vector fPattern;
0243: private Vector fPatternStr;
0244: private Vector fEnumeration;
0245: private short[] fEnumerationType;
0246: private ShortList[] fEnumerationItemType; // used in case fenumerationType value is LIST or LISTOFUNION
0247: private ShortList fEnumerationTypeList;
0248: private ObjectList fEnumerationItemTypeList;
0249: private StringList fLexicalPattern;
0250: private StringList fLexicalEnumeration;
0251: private ObjectList fActualEnumeration;
0252: private Object fMaxInclusive;
0253: private Object fMaxExclusive;
0254: private Object fMinExclusive;
0255: private Object fMinInclusive;
0256:
0257: // annotations for constraining facets
0258: public XSAnnotation lengthAnnotation;
0259: public XSAnnotation minLengthAnnotation;
0260: public XSAnnotation maxLengthAnnotation;
0261: public XSAnnotation whiteSpaceAnnotation;
0262: public XSAnnotation totalDigitsAnnotation;
0263: public XSAnnotation fractionDigitsAnnotation;
0264: public XSObjectListImpl patternAnnotations;
0265: public XSObjectList enumerationAnnotations;
0266: public XSAnnotation maxInclusiveAnnotation;
0267: public XSAnnotation maxExclusiveAnnotation;
0268: public XSAnnotation minInclusiveAnnotation;
0269: public XSAnnotation minExclusiveAnnotation;
0270:
0271: // facets as objects
0272: private XSObjectListImpl fFacets;
0273:
0274: // enumeration and pattern facets
0275: private XSObjectListImpl fMultiValueFacets;
0276:
0277: // simpleType annotations
0278: private XSObjectList fAnnotations = null;
0279:
0280: private short fPatternType = SPECIAL_PATTERN_NONE;
0281:
0282: // for fundamental facets
0283: private short fOrdered;
0284: private boolean fFinite;
0285: private boolean fBounded;
0286: private boolean fNumeric;
0287:
0288: // default constructor
0289: public XSSimpleTypeDecl() {
0290: }
0291:
0292: //Create a new built-in primitive types (and id/idref/entity/integer/yearMonthDuration)
0293: protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name,
0294: short validateDV, short ordered, boolean bounded,
0295: boolean finite, boolean numeric, boolean isImmutable,
0296: short builtInKind) {
0297: fIsImmutable = isImmutable;
0298: fBase = base;
0299: fTypeName = name;
0300: fTargetNamespace = URI_SCHEMAFORSCHEMA;
0301: // To simplify the code for anySimpleType, we treat it as an atomic type
0302: fVariety = VARIETY_ATOMIC;
0303: fValidationDV = validateDV;
0304: fFacetsDefined = FACET_WHITESPACE;
0305: if (validateDV == DV_STRING) {
0306: fWhiteSpace = WS_PRESERVE;
0307: } else {
0308: fWhiteSpace = WS_COLLAPSE;
0309: fFixedFacet = FACET_WHITESPACE;
0310: }
0311: this .fOrdered = ordered;
0312: this .fBounded = bounded;
0313: this .fFinite = finite;
0314: this .fNumeric = numeric;
0315: fAnnotations = null;
0316:
0317: // Specify the build in kind for this primitive type
0318: fBuiltInKind = builtInKind;
0319: }
0320:
0321: //Create a new simple type for restriction for built-in types
0322: protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name,
0323: String uri, short finalSet, boolean isImmutable,
0324: XSObjectList annotations, short builtInKind) {
0325: this (base, name, uri, finalSet, isImmutable, annotations);
0326: // Specify the build in kind for this built-in type
0327: fBuiltInKind = builtInKind;
0328: }
0329:
0330: //Create a new simple type for restriction.
0331: protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name,
0332: String uri, short finalSet, boolean isImmutable,
0333: XSObjectList annotations) {
0334: fBase = base;
0335: fTypeName = name;
0336: fTargetNamespace = uri;
0337: fFinalSet = finalSet;
0338: fAnnotations = annotations;
0339:
0340: fVariety = fBase.fVariety;
0341: fValidationDV = fBase.fValidationDV;
0342: switch (fVariety) {
0343: case VARIETY_ATOMIC:
0344: break;
0345: case VARIETY_LIST:
0346: fItemType = fBase.fItemType;
0347: break;
0348: case VARIETY_UNION:
0349: fMemberTypes = fBase.fMemberTypes;
0350: break;
0351: }
0352:
0353: // always inherit facets from the base.
0354: // in case a type is created, but applyFacets is not called
0355: fLength = fBase.fLength;
0356: fMinLength = fBase.fMinLength;
0357: fMaxLength = fBase.fMaxLength;
0358: fPattern = fBase.fPattern;
0359: fPatternStr = fBase.fPatternStr;
0360: fEnumeration = fBase.fEnumeration;
0361: fEnumerationType = fBase.fEnumerationType;
0362: fEnumerationItemType = fBase.fEnumerationItemType;
0363: fWhiteSpace = fBase.fWhiteSpace;
0364: fMaxExclusive = fBase.fMaxExclusive;
0365: fMaxInclusive = fBase.fMaxInclusive;
0366: fMinExclusive = fBase.fMinExclusive;
0367: fMinInclusive = fBase.fMinInclusive;
0368: fTotalDigits = fBase.fTotalDigits;
0369: fFractionDigits = fBase.fFractionDigits;
0370: fPatternType = fBase.fPatternType;
0371: fFixedFacet = fBase.fFixedFacet;
0372: fFacetsDefined = fBase.fFacetsDefined;
0373:
0374: // always inherit facet annotations in case applyFacets is not called.
0375: lengthAnnotation = fBase.lengthAnnotation;
0376: minLengthAnnotation = fBase.minLengthAnnotation;
0377: maxLengthAnnotation = fBase.maxLengthAnnotation;
0378: patternAnnotations = fBase.patternAnnotations;
0379: enumerationAnnotations = fBase.enumerationAnnotations;
0380: whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
0381: maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
0382: maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
0383: minExclusiveAnnotation = fBase.minExclusiveAnnotation;
0384: minInclusiveAnnotation = fBase.minInclusiveAnnotation;
0385: totalDigitsAnnotation = fBase.totalDigitsAnnotation;
0386: fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;
0387:
0388: //we also set fundamental facets information in case applyFacets is not called.
0389: calcFundamentalFacets();
0390: fIsImmutable = isImmutable;
0391:
0392: // Inherit from the base type
0393: fBuiltInKind = base.fBuiltInKind;
0394: }
0395:
0396: //Create a new simple type for list.
0397: protected XSSimpleTypeDecl(String name, String uri, short finalSet,
0398: XSSimpleTypeDecl itemType, boolean isImmutable,
0399: XSObjectList annotations) {
0400: fBase = fAnySimpleType;
0401: fTypeName = name;
0402: fTargetNamespace = uri;
0403: fFinalSet = finalSet;
0404: fAnnotations = annotations;
0405:
0406: fVariety = VARIETY_LIST;
0407: fItemType = (XSSimpleTypeDecl) itemType;
0408: fValidationDV = DV_LIST;
0409: fFacetsDefined = FACET_WHITESPACE;
0410: fFixedFacet = FACET_WHITESPACE;
0411: fWhiteSpace = WS_COLLAPSE;
0412:
0413: //setting fundamental facets
0414: calcFundamentalFacets();
0415: fIsImmutable = isImmutable;
0416:
0417: // Values of this type are lists
0418: fBuiltInKind = XSConstants.LIST_DT;
0419: }
0420:
0421: //Create a new simple type for union.
0422: protected XSSimpleTypeDecl(String name, String uri, short finalSet,
0423: XSSimpleTypeDecl[] memberTypes, XSObjectList annotations) {
0424: fBase = fAnySimpleType;
0425: fTypeName = name;
0426: fTargetNamespace = uri;
0427: fFinalSet = finalSet;
0428: fAnnotations = annotations;
0429:
0430: fVariety = VARIETY_UNION;
0431: fMemberTypes = memberTypes;
0432: fValidationDV = DV_UNION;
0433: // even for union, we set whitespace to something
0434: // this will never be used, but we can use fFacetsDefined to check
0435: // whether applyFacets() is allwwed: it's not allowed
0436: // if fFacetsDefined != 0
0437: fFacetsDefined = FACET_WHITESPACE;
0438: fWhiteSpace = WS_COLLAPSE;
0439:
0440: //setting fundamental facets
0441: calcFundamentalFacets();
0442: // none of the schema-defined types are unions, so just set
0443: // fIsImmutable to false.
0444: fIsImmutable = false;
0445:
0446: // No value can be of this type, so it's unavailable.
0447: fBuiltInKind = XSConstants.UNAVAILABLE_DT;
0448: }
0449:
0450: //set values for restriction.
0451: protected XSSimpleTypeDecl setRestrictionValues(
0452: XSSimpleTypeDecl base, String name, String uri,
0453: short finalSet, XSObjectList annotations) {
0454: //decline to do anything if the object is immutable.
0455: if (fIsImmutable)
0456: return null;
0457: fBase = base;
0458: fTypeName = name;
0459: fTargetNamespace = uri;
0460: fFinalSet = finalSet;
0461: fAnnotations = annotations;
0462:
0463: fVariety = fBase.fVariety;
0464: fValidationDV = fBase.fValidationDV;
0465: switch (fVariety) {
0466: case VARIETY_ATOMIC:
0467: break;
0468: case VARIETY_LIST:
0469: fItemType = fBase.fItemType;
0470: break;
0471: case VARIETY_UNION:
0472: fMemberTypes = fBase.fMemberTypes;
0473: break;
0474: }
0475:
0476: // always inherit facets from the base.
0477: // in case a type is created, but applyFacets is not called
0478: fLength = fBase.fLength;
0479: fMinLength = fBase.fMinLength;
0480: fMaxLength = fBase.fMaxLength;
0481: fPattern = fBase.fPattern;
0482: fPatternStr = fBase.fPatternStr;
0483: fEnumeration = fBase.fEnumeration;
0484: fEnumerationType = fBase.fEnumerationType;
0485: fEnumerationItemType = fBase.fEnumerationItemType;
0486: fWhiteSpace = fBase.fWhiteSpace;
0487: fMaxExclusive = fBase.fMaxExclusive;
0488: fMaxInclusive = fBase.fMaxInclusive;
0489: fMinExclusive = fBase.fMinExclusive;
0490: fMinInclusive = fBase.fMinInclusive;
0491: fTotalDigits = fBase.fTotalDigits;
0492: fFractionDigits = fBase.fFractionDigits;
0493: fPatternType = fBase.fPatternType;
0494: fFixedFacet = fBase.fFixedFacet;
0495: fFacetsDefined = fBase.fFacetsDefined;
0496:
0497: //we also set fundamental facets information in case applyFacets is not called.
0498: calcFundamentalFacets();
0499:
0500: // Inherit from the base type
0501: fBuiltInKind = base.fBuiltInKind;
0502:
0503: return this ;
0504: }
0505:
0506: //set values for list.
0507: protected XSSimpleTypeDecl setListValues(String name, String uri,
0508: short finalSet, XSSimpleTypeDecl itemType,
0509: XSObjectList annotations) {
0510: //decline to do anything if the object is immutable.
0511: if (fIsImmutable)
0512: return null;
0513: fBase = fAnySimpleType;
0514: fTypeName = name;
0515: fTargetNamespace = uri;
0516: fFinalSet = finalSet;
0517: fAnnotations = annotations;
0518:
0519: fVariety = VARIETY_LIST;
0520: fItemType = (XSSimpleTypeDecl) itemType;
0521: fValidationDV = DV_LIST;
0522: fFacetsDefined = FACET_WHITESPACE;
0523: fFixedFacet = FACET_WHITESPACE;
0524: fWhiteSpace = WS_COLLAPSE;
0525:
0526: //setting fundamental facets
0527: calcFundamentalFacets();
0528:
0529: // Values of this type are lists
0530: fBuiltInKind = XSConstants.LIST_DT;
0531:
0532: return this ;
0533: }
0534:
0535: //set values for union.
0536: protected XSSimpleTypeDecl setUnionValues(String name, String uri,
0537: short finalSet, XSSimpleTypeDecl[] memberTypes,
0538: XSObjectList annotations) {
0539: //decline to do anything if the object is immutable.
0540: if (fIsImmutable)
0541: return null;
0542: fBase = fAnySimpleType;
0543: fTypeName = name;
0544: fTargetNamespace = uri;
0545: fFinalSet = finalSet;
0546: fAnnotations = annotations;
0547:
0548: fVariety = VARIETY_UNION;
0549: fMemberTypes = memberTypes;
0550: fValidationDV = DV_UNION;
0551: // even for union, we set whitespace to something
0552: // this will never be used, but we can use fFacetsDefined to check
0553: // whether applyFacets() is allwwed: it's not allowed
0554: // if fFacetsDefined != 0
0555: fFacetsDefined = FACET_WHITESPACE;
0556: fWhiteSpace = WS_COLLAPSE;
0557:
0558: //setting fundamental facets
0559: calcFundamentalFacets();
0560:
0561: // No value can be of this type, so it's unavailable.
0562: fBuiltInKind = XSConstants.UNAVAILABLE_DT;
0563:
0564: return this ;
0565: }
0566:
0567: public short getType() {
0568: return XSConstants.TYPE_DEFINITION;
0569: }
0570:
0571: public short getTypeCategory() {
0572: return SIMPLE_TYPE;
0573: }
0574:
0575: public String getName() {
0576: return getAnonymous() ? null : fTypeName;
0577: }
0578:
0579: public String getTypeName() {
0580: return fTypeName;
0581: }
0582:
0583: public String getNamespace() {
0584: return fTargetNamespace;
0585: }
0586:
0587: public short getFinal() {
0588: return fFinalSet;
0589: }
0590:
0591: public boolean isFinal(short derivation) {
0592: return (fFinalSet & derivation) != 0;
0593: }
0594:
0595: public XSTypeDefinition getBaseType() {
0596: return fBase;
0597: }
0598:
0599: public boolean getAnonymous() {
0600: return fAnonymous || (fTypeName == null);
0601: }
0602:
0603: public short getVariety() {
0604: // for anySimpleType, return absent variaty
0605: return fValidationDV == DV_ANYSIMPLETYPE ? VARIETY_ABSENT
0606: : fVariety;
0607: }
0608:
0609: public boolean isIDType() {
0610: switch (fVariety) {
0611: case VARIETY_ATOMIC:
0612: return fValidationDV == DV_ID;
0613: case VARIETY_LIST:
0614: return fItemType.isIDType();
0615: case VARIETY_UNION:
0616: for (int i = 0; i < fMemberTypes.length; i++) {
0617: if (fMemberTypes[i].isIDType())
0618: return true;
0619: }
0620: }
0621: return false;
0622: }
0623:
0624: public short getWhitespace() throws DatatypeException {
0625: if (fVariety == VARIETY_UNION) {
0626: throw new DatatypeException("dt-whitespace",
0627: new Object[] { fTypeName });
0628: }
0629: return fWhiteSpace;
0630: }
0631:
0632: public short getPrimitiveKind() {
0633: if (fVariety == VARIETY_ATOMIC
0634: && fValidationDV != DV_ANYSIMPLETYPE) {
0635: if (fValidationDV == DV_ID || fValidationDV == DV_IDREF
0636: || fValidationDV == DV_ENTITY) {
0637: return DV_STRING;
0638: } else if (fValidationDV == DV_INTEGER) {
0639: return DV_DECIMAL;
0640: } else if (Constants.SCHEMA_1_1_SUPPORT
0641: && (fValidationDV == DV_YEARMONTHDURATION || fValidationDV == DV_DAYTIMEDURATION)) {
0642: return DV_DURATION;
0643: } else {
0644: return fValidationDV;
0645: }
0646: } else {
0647: // REVISIT: error situation. runtime exception?
0648: return (short) 0;
0649: }
0650: }
0651:
0652: /**
0653: * Returns the closest built-in type category this type represents or
0654: * derived from. For example, if this simple type is a built-in derived
0655: * type integer the <code>INTEGER_DV</code> is returned.
0656: */
0657: public short getBuiltInKind() {
0658: return this .fBuiltInKind;
0659: }
0660:
0661: /**
0662: * If variety is <code>atomic</code> the primitive type definition (a
0663: * built-in primitive datatype definition or the simple ur-type
0664: * definition) is available, otherwise <code>null</code>.
0665: */
0666: public XSSimpleTypeDefinition getPrimitiveType() {
0667: if (fVariety == VARIETY_ATOMIC
0668: && fValidationDV != DV_ANYSIMPLETYPE) {
0669: XSSimpleTypeDecl pri = this ;
0670: // recursively get base, until we reach anySimpleType
0671: while (pri.fBase != fAnySimpleType)
0672: pri = pri.fBase;
0673: return pri;
0674: } else {
0675: // REVISIT: error situation. runtime exception?
0676: return null;
0677: }
0678: }
0679:
0680: /**
0681: * If variety is <code>list</code> the item type definition (an atomic or
0682: * union simple type definition) is available, otherwise
0683: * <code>null</code>.
0684: */
0685: public XSSimpleTypeDefinition getItemType() {
0686: if (fVariety == VARIETY_LIST) {
0687: return fItemType;
0688: } else {
0689: // REVISIT: error situation. runtime exception?
0690: return null;
0691: }
0692: }
0693:
0694: /**
0695: * If variety is <code>union</code> the list of member type definitions (a
0696: * non-empty sequence of simple type definitions) is available,
0697: * otherwise an empty <code>XSObjectList</code>.
0698: */
0699: public XSObjectList getMemberTypes() {
0700: if (fVariety == VARIETY_UNION) {
0701: return new XSObjectListImpl(fMemberTypes,
0702: fMemberTypes.length);
0703: } else {
0704: return XSObjectListImpl.EMPTY_LIST;
0705: }
0706: }
0707:
0708: /**
0709: * If <restriction> is chosen
0710: */
0711: public void applyFacets(XSFacets facets, short presentFacet,
0712: short fixedFacet, ValidationContext context)
0713: throws InvalidDatatypeFacetException {
0714: applyFacets(facets, presentFacet, fixedFacet,
0715: SPECIAL_PATTERN_NONE, context);
0716: }
0717:
0718: /**
0719: * built-in derived types by restriction
0720: */
0721: void applyFacets1(XSFacets facets, short presentFacet,
0722: short fixedFacet) {
0723:
0724: try {
0725: applyFacets(facets, presentFacet, fixedFacet,
0726: SPECIAL_PATTERN_NONE, fDummyContext);
0727: } catch (InvalidDatatypeFacetException e) {
0728: // should never gets here, internel error
0729: throw new RuntimeException("internal error");
0730: }
0731: // we've now applied facets; so lock this object:
0732: fIsImmutable = true;
0733: }
0734:
0735: /**
0736: * built-in derived types by restriction
0737: */
0738: void applyFacets1(XSFacets facets, short presentFacet,
0739: short fixedFacet, short patternType) {
0740:
0741: try {
0742: applyFacets(facets, presentFacet, fixedFacet, patternType,
0743: fDummyContext);
0744: } catch (InvalidDatatypeFacetException e) {
0745: // should never gets here, internel error
0746: throw new RuntimeException("internal error");
0747: }
0748: // we've now applied facets; so lock this object:
0749: fIsImmutable = true;
0750: }
0751:
0752: /**
0753: * If <restriction> is chosen, or built-in derived types by restriction
0754: */
0755: void applyFacets(XSFacets facets, short presentFacet,
0756: short fixedFacet, short patternType,
0757: ValidationContext context)
0758: throws InvalidDatatypeFacetException {
0759:
0760: // if the object is immutable, should not apply facets...
0761: if (fIsImmutable)
0762: return;
0763: ValidatedInfo tempInfo = new ValidatedInfo();
0764:
0765: // clear facets. because we always inherit facets in the constructor
0766: // REVISIT: in fact, we don't need to clear them.
0767: // we can convert 5 string values (4 bounds + 1 enum) to actual values,
0768: // store them somewhere, then do facet checking at once, instead of
0769: // going through the following steps. (lots of checking are redundant:
0770: // for example, ((presentFacet & FACET_XXX) != 0))
0771:
0772: fFacetsDefined = 0;
0773: fFixedFacet = 0;
0774:
0775: int result = 0;
0776:
0777: // step 1: parse present facets
0778: short allowedFacet = fDVs[fValidationDV].getAllowedFacets();
0779:
0780: // length
0781: if ((presentFacet & FACET_LENGTH) != 0) {
0782: if ((allowedFacet & FACET_LENGTH) == 0) {
0783: reportError("cos-applicable-facets", new Object[] {
0784: "length", fTypeName });
0785: } else {
0786: fLength = facets.length;
0787: lengthAnnotation = facets.lengthAnnotation;
0788: fFacetsDefined |= FACET_LENGTH;
0789: if ((fixedFacet & FACET_LENGTH) != 0)
0790: fFixedFacet |= FACET_LENGTH;
0791: }
0792: }
0793: // minLength
0794: if ((presentFacet & FACET_MINLENGTH) != 0) {
0795: if ((allowedFacet & FACET_MINLENGTH) == 0) {
0796: reportError("cos-applicable-facets", new Object[] {
0797: "minLength", fTypeName });
0798: } else {
0799: fMinLength = facets.minLength;
0800: minLengthAnnotation = facets.minLengthAnnotation;
0801: fFacetsDefined |= FACET_MINLENGTH;
0802: if ((fixedFacet & FACET_MINLENGTH) != 0)
0803: fFixedFacet |= FACET_MINLENGTH;
0804: }
0805: }
0806: // maxLength
0807: if ((presentFacet & FACET_MAXLENGTH) != 0) {
0808: if ((allowedFacet & FACET_MAXLENGTH) == 0) {
0809: reportError("cos-applicable-facets", new Object[] {
0810: "maxLength", fTypeName });
0811: } else {
0812: fMaxLength = facets.maxLength;
0813: maxLengthAnnotation = facets.maxLengthAnnotation;
0814: fFacetsDefined |= FACET_MAXLENGTH;
0815: if ((fixedFacet & FACET_MAXLENGTH) != 0)
0816: fFixedFacet |= FACET_MAXLENGTH;
0817: }
0818: }
0819: // pattern
0820: if ((presentFacet & FACET_PATTERN) != 0) {
0821: if ((allowedFacet & FACET_PATTERN) == 0) {
0822: reportError("cos-applicable-facets", new Object[] {
0823: "pattern", fTypeName });
0824: } else {
0825: patternAnnotations = facets.patternAnnotations;
0826: RegularExpression regex = null;
0827: try {
0828: regex = new RegularExpression(facets.pattern, "X");
0829: } catch (Exception e) {
0830: reportError("InvalidRegex", new Object[] {
0831: facets.pattern, e.getLocalizedMessage() });
0832: }
0833: if (regex != null) {
0834: fPattern = new Vector();
0835: fPattern.addElement(regex);
0836: fPatternStr = new Vector();
0837: fPatternStr.addElement(facets.pattern);
0838: fFacetsDefined |= FACET_PATTERN;
0839: if ((fixedFacet & FACET_PATTERN) != 0)
0840: fFixedFacet |= FACET_PATTERN;
0841: }
0842: }
0843: }
0844:
0845: // enumeration
0846: if ((presentFacet & FACET_ENUMERATION) != 0) {
0847: if ((allowedFacet & FACET_ENUMERATION) == 0) {
0848: reportError("cos-applicable-facets", new Object[] {
0849: "enumeration", fTypeName });
0850: } else {
0851: fEnumeration = new Vector();
0852: Vector enumVals = facets.enumeration;
0853: fEnumerationType = new short[enumVals.size()];
0854: fEnumerationItemType = new ShortList[enumVals.size()];
0855: Vector enumNSDecls = facets.enumNSDecls;
0856: ValidationContextImpl ctx = new ValidationContextImpl(
0857: context);
0858: enumerationAnnotations = facets.enumAnnotations;
0859: for (int i = 0; i < enumVals.size(); i++) {
0860: if (enumNSDecls != null)
0861: ctx.setNSContext((NamespaceContext) enumNSDecls
0862: .elementAt(i));
0863: try {
0864: ValidatedInfo info = this .fBase
0865: .validateWithInfo((String) enumVals
0866: .elementAt(i), ctx, tempInfo);
0867: // check 4.3.5.c0 must: enumeration values from the value space of base
0868: fEnumeration.addElement(info.actualValue);
0869: fEnumerationType[i] = info.actualValueType;
0870: fEnumerationItemType[i] = info.itemValueTypes;
0871: } catch (InvalidDatatypeValueException ide) {
0872: reportError("enumeration-valid-restriction",
0873: new Object[] { enumVals.elementAt(i),
0874: this .getBaseType().getName() });
0875: }
0876: }
0877: fFacetsDefined |= FACET_ENUMERATION;
0878: if ((fixedFacet & FACET_ENUMERATION) != 0)
0879: fFixedFacet |= FACET_ENUMERATION;
0880: }
0881: }
0882: // whiteSpace
0883: if ((presentFacet & FACET_WHITESPACE) != 0) {
0884: if ((allowedFacet & FACET_WHITESPACE) == 0) {
0885: reportError("cos-applicable-facets", new Object[] {
0886: "whiteSpace", fTypeName });
0887: } else {
0888: fWhiteSpace = facets.whiteSpace;
0889: whiteSpaceAnnotation = facets.whiteSpaceAnnotation;
0890: fFacetsDefined |= FACET_WHITESPACE;
0891: if ((fixedFacet & FACET_WHITESPACE) != 0)
0892: fFixedFacet |= FACET_WHITESPACE;
0893: }
0894: }
0895:
0896: // maxInclusive
0897: if ((presentFacet & FACET_MAXINCLUSIVE) != 0) {
0898: if ((allowedFacet & FACET_MAXINCLUSIVE) == 0) {
0899: reportError("cos-applicable-facets", new Object[] {
0900: "maxInclusive", fTypeName });
0901: } else {
0902: maxInclusiveAnnotation = facets.maxInclusiveAnnotation;
0903: try {
0904: fMaxInclusive = fBase.getActualValue(
0905: facets.maxInclusive, context, tempInfo,
0906: true);
0907: fFacetsDefined |= FACET_MAXINCLUSIVE;
0908: if ((fixedFacet & FACET_MAXINCLUSIVE) != 0)
0909: fFixedFacet |= FACET_MAXINCLUSIVE;
0910: } catch (InvalidDatatypeValueException ide) {
0911: reportError(ide.getKey(), ide.getArgs());
0912: reportError("FacetValueFromBase", new Object[] {
0913: fTypeName, facets.maxInclusive,
0914: "maxInclusive", fBase.getName() });
0915: }
0916:
0917: // check against fixed value in base
0918: if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
0919: if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0) {
0920: if (fDVs[fValidationDV].compare(fMaxInclusive,
0921: fBase.fMaxInclusive) != 0)
0922: reportError("FixedFacetValue",
0923: new Object[] { "maxInclusive",
0924: fMaxInclusive,
0925: fBase.fMaxInclusive,
0926: fTypeName });
0927: }
0928: }
0929: // maxInclusive from base
0930: try {
0931: fBase.validate(context, tempInfo);
0932: } catch (InvalidDatatypeValueException ide) {
0933: reportError(ide.getKey(), ide.getArgs());
0934: reportError("FacetValueFromBase", new Object[] {
0935: fTypeName, facets.maxInclusive,
0936: "maxInclusive", fBase.getName() });
0937: }
0938: }
0939: }
0940:
0941: // maxExclusive
0942: boolean needCheckBase = true;
0943: if ((presentFacet & FACET_MAXEXCLUSIVE) != 0) {
0944: if ((allowedFacet & FACET_MAXEXCLUSIVE) == 0) {
0945: reportError("cos-applicable-facets", new Object[] {
0946: "maxExclusive", fTypeName });
0947: } else {
0948: maxExclusiveAnnotation = facets.maxExclusiveAnnotation;
0949: try {
0950: fMaxExclusive = fBase.getActualValue(
0951: facets.maxExclusive, context, tempInfo,
0952: true);
0953: fFacetsDefined |= FACET_MAXEXCLUSIVE;
0954: if ((fixedFacet & FACET_MAXEXCLUSIVE) != 0)
0955: fFixedFacet |= FACET_MAXEXCLUSIVE;
0956: } catch (InvalidDatatypeValueException ide) {
0957: reportError(ide.getKey(), ide.getArgs());
0958: reportError("FacetValueFromBase", new Object[] {
0959: fTypeName, facets.maxExclusive,
0960: "maxExclusive", fBase.getName() });
0961: }
0962:
0963: // check against fixed value in base
0964: if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
0965: result = fDVs[fValidationDV].compare(fMaxExclusive,
0966: fBase.fMaxExclusive);
0967: if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0
0968: && result != 0) {
0969: reportError("FixedFacetValue", new Object[] {
0970: "maxExclusive", facets.maxExclusive,
0971: fBase.fMaxExclusive, fTypeName });
0972: }
0973: if (result == 0) {
0974: needCheckBase = false;
0975: }
0976: }
0977: // maxExclusive from base
0978: if (needCheckBase) {
0979: try {
0980: fBase.validate(context, tempInfo);
0981: } catch (InvalidDatatypeValueException ide) {
0982: reportError(ide.getKey(), ide.getArgs());
0983: reportError("FacetValueFromBase", new Object[] {
0984: fTypeName, facets.maxExclusive,
0985: "maxExclusive", fBase.getName() });
0986: }
0987: }
0988: // If maxExclusive == base.maxExclusive, then we only need to check
0989: // maxExclusive <= base.maxInclusive
0990: else if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
0991: if (fDVs[fValidationDV].compare(fMaxExclusive,
0992: fBase.fMaxInclusive) > 0) {
0993: reportError("maxExclusive-valid-restriction.2",
0994: new Object[] { facets.maxExclusive,
0995: fBase.fMaxInclusive });
0996: }
0997: }
0998: }
0999: }
1000: // minExclusive
1001: needCheckBase = true;
1002: if ((presentFacet & FACET_MINEXCLUSIVE) != 0) {
1003: if ((allowedFacet & FACET_MINEXCLUSIVE) == 0) {
1004: reportError("cos-applicable-facets", new Object[] {
1005: "minExclusive", fTypeName });
1006: } else {
1007: minExclusiveAnnotation = facets.minExclusiveAnnotation;
1008: try {
1009: fMinExclusive = fBase.getActualValue(
1010: facets.minExclusive, context, tempInfo,
1011: true);
1012: fFacetsDefined |= FACET_MINEXCLUSIVE;
1013: if ((fixedFacet & FACET_MINEXCLUSIVE) != 0)
1014: fFixedFacet |= FACET_MINEXCLUSIVE;
1015: } catch (InvalidDatatypeValueException ide) {
1016: reportError(ide.getKey(), ide.getArgs());
1017: reportError("FacetValueFromBase", new Object[] {
1018: fTypeName, facets.minExclusive,
1019: "minExclusive", fBase.getName() });
1020: }
1021:
1022: // check against fixed value in base
1023: if (((fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1024: result = fDVs[fValidationDV].compare(fMinExclusive,
1025: fBase.fMinExclusive);
1026: if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0
1027: && result != 0) {
1028: reportError("FixedFacetValue", new Object[] {
1029: "minExclusive", facets.minExclusive,
1030: fBase.fMinExclusive, fTypeName });
1031: }
1032: if (result == 0) {
1033: needCheckBase = false;
1034: }
1035: }
1036: // minExclusive from base
1037: if (needCheckBase) {
1038: try {
1039: fBase.validate(context, tempInfo);
1040: } catch (InvalidDatatypeValueException ide) {
1041: reportError(ide.getKey(), ide.getArgs());
1042: reportError("FacetValueFromBase", new Object[] {
1043: fTypeName, facets.minExclusive,
1044: "minExclusive", fBase.getName() });
1045: }
1046: }
1047: // If minExclusive == base.minExclusive, then we only need to check
1048: // minExclusive >= base.minInclusive
1049: else if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1050: if (fDVs[fValidationDV].compare(fMinExclusive,
1051: fBase.fMinInclusive) < 0) {
1052: reportError("minExclusive-valid-restriction.3",
1053: new Object[] { facets.minExclusive,
1054: fBase.fMinInclusive });
1055: }
1056: }
1057: }
1058: }
1059: // minInclusive
1060: if ((presentFacet & FACET_MININCLUSIVE) != 0) {
1061: if ((allowedFacet & FACET_MININCLUSIVE) == 0) {
1062: reportError("cos-applicable-facets", new Object[] {
1063: "minInclusive", fTypeName });
1064: } else {
1065: minInclusiveAnnotation = facets.minInclusiveAnnotation;
1066: try {
1067: fMinInclusive = fBase.getActualValue(
1068: facets.minInclusive, context, tempInfo,
1069: true);
1070: fFacetsDefined |= FACET_MININCLUSIVE;
1071: if ((fixedFacet & FACET_MININCLUSIVE) != 0)
1072: fFixedFacet |= FACET_MININCLUSIVE;
1073: } catch (InvalidDatatypeValueException ide) {
1074: reportError(ide.getKey(), ide.getArgs());
1075: reportError("FacetValueFromBase", new Object[] {
1076: fTypeName, facets.minInclusive,
1077: "minInclusive", fBase.getName() });
1078: }
1079:
1080: // check against fixed value in base
1081: if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1082: if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0) {
1083: if (fDVs[fValidationDV].compare(fMinInclusive,
1084: fBase.fMinInclusive) != 0)
1085: reportError("FixedFacetValue",
1086: new Object[] { "minInclusive",
1087: facets.minInclusive,
1088: fBase.fMinInclusive,
1089: fTypeName });
1090: }
1091: }
1092: // minInclusive from base
1093: try {
1094: fBase.validate(context, tempInfo);
1095: } catch (InvalidDatatypeValueException ide) {
1096: reportError(ide.getKey(), ide.getArgs());
1097: reportError("FacetValueFromBase", new Object[] {
1098: fTypeName, facets.minInclusive,
1099: "minInclusive", fBase.getName() });
1100: }
1101: }
1102: }
1103:
1104: // totalDigits
1105: if ((presentFacet & FACET_TOTALDIGITS) != 0) {
1106: if ((allowedFacet & FACET_TOTALDIGITS) == 0) {
1107: reportError("cos-applicable-facets", new Object[] {
1108: "totalDigits", fTypeName });
1109: } else {
1110: totalDigitsAnnotation = facets.totalDigitsAnnotation;
1111: fTotalDigits = facets.totalDigits;
1112: fFacetsDefined |= FACET_TOTALDIGITS;
1113: if ((fixedFacet & FACET_TOTALDIGITS) != 0)
1114: fFixedFacet |= FACET_TOTALDIGITS;
1115: }
1116: }
1117: // fractionDigits
1118: if ((presentFacet & FACET_FRACTIONDIGITS) != 0) {
1119: if ((allowedFacet & FACET_FRACTIONDIGITS) == 0) {
1120: reportError("cos-applicable-facets", new Object[] {
1121: "fractionDigits", fTypeName });
1122: } else {
1123: fFractionDigits = facets.fractionDigits;
1124: fractionDigitsAnnotation = facets.fractionDigitsAnnotation;
1125: fFacetsDefined |= FACET_FRACTIONDIGITS;
1126: if ((fixedFacet & FACET_FRACTIONDIGITS) != 0)
1127: fFixedFacet |= FACET_FRACTIONDIGITS;
1128: }
1129: }
1130:
1131: // token type: internal use, so do less checking
1132: if (patternType != SPECIAL_PATTERN_NONE) {
1133: fPatternType = patternType;
1134: }
1135:
1136: // step 2: check facets against each other: length, bounds
1137: if (fFacetsDefined != 0) {
1138:
1139: // check 4.3.2.c1 must: minLength <= maxLength
1140: if (((fFacetsDefined & FACET_MINLENGTH) != 0)
1141: && ((fFacetsDefined & FACET_MAXLENGTH) != 0)) {
1142: if (fMinLength > fMaxLength)
1143: reportError(
1144: "minLength-less-than-equal-to-maxLength",
1145: new Object[] {
1146: Integer.toString(fMinLength),
1147: Integer.toString(fMaxLength),
1148: fTypeName });
1149: }
1150:
1151: // check 4.3.8.c1 error: maxInclusive + maxExclusive
1152: if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)
1153: && ((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1154: reportError("maxInclusive-maxExclusive", new Object[] {
1155: fMaxInclusive, fMaxExclusive, fTypeName });
1156: }
1157:
1158: // check 4.3.9.c1 error: minInclusive + minExclusive
1159: if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)
1160: && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1161: reportError("minInclusive-minExclusive", new Object[] {
1162: fMinInclusive, fMinExclusive, fTypeName });
1163: }
1164:
1165: // check 4.3.7.c1 must: minInclusive <= maxInclusive
1166: if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)
1167: && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1168: result = fDVs[fValidationDV].compare(fMinInclusive,
1169: fMaxInclusive);
1170: if (result != -1 && result != 0)
1171: reportError(
1172: "minInclusive-less-than-equal-to-maxInclusive",
1173: new Object[] { fMinInclusive,
1174: fMaxInclusive, fTypeName });
1175: }
1176:
1177: // check 4.3.8.c2 must: minExclusive <= maxExclusive ??? minExclusive < maxExclusive
1178: if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)
1179: && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1180: result = fDVs[fValidationDV].compare(fMinExclusive,
1181: fMaxExclusive);
1182: if (result != -1 && result != 0)
1183: reportError(
1184: "minExclusive-less-than-equal-to-maxExclusive",
1185: new Object[] { fMinExclusive,
1186: fMaxExclusive, fTypeName });
1187: }
1188:
1189: // check 4.3.9.c2 must: minExclusive < maxInclusive
1190: if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)
1191: && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1192: if (fDVs[fValidationDV].compare(fMinExclusive,
1193: fMaxInclusive) != -1)
1194: reportError("minExclusive-less-than-maxInclusive",
1195: new Object[] { fMinExclusive,
1196: fMaxInclusive, fTypeName });
1197: }
1198:
1199: // check 4.3.10.c1 must: minInclusive < maxExclusive
1200: if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)
1201: && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1202: if (fDVs[fValidationDV].compare(fMinInclusive,
1203: fMaxExclusive) != -1)
1204: reportError("minInclusive-less-than-maxExclusive",
1205: new Object[] { fMinInclusive,
1206: fMaxExclusive, fTypeName });
1207: }
1208:
1209: // check 4.3.12.c1 must: fractionDigits <= totalDigits
1210: if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)
1211: && ((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1212: if (fFractionDigits > fTotalDigits)
1213: reportError("fractionDigits-totalDigits",
1214: new Object[] {
1215: Integer.toString(fFractionDigits),
1216: Integer.toString(fTotalDigits),
1217: fTypeName });
1218: }
1219:
1220: // step 3: check facets against base
1221: // check 4.3.1.c1 error: length & (fBase.maxLength | fBase.minLength)
1222: if ((fFacetsDefined & FACET_LENGTH) != 0) {
1223: if ((fBase.fFacetsDefined & FACET_MINLENGTH) != 0
1224: && fLength < fBase.fMinLength) {
1225: // length, fBase.minLength and fBase.maxLength defined
1226: reportError(
1227: "length-minLength-maxLength.1.1",
1228: new Object[] { fTypeName,
1229: Integer.toString(fLength),
1230: Integer.toString(fBase.fMinLength) });
1231: }
1232: if ((fBase.fFacetsDefined & FACET_MAXLENGTH) != 0
1233: && fLength > fBase.fMaxLength) {
1234: // length and fBase.maxLength defined
1235: reportError(
1236: "length-minLength-maxLength.2.1",
1237: new Object[] { fTypeName,
1238: Integer.toString(fLength),
1239: Integer.toString(fBase.fMaxLength) });
1240: }
1241: if ((fBase.fFacetsDefined & FACET_LENGTH) != 0) {
1242: // check 4.3.1.c2 error: length != fBase.length
1243: if (fLength != fBase.fLength)
1244: reportError(
1245: "length-valid-restriction",
1246: new Object[] {
1247: Integer.toString(fLength),
1248: Integer.toString(fBase.fLength),
1249: fTypeName });
1250: }
1251: }
1252:
1253: // check 4.3.1.c1 error: fBase.length & (maxLength | minLength)
1254: if ((fBase.fFacetsDefined & FACET_LENGTH) != 0
1255: || (fFacetsDefined & FACET_LENGTH) != 0) {
1256: if ((fFacetsDefined & FACET_MINLENGTH) != 0) {
1257: if (fBase.fLength < fMinLength) {
1258: // fBase.length, minLength and maxLength defined
1259: reportError(
1260: "length-minLength-maxLength.1.1",
1261: new Object[] {
1262: fTypeName,
1263: Integer.toString(fBase.fLength),
1264: Integer.toString(fMinLength) });
1265: }
1266: if ((fBase.fFacetsDefined & FACET_MINLENGTH) == 0) {
1267: reportError("length-minLength-maxLength.1.2.a",
1268: new Object[] { fTypeName });
1269: }
1270: if (fMinLength != fBase.fMinLength) {
1271: reportError(
1272: "length-minLength-maxLength.1.2.b",
1273: new Object[] {
1274: fTypeName,
1275: Integer.toString(fMinLength),
1276: Integer
1277: .toString(fBase.fMinLength) });
1278: }
1279: }
1280: if ((fFacetsDefined & FACET_MAXLENGTH) != 0) {
1281: if (fBase.fLength > fMaxLength) {
1282: // fBase.length, minLength and maxLength defined
1283: reportError(
1284: "length-minLength-maxLength.2.1",
1285: new Object[] {
1286: fTypeName,
1287: Integer.toString(fBase.fLength),
1288: Integer.toString(fMaxLength) });
1289: }
1290: if ((fBase.fFacetsDefined & FACET_MAXLENGTH) == 0) {
1291: reportError("length-minLength-maxLength.2.2.a",
1292: new Object[] { fTypeName });
1293: }
1294: if (fMaxLength != fBase.fMaxLength) {
1295: reportError(
1296: "length-minLength-maxLength.2.2.b",
1297: new Object[] {
1298: fTypeName,
1299: Integer.toString(fMaxLength),
1300: Integer
1301: .toString(fBase.fBase.fMaxLength) });
1302: }
1303: }
1304: }
1305:
1306: // check 4.3.2.c1 must: minLength <= fBase.maxLength
1307: if (((fFacetsDefined & FACET_MINLENGTH) != 0)) {
1308: if ((fBase.fFacetsDefined & FACET_MAXLENGTH) != 0) {
1309: if (fMinLength > fBase.fMaxLength) {
1310: reportError(
1311: "minLength-less-than-equal-to-maxLength",
1312: new Object[] {
1313: Integer.toString(fMinLength),
1314: Integer
1315: .toString(fBase.fMaxLength),
1316: fTypeName });
1317: }
1318: } else if ((fBase.fFacetsDefined & FACET_MINLENGTH) != 0) {
1319: if ((fBase.fFixedFacet & FACET_MINLENGTH) != 0
1320: && fMinLength != fBase.fMinLength) {
1321: reportError("FixedFacetValue", new Object[] {
1322: "minLength",
1323: Integer.toString(fMinLength),
1324: Integer.toString(fBase.fMinLength),
1325: fTypeName });
1326: }
1327:
1328: // check 4.3.2.c2 error: minLength < fBase.minLength
1329: if (fMinLength < fBase.fMinLength) {
1330: reportError(
1331: "minLength-valid-restriction",
1332: new Object[] {
1333: Integer.toString(fMinLength),
1334: Integer
1335: .toString(fBase.fMinLength),
1336: fTypeName });
1337: }
1338: }
1339: }
1340:
1341: // check 4.3.2.c1 must: maxLength < fBase.minLength
1342: if (((fFacetsDefined & FACET_MAXLENGTH) != 0)
1343: && ((fBase.fFacetsDefined & FACET_MINLENGTH) != 0)) {
1344: if (fMaxLength < fBase.fMinLength) {
1345: reportError(
1346: "minLength-less-than-equal-to-maxLength",
1347: new Object[] {
1348: Integer.toString(fBase.fMinLength),
1349: Integer.toString(fMaxLength) });
1350: }
1351: }
1352:
1353: // check 4.3.3.c1 error: maxLength > fBase.maxLength
1354: if ((fFacetsDefined & FACET_MAXLENGTH) != 0) {
1355: if ((fBase.fFacetsDefined & FACET_MAXLENGTH) != 0) {
1356: if (((fBase.fFixedFacet & FACET_MAXLENGTH) != 0)
1357: && fMaxLength != fBase.fMaxLength) {
1358: reportError("FixedFacetValue", new Object[] {
1359: "maxLength",
1360: Integer.toString(fMaxLength),
1361: Integer.toString(fBase.fMaxLength),
1362: fTypeName });
1363: }
1364: if (fMaxLength > fBase.fMaxLength) {
1365: reportError(
1366: "maxLength-valid-restriction",
1367: new Object[] {
1368: Integer.toString(fMaxLength),
1369: Integer
1370: .toString(fBase.fMaxLength),
1371: fTypeName });
1372: }
1373: }
1374: }
1375:
1376: /* // check 4.3.7.c2 error:
1377: // maxInclusive > fBase.maxInclusive
1378: // maxInclusive >= fBase.maxExclusive
1379: // maxInclusive < fBase.minInclusive
1380: // maxInclusive <= fBase.minExclusive
1381:
1382: if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1383: if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1384: result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive);
1385: if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0 && result != 0) {
1386: reportError( "FixedFacetValue", new Object[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
1387: }
1388: if (result != -1 && result != 0) {
1389: reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxInclusive, fTypeName});
1390: }
1391: }
1392: if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1393: fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxExclusive) != -1){
1394: reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxExclusive, fTypeName});
1395: }
1396:
1397: if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1398: result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinInclusive);
1399: if (result != 1 && result != 0) {
1400: reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinInclusive, fTypeName});
1401: }
1402: }
1403:
1404: if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1405: fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinExclusive ) != 1)
1406: reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinExclusive, fTypeName});
1407: }
1408:
1409: // check 4.3.8.c3 error:
1410: // maxExclusive > fBase.maxExclusive
1411: // maxExclusive > fBase.maxInclusive
1412: // maxExclusive <= fBase.minInclusive
1413: // maxExclusive <= fBase.minExclusive
1414: if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
1415: if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
1416: result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
1417: if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 && result != 0) {
1418: reportError( "FixedFacetValue", new Object[]{"maxExclusive", fMaxExclusive, fBase.fMaxExclusive, fTypeName});
1419: }
1420: if (result != -1 && result != 0) {
1421: reportError( "maxExclusive-valid-restriction.1", new Object[]{fMaxExclusive, fBase.fMaxExclusive, fTypeName});
1422: }
1423: }
1424:
1425: if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1426: result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive);
1427: if (result != -1 && result != 0) {
1428: reportError( "maxExclusive-valid-restriction.2", new Object[]{fMaxExclusive, fBase.fMaxInclusive, fTypeName});
1429: }
1430: }
1431:
1432: if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1433: fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinExclusive ) != 1)
1434: reportError( "maxExclusive-valid-restriction.3", new Object[]{fMaxExclusive, fBase.fMinExclusive, fTypeName});
1435:
1436: if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
1437: fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinInclusive) != 1)
1438: reportError( "maxExclusive-valid-restriction.4", new Object[]{fMaxExclusive, fBase.fMinInclusive, fTypeName});
1439: }
1440:
1441: // check 4.3.9.c3 error:
1442: // minExclusive < fBase.minExclusive
1443: // minExclusive > fBase.maxInclusive
1444: // minExclusive < fBase.minInclusive
1445: // minExclusive >= fBase.maxExclusive
1446: if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1447: if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1448: result= fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
1449: if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
1450: reportError( "FixedFacetValue", new Object[]{"minExclusive", fMinExclusive, fBase.fMinExclusive, fTypeName});
1451: }
1452: if (result != 1 && result != 0) {
1453: reportError( "minExclusive-valid-restriction.1", new Object[]{fMinExclusive, fBase.fMinExclusive, fTypeName});
1454: }
1455: }
1456:
1457: if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1458: result=fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxInclusive);
1459:
1460: if (result != -1 && result != 0) {
1461: reportError( "minExclusive-valid-restriction.2", new Object[]{fMinExclusive, fBase.fMaxInclusive, fTypeName});
1462: }
1463: }
1464:
1465: if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1466: result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive);
1467:
1468: if (result != 1 && result != 0) {
1469: reportError( "minExclusive-valid-restriction.3", new Object[]{fMinExclusive, fBase.fMinInclusive, fTypeName});
1470: }
1471: }
1472:
1473: if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1474: fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxExclusive) != -1)
1475: reportError( "minExclusive-valid-restriction.4", new Object[]{fMinExclusive, fBase.fMaxExclusive, fTypeName});
1476: }
1477:
1478: // check 4.3.10.c2 error:
1479: // minInclusive < fBase.minInclusive
1480: // minInclusive > fBase.maxInclusive
1481: // minInclusive <= fBase.minExclusive
1482: // minInclusive >= fBase.maxExclusive
1483: if (((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1484: if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1485: result = fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive);
1486:
1487: if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0 && result != 0) {
1488: reportError( "FixedFacetValue", new Object[]{"minInclusive", fMinInclusive, fBase.fMinInclusive, fTypeName});
1489: }
1490: if (result != 1 && result != 0) {
1491: reportError( "minInclusive-valid-restriction.1", new Object[]{fMinInclusive, fBase.fMinInclusive, fTypeName});
1492: }
1493: }
1494: if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1495: result=fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxInclusive);
1496: if (result != -1 && result != 0) {
1497: reportError( "minInclusive-valid-restriction.2", new Object[]{fMinInclusive, fBase.fMaxInclusive, fTypeName});
1498: }
1499: }
1500: if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1501: fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinExclusive ) != 1)
1502: reportError( "minInclusive-valid-restriction.3", new Object[]{fMinInclusive, fBase.fMinExclusive, fTypeName});
1503: if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1504: fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxExclusive) != -1)
1505: reportError( "minInclusive-valid-restriction.4", new Object[]{fMinInclusive, fBase.fMaxExclusive, fTypeName});
1506: }
1507: */
1508: // check 4.3.11.c1 error: totalDigits > fBase.totalDigits
1509: if (((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1510: if (((fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1511: if ((fBase.fFixedFacet & FACET_TOTALDIGITS) != 0
1512: && fTotalDigits != fBase.fTotalDigits) {
1513: reportError("FixedFacetValue", new Object[] {
1514: "totalDigits",
1515: Integer.toString(fTotalDigits),
1516: Integer.toString(fBase.fTotalDigits),
1517: fTypeName });
1518: }
1519: if (fTotalDigits > fBase.fTotalDigits) {
1520: reportError(
1521: "totalDigits-valid-restriction",
1522: new Object[] {
1523: Integer.toString(fTotalDigits),
1524: Integer
1525: .toString(fBase.fTotalDigits),
1526: fTypeName });
1527: }
1528: }
1529: }
1530:
1531: // check 4.3.12.c1 must: fractionDigits <= base.totalDigits
1532: if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
1533: if ((fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) {
1534: if (fFractionDigits > fBase.fTotalDigits)
1535: reportError(
1536: "fractionDigits-totalDigits",
1537: new Object[] {
1538: Integer
1539: .toString(fFractionDigits),
1540: Integer.toString(fTotalDigits),
1541: fTypeName });
1542: }
1543: }
1544:
1545: // check 4.3.12.c2 error: fractionDigits > fBase.fractionDigits
1546: // check fixed value for fractionDigits
1547: if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1548: if (((fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1549: if (((fBase.fFixedFacet & FACET_FRACTIONDIGITS) != 0 && fFractionDigits != fBase.fFractionDigits)
1550: || (fValidationDV == DV_INTEGER && fFractionDigits != 0)) {
1551: reportError(
1552: "FixedFacetValue",
1553: new Object[] {
1554: "fractionDigits",
1555: Integer
1556: .toString(fFractionDigits),
1557: Integer
1558: .toString(fBase.fFractionDigits),
1559: fTypeName });
1560: }
1561: if (fFractionDigits > fBase.fFractionDigits) {
1562: reportError(
1563: "fractionDigits-valid-restriction",
1564: new Object[] {
1565: Integer
1566: .toString(fFractionDigits),
1567: Integer
1568: .toString(fBase.fFractionDigits),
1569: fTypeName });
1570: }
1571: } else if (fValidationDV == DV_INTEGER
1572: && fFractionDigits != 0) {
1573: reportError("FixedFacetValue", new Object[] {
1574: "fractionDigits",
1575: Integer.toString(fFractionDigits), "0",
1576: fTypeName });
1577: }
1578: }
1579:
1580: // check 4.3.6.c1 error:
1581: // (whiteSpace = preserve || whiteSpace = replace) && fBase.whiteSpace = collapese or
1582: // whiteSpace = preserve && fBase.whiteSpace = replace
1583:
1584: if ((fFacetsDefined & FACET_WHITESPACE) != 0
1585: && (fBase.fFacetsDefined & FACET_WHITESPACE) != 0) {
1586: if ((fBase.fFixedFacet & FACET_WHITESPACE) != 0
1587: && fWhiteSpace != fBase.fWhiteSpace) {
1588: reportError("FixedFacetValue", new Object[] {
1589: "whiteSpace", whiteSpaceValue(fWhiteSpace),
1590: whiteSpaceValue(fBase.fWhiteSpace),
1591: fTypeName });
1592: }
1593:
1594: if (fWhiteSpace == WS_PRESERVE
1595: && fBase.fWhiteSpace == WS_COLLAPSE) {
1596: reportError("whiteSpace-valid-restriction.1",
1597: new Object[] { fTypeName, "preserve" });
1598: }
1599: if (fWhiteSpace == WS_REPLACE
1600: && fBase.fWhiteSpace == WS_COLLAPSE) {
1601: reportError("whiteSpace-valid-restriction.1",
1602: new Object[] { fTypeName, "replace" });
1603: }
1604: if (fWhiteSpace == WS_PRESERVE
1605: && fBase.fWhiteSpace == WS_REPLACE) {
1606: reportError("whiteSpace-valid-restriction.2",
1607: new Object[] { fTypeName });
1608: }
1609: }
1610: }//fFacetsDefined != null
1611:
1612: // step 4: inherit other facets from base (including fTokeyType)
1613:
1614: // inherit length
1615: if ((fFacetsDefined & FACET_LENGTH) == 0
1616: && (fBase.fFacetsDefined & FACET_LENGTH) != 0) {
1617: fFacetsDefined |= FACET_LENGTH;
1618: fLength = fBase.fLength;
1619: lengthAnnotation = fBase.lengthAnnotation;
1620: }
1621: // inherit minLength
1622: if ((fFacetsDefined & FACET_MINLENGTH) == 0
1623: && (fBase.fFacetsDefined & FACET_MINLENGTH) != 0) {
1624: fFacetsDefined |= FACET_MINLENGTH;
1625: fMinLength = fBase.fMinLength;
1626: minLengthAnnotation = fBase.minLengthAnnotation;
1627: }
1628: // inherit maxLength
1629: if ((fFacetsDefined & FACET_MAXLENGTH) == 0
1630: && (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0) {
1631: fFacetsDefined |= FACET_MAXLENGTH;
1632: fMaxLength = fBase.fMaxLength;
1633: maxLengthAnnotation = fBase.maxLengthAnnotation;
1634: }
1635: // inherit pattern
1636: if ((fBase.fFacetsDefined & FACET_PATTERN) != 0) {
1637: if ((fFacetsDefined & FACET_PATTERN) == 0) {
1638: fFacetsDefined |= FACET_PATTERN;
1639: fPattern = fBase.fPattern;
1640: fPatternStr = fBase.fPatternStr;
1641: patternAnnotations = fBase.patternAnnotations;
1642: } else {
1643: for (int i = fBase.fPattern.size() - 1; i >= 0; --i) {
1644: fPattern.addElement(fBase.fPattern.elementAt(i));
1645: fPatternStr.addElement(fBase.fPatternStr
1646: .elementAt(i));
1647: }
1648: if (fBase.patternAnnotations != null) {
1649: if (patternAnnotations != null) {
1650: for (int i = fBase.patternAnnotations
1651: .getLength() - 1; i >= 0; --i) {
1652: patternAnnotations
1653: .add(fBase.patternAnnotations
1654: .item(i));
1655: }
1656: } else {
1657: patternAnnotations = fBase.patternAnnotations;
1658: }
1659: }
1660: }
1661: }
1662: // inherit whiteSpace
1663: if ((fFacetsDefined & FACET_WHITESPACE) == 0
1664: && (fBase.fFacetsDefined & FACET_WHITESPACE) != 0) {
1665: fFacetsDefined |= FACET_WHITESPACE;
1666: fWhiteSpace = fBase.fWhiteSpace;
1667: whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
1668: }
1669: // inherit enumeration
1670: if ((fFacetsDefined & FACET_ENUMERATION) == 0
1671: && (fBase.fFacetsDefined & FACET_ENUMERATION) != 0) {
1672: fFacetsDefined |= FACET_ENUMERATION;
1673: fEnumeration = fBase.fEnumeration;
1674: enumerationAnnotations = fBase.enumerationAnnotations;
1675: }
1676: // inherit maxExclusive
1677: if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)
1678: && !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)
1679: && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1680: fFacetsDefined |= FACET_MAXEXCLUSIVE;
1681: fMaxExclusive = fBase.fMaxExclusive;
1682: maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
1683: }
1684: // inherit maxInclusive
1685: if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)
1686: && !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)
1687: && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1688: fFacetsDefined |= FACET_MAXINCLUSIVE;
1689: fMaxInclusive = fBase.fMaxInclusive;
1690: maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
1691: }
1692: // inherit minExclusive
1693: if (((fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)
1694: && !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)
1695: && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1696: fFacetsDefined |= FACET_MINEXCLUSIVE;
1697: fMinExclusive = fBase.fMinExclusive;
1698: minExclusiveAnnotation = fBase.minExclusiveAnnotation;
1699: }
1700: // inherit minExclusive
1701: if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)
1702: && !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)
1703: && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1704: fFacetsDefined |= FACET_MININCLUSIVE;
1705: fMinInclusive = fBase.fMinInclusive;
1706: minInclusiveAnnotation = fBase.minInclusiveAnnotation;
1707: }
1708: // inherit totalDigits
1709: if (((fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0)
1710: && !((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1711: fFacetsDefined |= FACET_TOTALDIGITS;
1712: fTotalDigits = fBase.fTotalDigits;
1713: totalDigitsAnnotation = fBase.totalDigitsAnnotation;
1714: }
1715: // inherit fractionDigits
1716: if (((fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)
1717: && !((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1718: fFacetsDefined |= FACET_FRACTIONDIGITS;
1719: fFractionDigits = fBase.fFractionDigits;
1720: fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;
1721: }
1722: //inherit tokeytype
1723: if ((fPatternType == SPECIAL_PATTERN_NONE)
1724: && (fBase.fPatternType != SPECIAL_PATTERN_NONE)) {
1725: fPatternType = fBase.fPatternType;
1726: }
1727:
1728: // step 5: mark fixed values
1729: fFixedFacet |= fBase.fFixedFacet;
1730:
1731: //step 6: setting fundamental facets
1732: calcFundamentalFacets();
1733:
1734: } //applyFacets()
1735:
1736: /**
1737: * validate a value, and return the compiled form
1738: */
1739: public Object validate(String content, ValidationContext context,
1740: ValidatedInfo validatedInfo)
1741: throws InvalidDatatypeValueException {
1742:
1743: if (context == null)
1744: context = fEmptyContext;
1745:
1746: if (validatedInfo == null)
1747: validatedInfo = new ValidatedInfo();
1748: else
1749: validatedInfo.memberType = null;
1750:
1751: // first normalize string value, and convert it to actual value
1752: boolean needNormalize = context == null
1753: || context.needToNormalize();
1754: Object ob = getActualValue(content, context, validatedInfo,
1755: needNormalize);
1756:
1757: validate(context, validatedInfo);
1758:
1759: return ob;
1760:
1761: }
1762:
1763: /**
1764: * validate a value, and return the compiled form
1765: */
1766: public ValidatedInfo validateWithInfo(String content,
1767: ValidationContext context, ValidatedInfo validatedInfo)
1768: throws InvalidDatatypeValueException {
1769:
1770: if (context == null)
1771: context = fEmptyContext;
1772:
1773: if (validatedInfo == null)
1774: validatedInfo = new ValidatedInfo();
1775: else
1776: validatedInfo.memberType = null;
1777:
1778: // first normalize string value, and convert it to actual value
1779: boolean needNormalize = context == null
1780: || context.needToNormalize();
1781: getActualValue(content, context, validatedInfo, needNormalize);
1782:
1783: validate(context, validatedInfo);
1784:
1785: return validatedInfo;
1786:
1787: }
1788:
1789: /**
1790: * validate a value, and return the compiled form
1791: */
1792: public Object validate(Object content, ValidationContext context,
1793: ValidatedInfo validatedInfo)
1794: throws InvalidDatatypeValueException {
1795:
1796: if (context == null)
1797: context = fEmptyContext;
1798:
1799: if (validatedInfo == null)
1800: validatedInfo = new ValidatedInfo();
1801: else
1802: validatedInfo.memberType = null;
1803:
1804: // first normalize string value, and convert it to actual value
1805: boolean needNormalize = context == null
1806: || context.needToNormalize();
1807: Object ob = getActualValue(content, context, validatedInfo,
1808: needNormalize);
1809:
1810: validate(context, validatedInfo);
1811:
1812: return ob;
1813:
1814: }
1815:
1816: /**
1817: * validate an actual value against this DV
1818: *
1819: * @param context the validation context
1820: * @param validatedInfo used to provide the actual value and member types
1821: */
1822: public void validate(ValidationContext context,
1823: ValidatedInfo validatedInfo)
1824: throws InvalidDatatypeValueException {
1825:
1826: if (context == null)
1827: context = fEmptyContext;
1828:
1829: // then validate the actual value against the facets
1830: if (context.needFacetChecking()
1831: && (fFacetsDefined != 0 && fFacetsDefined != FACET_WHITESPACE)) {
1832: checkFacets(validatedInfo);
1833: }
1834:
1835: // now check extra rules: for ID/IDREF/ENTITY
1836: if (context.needExtraChecking()) {
1837: checkExtraRules(context, validatedInfo);
1838: }
1839:
1840: }
1841:
1842: private void checkFacets(ValidatedInfo validatedInfo)
1843: throws InvalidDatatypeValueException {
1844:
1845: Object ob = validatedInfo.actualValue;
1846: String content = validatedInfo.normalizedValue;
1847: short type = validatedInfo.actualValueType;
1848: ShortList itemType = validatedInfo.itemValueTypes;
1849:
1850: // For QName and NOTATION types, we don't check length facets
1851: if (fValidationDV != DV_QNAME && fValidationDV != DV_NOTATION) {
1852: int length = fDVs[fValidationDV].getDataLength(ob);
1853:
1854: // maxLength
1855: if ((fFacetsDefined & FACET_MAXLENGTH) != 0) {
1856: if (length > fMaxLength) {
1857: throw new InvalidDatatypeValueException(
1858: "cvc-maxLength-valid", new Object[] {
1859: content, Integer.toString(length),
1860: Integer.toString(fMaxLength),
1861: fTypeName });
1862: }
1863: }
1864:
1865: //minLength
1866: if ((fFacetsDefined & FACET_MINLENGTH) != 0) {
1867: if (length < fMinLength) {
1868: throw new InvalidDatatypeValueException(
1869: "cvc-minLength-valid", new Object[] {
1870: content, Integer.toString(length),
1871: Integer.toString(fMinLength),
1872: fTypeName });
1873: }
1874: }
1875:
1876: //length
1877: if ((fFacetsDefined & FACET_LENGTH) != 0) {
1878: if (length != fLength) {
1879: throw new InvalidDatatypeValueException(
1880: "cvc-length-valid", new Object[] { content,
1881: Integer.toString(length),
1882: Integer.toString(fLength),
1883: fTypeName });
1884: }
1885: }
1886: }
1887:
1888: //enumeration
1889: if (((fFacetsDefined & FACET_ENUMERATION) != 0)) {
1890: boolean present = false;
1891: final int enumSize = fEnumeration.size();
1892: final short primitiveType1 = convertToPrimitiveKind(type);
1893: for (int i = 0; i < enumSize; i++) {
1894: final short primitiveType2 = convertToPrimitiveKind(fEnumerationType[i]);
1895: if ((primitiveType1 == primitiveType2
1896: || primitiveType1 == XSConstants.ANYSIMPLETYPE_DT
1897: && primitiveType2 == XSConstants.STRING_DT || primitiveType1 == XSConstants.STRING_DT
1898: && primitiveType2 == XSConstants.ANYSIMPLETYPE_DT)
1899: && fEnumeration.elementAt(i).equals(ob)) {
1900: if (primitiveType1 == XSConstants.LIST_DT
1901: || primitiveType1 == XSConstants.LISTOFUNION_DT) {
1902: ShortList enumItemType = fEnumerationItemType[i];
1903: final int typeList1Length = itemType != null ? itemType
1904: .getLength()
1905: : 0;
1906: final int typeList2Length = enumItemType != null ? enumItemType
1907: .getLength()
1908: : 0;
1909: if (typeList1Length == typeList2Length) {
1910: int j;
1911: for (j = 0; j < typeList1Length; ++j) {
1912: final short primitiveItem1 = convertToPrimitiveKind(itemType
1913: .item(j));
1914: final short primitiveItem2 = convertToPrimitiveKind(enumItemType
1915: .item(j));
1916: if (primitiveItem1 != primitiveItem2) {
1917: if (primitiveItem1 == XSConstants.ANYSIMPLETYPE_DT
1918: && primitiveItem2 == XSConstants.STRING_DT
1919: || primitiveItem1 == XSConstants.STRING_DT
1920: && primitiveItem2 == XSConstants.ANYSIMPLETYPE_DT) {
1921: continue;
1922: }
1923: break;
1924: }
1925: }
1926: if (j == typeList1Length) {
1927: present = true;
1928: break;
1929: }
1930: }
1931: } else {
1932: present = true;
1933: break;
1934: }
1935: }
1936: }
1937: if (!present) {
1938: throw new InvalidDatatypeValueException(
1939: "cvc-enumeration-valid", new Object[] {
1940: content, fEnumeration.toString() });
1941: }
1942: }
1943:
1944: //fractionDigits
1945: if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
1946: int scale = fDVs[fValidationDV].getFractionDigits(ob);
1947: if (scale > fFractionDigits) {
1948: throw new InvalidDatatypeValueException(
1949: "cvc-fractionDigits-valid", new Object[] {
1950: content, Integer.toString(scale),
1951: Integer.toString(fFractionDigits) });
1952: }
1953: }
1954:
1955: //totalDigits
1956: if ((fFacetsDefined & FACET_TOTALDIGITS) != 0) {
1957: int totalDigits = fDVs[fValidationDV].getTotalDigits(ob);
1958: if (totalDigits > fTotalDigits) {
1959: throw new InvalidDatatypeValueException(
1960: "cvc-totalDigits-valid", new Object[] {
1961: content, Integer.toString(totalDigits),
1962: Integer.toString(fTotalDigits) });
1963: }
1964: }
1965:
1966: int compare;
1967:
1968: //maxinclusive
1969: if ((fFacetsDefined & FACET_MAXINCLUSIVE) != 0) {
1970: compare = fDVs[fValidationDV].compare(ob, fMaxInclusive);
1971: if (compare != -1 && compare != 0) {
1972: throw new InvalidDatatypeValueException(
1973: "cvc-maxInclusive-valid", new Object[] {
1974: content, fMaxInclusive, fTypeName });
1975: }
1976: }
1977:
1978: //maxExclusive
1979: if ((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) {
1980: compare = fDVs[fValidationDV].compare(ob, fMaxExclusive);
1981: if (compare != -1) {
1982: throw new InvalidDatatypeValueException(
1983: "cvc-maxExclusive-valid", new Object[] {
1984: content, fMaxExclusive, fTypeName });
1985: }
1986: }
1987:
1988: //minInclusive
1989: if ((fFacetsDefined & FACET_MININCLUSIVE) != 0) {
1990: compare = fDVs[fValidationDV].compare(ob, fMinInclusive);
1991: if (compare != 1 && compare != 0) {
1992: throw new InvalidDatatypeValueException(
1993: "cvc-minInclusive-valid", new Object[] {
1994: content, fMinInclusive, fTypeName });
1995: }
1996: }
1997:
1998: //minExclusive
1999: if ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) {
2000: compare = fDVs[fValidationDV].compare(ob, fMinExclusive);
2001: if (compare != 1) {
2002: throw new InvalidDatatypeValueException(
2003: "cvc-minExclusive-valid", new Object[] {
2004: content, fMinExclusive, fTypeName });
2005: }
2006: }
2007:
2008: }
2009:
2010: private void checkExtraRules(ValidationContext context,
2011: ValidatedInfo validatedInfo)
2012: throws InvalidDatatypeValueException {
2013:
2014: Object ob = validatedInfo.actualValue;
2015:
2016: if (fVariety == VARIETY_ATOMIC) {
2017:
2018: fDVs[fValidationDV].checkExtraRules(ob, context);
2019:
2020: } else if (fVariety == VARIETY_LIST) {
2021:
2022: ListDV.ListData values = (ListDV.ListData) ob;
2023: int len = values.getLength();
2024: if (fItemType.fVariety == VARIETY_UNION) {
2025: XSSimpleTypeDecl[] memberTypes = (XSSimpleTypeDecl[]) validatedInfo.memberTypes;
2026: XSSimpleType memberType = validatedInfo.memberType;
2027: for (int i = len - 1; i >= 0; i--) {
2028: validatedInfo.actualValue = values.item(i);
2029: validatedInfo.memberType = memberTypes[i];
2030: fItemType.checkExtraRules(context, validatedInfo);
2031: }
2032: validatedInfo.memberType = memberType;
2033: } else { // (fVariety == VARIETY_ATOMIC)
2034: for (int i = len - 1; i >= 0; i--) {
2035: validatedInfo.actualValue = values.item(i);
2036: fItemType.checkExtraRules(context, validatedInfo);
2037: }
2038: }
2039: validatedInfo.actualValue = values;
2040:
2041: } else { // (fVariety == VARIETY_UNION)
2042:
2043: ((XSSimpleTypeDecl) validatedInfo.memberType)
2044: .checkExtraRules(context, validatedInfo);
2045:
2046: }
2047:
2048: }// checkExtraRules()
2049:
2050: //we can still return object for internal use.
2051: private Object getActualValue(Object content,
2052: ValidationContext context, ValidatedInfo validatedInfo,
2053: boolean needNormalize) throws InvalidDatatypeValueException {
2054:
2055: String nvalue;
2056: if (needNormalize) {
2057: nvalue = normalize(content, fWhiteSpace);
2058: } else {
2059: nvalue = content.toString();
2060: }
2061: if ((fFacetsDefined & FACET_PATTERN) != 0) {
2062: RegularExpression regex;
2063: for (int idx = fPattern.size() - 1; idx >= 0; idx--) {
2064: regex = (RegularExpression) fPattern.elementAt(idx);
2065: if (!regex.matches(nvalue)) {
2066: throw new InvalidDatatypeValueException(
2067: "cvc-pattern-valid", new Object[] {
2068: content,
2069: fPatternStr.elementAt(idx),
2070:
2071: fTypeName });
2072: }
2073: }
2074: }
2075:
2076: if (fVariety == VARIETY_ATOMIC) {
2077:
2078: // validate special kinds of token, in place of old pattern matching
2079: if (fPatternType != SPECIAL_PATTERN_NONE) {
2080:
2081: boolean seenErr = false;
2082: if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
2083: // PATTERN "\\c+"
2084: seenErr = !XMLChar.isValidNmtoken(nvalue);
2085: } else if (fPatternType == SPECIAL_PATTERN_NAME) {
2086: // PATTERN "\\i\\c*"
2087: seenErr = !XMLChar.isValidName(nvalue);
2088: } else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
2089: // PATTERN "[\\i-[:]][\\c-[:]]*"
2090: seenErr = !XMLChar.isValidNCName(nvalue);
2091: }
2092: if (seenErr) {
2093: throw new InvalidDatatypeValueException(
2094: "cvc-datatype-valid.1.2.1",
2095: new Object[] {
2096: nvalue,
2097: SPECIAL_PATTERN_STRING[fPatternType] });
2098: }
2099: }
2100:
2101: validatedInfo.normalizedValue = nvalue;
2102: Object avalue = fDVs[fValidationDV].getActualValue(nvalue,
2103: context);
2104: validatedInfo.actualValue = avalue;
2105: validatedInfo.actualValueType = fBuiltInKind;
2106:
2107: return avalue;
2108:
2109: } else if (fVariety == VARIETY_LIST) {
2110:
2111: StringTokenizer parsedList = new StringTokenizer(nvalue,
2112: " ");
2113: int countOfTokens = parsedList.countTokens();
2114: Object[] avalue = new Object[countOfTokens];
2115: boolean isUnion = fItemType.getVariety() == VARIETY_UNION;
2116: short[] itemTypes = new short[isUnion ? countOfTokens : 1];
2117: if (!isUnion)
2118: itemTypes[0] = fItemType.fBuiltInKind;
2119: XSSimpleTypeDecl[] memberTypes = new XSSimpleTypeDecl[countOfTokens];
2120: for (int i = 0; i < countOfTokens; i++) {
2121: // we can't call fItemType.validate(), otherwise checkExtraRules()
2122: // will be called twice: once in fItemType.validate, once in
2123: // validate method of this type.
2124: // so we take two steps to get the actual value:
2125: // 1. fItemType.getActualValue()
2126: // 2. fItemType.chekcFacets()
2127: avalue[i] = fItemType.getActualValue(parsedList
2128: .nextToken(), context, validatedInfo, false);
2129: if (context.needFacetChecking()
2130: && (fItemType.fFacetsDefined != 0 && fItemType.fFacetsDefined != FACET_WHITESPACE)) {
2131: fItemType.checkFacets(validatedInfo);
2132: }
2133: memberTypes[i] = (XSSimpleTypeDecl) validatedInfo.memberType;
2134: if (isUnion)
2135: itemTypes[i] = memberTypes[i].fBuiltInKind;
2136: }
2137:
2138: ListDV.ListData v = new ListDV.ListData(avalue);
2139: validatedInfo.actualValue = v;
2140: validatedInfo.actualValueType = isUnion ? XSConstants.LISTOFUNION_DT
2141: : XSConstants.LIST_DT;
2142: validatedInfo.memberType = null;
2143: validatedInfo.memberTypes = memberTypes;
2144: validatedInfo.itemValueTypes = new ShortListImpl(itemTypes,
2145: itemTypes.length);
2146: validatedInfo.normalizedValue = nvalue;
2147:
2148: return v;
2149:
2150: } else { // (fVariety == VARIETY_UNION)
2151: for (int i = 0; i < fMemberTypes.length; i++) {
2152: try {
2153: // we can't call fMemberType[i].validate(), otherwise checkExtraRules()
2154: // will be called twice: once in fMemberType[i].validate, once in
2155: // validate method of this type.
2156: // so we take two steps to get the actual value:
2157: // 1. fMemberType[i].getActualValue()
2158: // 2. fMemberType[i].chekcFacets()
2159: Object aValue = fMemberTypes[i].getActualValue(
2160: content, context, validatedInfo, true);
2161: if (context.needFacetChecking()
2162: && (fMemberTypes[i].fFacetsDefined != 0 && fMemberTypes[i].fFacetsDefined != FACET_WHITESPACE)) {
2163: fMemberTypes[i].checkFacets(validatedInfo);
2164: }
2165: validatedInfo.memberType = fMemberTypes[i];
2166: return aValue;
2167: } catch (InvalidDatatypeValueException invalidValue) {
2168: }
2169: }
2170: StringBuffer typesBuffer = new StringBuffer();
2171: XSSimpleTypeDecl decl;
2172: for (int i = 0; i < fMemberTypes.length; i++) {
2173: if (i != 0)
2174: typesBuffer.append(" | ");
2175: decl = fMemberTypes[i];
2176: if (decl.fTargetNamespace != null) {
2177: typesBuffer.append('{');
2178: typesBuffer.append(decl.fTargetNamespace);
2179: typesBuffer.append('}');
2180: }
2181: typesBuffer.append(decl.fTypeName);
2182: if (decl.fEnumeration != null) {
2183: Vector v = decl.fEnumeration;
2184: typesBuffer.append(" : [");
2185: for (int j = 0; j < v.size(); j++) {
2186: if (j != 0)
2187: typesBuffer.append(',');
2188: typesBuffer.append(v.elementAt(j));
2189: }
2190: typesBuffer.append(']');
2191: }
2192: }
2193: throw new InvalidDatatypeValueException(
2194: "cvc-datatype-valid.1.2.3", new Object[] { content,
2195: fTypeName, typesBuffer.toString() });
2196: }
2197:
2198: }//getActualValue()
2199:
2200: public boolean isEqual(Object value1, Object value2) {
2201: if (value1 == null) {
2202: return false;
2203: }
2204: return value1.equals(value2);
2205: }//isEqual()
2206:
2207: // determine whether the two values are identical
2208: public boolean isIdentical(Object value1, Object value2) {
2209: if (value1 == null) {
2210: return false;
2211: }
2212: return fDVs[fValidationDV].isIdentical(value1, value2);
2213: }//isIdentical()
2214:
2215: // normalize the string according to the whiteSpace facet
2216: public static String normalize(String content, short ws) {
2217: int len = content == null ? 0 : content.length();
2218: if (len == 0 || ws == WS_PRESERVE)
2219: return content;
2220:
2221: StringBuffer sb = new StringBuffer();
2222: if (ws == WS_REPLACE) {
2223: char ch;
2224: // when it's replace, just replace #x9, #xa, #xd by #x20
2225: for (int i = 0; i < len; i++) {
2226: ch = content.charAt(i);
2227: if (ch != 0x9 && ch != 0xa && ch != 0xd)
2228: sb.append(ch);
2229: else
2230: sb.append((char) 0x20);
2231: }
2232: } else {
2233: char ch;
2234: int i;
2235: boolean isLeading = true;
2236: // when it's collapse
2237: for (i = 0; i < len; i++) {
2238: ch = content.charAt(i);
2239: // append real characters, so we passed leading ws
2240: if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
2241: sb.append(ch);
2242: isLeading = false;
2243: } else {
2244: // for whitespaces, we skip all following ws
2245: for (; i < len - 1; i++) {
2246: ch = content.charAt(i + 1);
2247: if (ch != 0x9 && ch != 0xa && ch != 0xd
2248: && ch != 0x20)
2249: break;
2250: }
2251: // if it's not a leading or tailing ws, then append a space
2252: if (i < len - 1 && !isLeading)
2253: sb.append((char) 0x20);
2254: }
2255: }
2256: }
2257:
2258: return sb.toString();
2259: }
2260:
2261: // normalize the string according to the whiteSpace facet
2262: protected String normalize(Object content, short ws) {
2263: if (content == null)
2264: return null;
2265:
2266: // If pattern is not defined, we can skip some of the normalization.
2267: // Otherwise we have to normalize the data for correct result of
2268: // pattern validation.
2269: if ((fFacetsDefined & FACET_PATTERN) == 0) {
2270: short norm_type = fDVNormalizeType[fValidationDV];
2271: if (norm_type == NORMALIZE_NONE) {
2272: return content.toString();
2273: } else if (norm_type == NORMALIZE_TRIM) {
2274: return XMLChar.trim(content.toString());
2275: }
2276: }
2277:
2278: if (!(content instanceof StringBuffer)) {
2279: String strContent = content.toString();
2280: return normalize(strContent, ws);
2281: }
2282:
2283: StringBuffer sb = (StringBuffer) content;
2284: int len = sb.length();
2285: if (len == 0)
2286: return "";
2287: if (ws == WS_PRESERVE)
2288: return sb.toString();
2289:
2290: if (ws == WS_REPLACE) {
2291: char ch;
2292: // when it's replace, just replace #x9, #xa, #xd by #x20
2293: for (int i = 0; i < len; i++) {
2294: ch = sb.charAt(i);
2295: if (ch == 0x9 || ch == 0xa || ch == 0xd)
2296: sb.setCharAt(i, (char) 0x20);
2297: }
2298: } else {
2299: char ch;
2300: int i, j = 0;
2301: boolean isLeading = true;
2302: // when it's collapse
2303: for (i = 0; i < len; i++) {
2304: ch = sb.charAt(i);
2305: // append real characters, so we passed leading ws
2306: if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
2307: sb.setCharAt(j++, ch);
2308: isLeading = false;
2309: } else {
2310: // for whitespaces, we skip all following ws
2311: for (; i < len - 1; i++) {
2312: ch = sb.charAt(i + 1);
2313: if (ch != 0x9 && ch != 0xa && ch != 0xd
2314: && ch != 0x20)
2315: break;
2316: }
2317: // if it's not a leading or tailing ws, then append a space
2318: if (i < len - 1 && !isLeading)
2319: sb.setCharAt(j++, (char) 0x20);
2320: }
2321: }
2322: sb.setLength(j);
2323: }
2324:
2325: return sb.toString();
2326: }
2327:
2328: void reportError(String key, Object[] args)
2329: throws InvalidDatatypeFacetException {
2330: throw new InvalidDatatypeFacetException(key, args);
2331: }
2332:
2333: private String whiteSpaceValue(short ws) {
2334: return WS_FACET_STRING[ws];
2335: }
2336:
2337: /**
2338: * Fundamental Facet: ordered.
2339: */
2340: public short getOrdered() {
2341: return fOrdered;
2342: }
2343:
2344: /**
2345: * Fundamental Facet: bounded.
2346: */
2347: public boolean getBounded() {
2348: return fBounded;
2349: }
2350:
2351: /**
2352: * Fundamental Facet: cardinality.
2353: */
2354: public boolean getFinite() {
2355: return fFinite;
2356: }
2357:
2358: /**
2359: * Fundamental Facet: numeric.
2360: */
2361: public boolean getNumeric() {
2362: return fNumeric;
2363: }
2364:
2365: /**
2366: * Convenience method. [Facets]: check whether a facet is defined on this
2367: * type.
2368: * @param facetName The name of the facet.
2369: * @return True if the facet is defined, false otherwise.
2370: */
2371: public boolean isDefinedFacet(short facetName) {
2372: if ((fFacetsDefined & facetName) != 0)
2373: return true;
2374: if (fPatternType != SPECIAL_PATTERN_NONE)
2375: return facetName == FACET_PATTERN;
2376: if (fValidationDV == DV_INTEGER)
2377: return facetName == FACET_PATTERN
2378: || facetName == FACET_FRACTIONDIGITS;
2379: return false;
2380: }
2381:
2382: /**
2383: * [facets]: all facets defined on this type. The value is a bit
2384: * combination of FACET_XXX constants of all defined facets.
2385: */
2386: public short getDefinedFacets() {
2387: if (fPatternType != SPECIAL_PATTERN_NONE)
2388: return (short) (fFacetsDefined | FACET_PATTERN);
2389: if (fValidationDV == DV_INTEGER)
2390: return (short) (fFacetsDefined | FACET_PATTERN | FACET_FRACTIONDIGITS);
2391: return fFacetsDefined;
2392: }
2393:
2394: /**
2395: * Convenience method. [Facets]: check whether a facet is defined and
2396: * fixed on this type.
2397: * @param facetName The name of the facet.
2398: * @return True if the facet is fixed, false otherwise.
2399: */
2400: public boolean isFixedFacet(short facetName) {
2401: if ((fFixedFacet & facetName) != 0)
2402: return true;
2403: if (fValidationDV == DV_INTEGER)
2404: return facetName == FACET_FRACTIONDIGITS;
2405: return false;
2406: }
2407:
2408: /**
2409: * [facets]: all defined facets for this type which are fixed.
2410: */
2411: public short getFixedFacets() {
2412: if (fValidationDV == DV_INTEGER)
2413: return (short) (fFixedFacet | FACET_FRACTIONDIGITS);
2414: return fFixedFacet;
2415: }
2416:
2417: /**
2418: * Convenience method. Returns a value of a single constraining facet for
2419: * this simple type definition. This method must not be used to retrieve
2420: * values for <code>enumeration</code> and <code>pattern</code> facets.
2421: * @param facetName The name of the facet, i.e.
2422: * <code>FACET_LENGTH, FACET_TOTALDIGITS </code> (see
2423: * <code>XSConstants</code>). To retrieve the value for a pattern or
2424: * an enumeration, see <code>enumeration</code> and
2425: * <code>pattern</code>.
2426: * @return A value of the facet specified in <code>facetName</code> for
2427: * this simple type definition or <code>null</code>.
2428: */
2429: public String getLexicalFacetValue(short facetName) {
2430: switch (facetName) {
2431: case FACET_LENGTH:
2432: return (fLength == -1) ? null : Integer.toString(fLength);
2433: case FACET_MINLENGTH:
2434: return (fMinLength == -1) ? null : Integer
2435: .toString(fMinLength);
2436: case FACET_MAXLENGTH:
2437: return (fMaxLength == -1) ? null : Integer
2438: .toString(fMaxLength);
2439: case FACET_WHITESPACE:
2440: return WS_FACET_STRING[fWhiteSpace];
2441: case FACET_MAXINCLUSIVE:
2442: return (fMaxInclusive == null) ? null : fMaxInclusive
2443: .toString();
2444: case FACET_MAXEXCLUSIVE:
2445: return (fMaxExclusive == null) ? null : fMaxExclusive
2446: .toString();
2447: case FACET_MINEXCLUSIVE:
2448: return (fMinExclusive == null) ? null : fMinExclusive
2449: .toString();
2450: case FACET_MININCLUSIVE:
2451: return (fMinInclusive == null) ? null : fMinInclusive
2452: .toString();
2453: case FACET_TOTALDIGITS:
2454: return (fTotalDigits == -1) ? null : Integer
2455: .toString(fTotalDigits);
2456: case FACET_FRACTIONDIGITS:
2457: if (fValidationDV == DV_INTEGER) {
2458: return "0";
2459: }
2460: return (fFractionDigits == -1) ? null : Integer
2461: .toString(fFractionDigits);
2462: }
2463: return null;
2464: }
2465:
2466: /**
2467: * A list of enumeration values if it exists, otherwise an empty
2468: * <code>StringList</code>.
2469: */
2470: public StringList getLexicalEnumeration() {
2471: if (fLexicalEnumeration == null) {
2472: if (fEnumeration == null)
2473: return StringListImpl.EMPTY_LIST;
2474: int size = fEnumeration.size();
2475: String[] strs = new String[size];
2476: for (int i = 0; i < size; i++)
2477: strs[i] = fEnumeration.elementAt(i).toString();
2478: fLexicalEnumeration = new StringListImpl(strs, size);
2479: }
2480: return fLexicalEnumeration;
2481: }
2482:
2483: /**
2484: * A list of actual enumeration values if it exists, otherwise an empty
2485: * <code>ObjectList</code>.
2486: */
2487: public ObjectList getActualEnumeration() {
2488: if (fActualEnumeration == null) {
2489: fActualEnumeration = new ObjectList() {
2490: public int getLength() {
2491: return (fEnumeration != null) ? fEnumeration.size()
2492: : 0;
2493: }
2494:
2495: public boolean contains(Object item) {
2496: return (fEnumeration != null && fEnumeration
2497: .contains(item));
2498: }
2499:
2500: public Object item(int index) {
2501: if (index < 0 || index >= getLength()) {
2502: return null;
2503: }
2504: return fEnumeration.elementAt(index);
2505: }
2506: };
2507: }
2508: return fActualEnumeration;
2509: }
2510:
2511: /**
2512: * A list of enumeration type values (as a list of ShortList objects) if it exists, otherwise returns
2513: * null
2514: */
2515: public ObjectList getEnumerationItemTypeList() {
2516: if (fEnumerationItemTypeList == null) {
2517: if (fEnumerationItemType == null)
2518: return null;
2519: fEnumerationItemTypeList = new ObjectList() {
2520: public int getLength() {
2521: return (fEnumerationItemType != null) ? fEnumerationItemType.length
2522: : 0;
2523: }
2524:
2525: public boolean contains(Object item) {
2526: if (fEnumerationItemType == null
2527: || !(item instanceof ShortList))
2528: return false;
2529: for (int i = 0; i < fEnumerationItemType.length; i++)
2530: if (fEnumerationItemType[i] == item)
2531: return true;
2532: return false;
2533: }
2534:
2535: public Object item(int index) {
2536: if (index < 0 || index >= getLength()) {
2537: return null;
2538: }
2539: return fEnumerationItemType[index];
2540: }
2541: };
2542: }
2543: return fEnumerationItemTypeList;
2544: }
2545:
2546: public ShortList getEnumerationTypeList() {
2547: if (fEnumerationTypeList == null) {
2548: if (fEnumerationType == null) {
2549: return ShortListImpl.EMPTY_LIST;
2550: }
2551: fEnumerationTypeList = new ShortListImpl(fEnumerationType,
2552: fEnumerationType.length);
2553: }
2554: return fEnumerationTypeList;
2555: }
2556:
2557: /**
2558: * A list of pattern values if it exists, otherwise an empty
2559: * <code>StringList</code>.
2560: */
2561: public StringList getLexicalPattern() {
2562: if (fPatternType == SPECIAL_PATTERN_NONE
2563: && fValidationDV != DV_INTEGER && fPatternStr == null)
2564: return StringListImpl.EMPTY_LIST;
2565: if (fLexicalPattern == null) {
2566: int size = fPatternStr == null ? 0 : fPatternStr.size();
2567: String[] strs;
2568: if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
2569: strs = new String[size + 1];
2570: strs[size] = "\\c+";
2571: } else if (fPatternType == SPECIAL_PATTERN_NAME) {
2572: strs = new String[size + 1];
2573: strs[size] = "\\i\\c*";
2574: } else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
2575: strs = new String[size + 2];
2576: strs[size] = "\\i\\c*";
2577: strs[size + 1] = "[\\i-[:]][\\c-[:]]*";
2578: } else if (fValidationDV == DV_INTEGER) {
2579: strs = new String[size + 1];
2580: strs[size] = "[\\-+]?[0-9]+";
2581: } else {
2582: strs = new String[size];
2583: }
2584: for (int i = 0; i < size; i++)
2585: strs[i] = (String) fPatternStr.elementAt(i);
2586: fLexicalPattern = new StringListImpl(strs, strs.length);
2587: }
2588: return fLexicalPattern;
2589: }
2590:
2591: /**
2592: * [annotations]: a set of annotations for this simple type component if
2593: * it exists, otherwise an empty <code>XSObjectList</code>.
2594: */
2595: public XSObjectList getAnnotations() {
2596: return (fAnnotations != null) ? fAnnotations
2597: : XSObjectListImpl.EMPTY_LIST;
2598: }
2599:
2600: private void calcFundamentalFacets() {
2601: setOrdered();
2602: setNumeric();
2603: setBounded();
2604: setCardinality();
2605: }
2606:
2607: private void setOrdered() {
2608:
2609: // When {variety} is atomic, {value} is inherited from {value} of {base type definition}. For all "primitive" types {value} is as specified in the table in Fundamental Facets (C.1).
2610: if (fVariety == VARIETY_ATOMIC) {
2611: this .fOrdered = fBase.fOrdered;
2612: }
2613:
2614: // When {variety} is list, {value} is false.
2615: else if (fVariety == VARIETY_LIST) {
2616: this .fOrdered = ORDERED_FALSE;
2617: }
2618:
2619: // When {variety} is union, the {value} is partial unless one of the following:
2620: // 1. If every member of {member type definitions} is derived from a common ancestor other than the simple ur-type, then {value} is the same as that ancestor's ordered facet.
2621: // 2. If every member of {member type definitions} has a {value} of false for the ordered facet, then {value} is false.
2622: else if (fVariety == VARIETY_UNION) {
2623: int length = fMemberTypes.length;
2624: // REVISIT: is the length possible to be 0?
2625: if (length == 0) {
2626: this .fOrdered = ORDERED_PARTIAL;
2627: return;
2628: }
2629: // we need to process the first member type before entering the loop
2630: short ancestorId = getPrimitiveDV(fMemberTypes[0].fValidationDV);
2631: boolean commonAnc = ancestorId != DV_ANYSIMPLETYPE;
2632: boolean allFalse = fMemberTypes[0].fOrdered == ORDERED_FALSE;
2633: // for the other member types, check whether the value is false
2634: // and whether they have the same ancestor as the first one
2635: for (int i = 1; i < fMemberTypes.length
2636: && (commonAnc || allFalse); i++) {
2637: if (commonAnc)
2638: commonAnc = ancestorId == getPrimitiveDV(fMemberTypes[i].fValidationDV);
2639: if (allFalse)
2640: allFalse = fMemberTypes[i].fOrdered == ORDERED_FALSE;
2641: }
2642: if (commonAnc) {
2643: // REVISIT: all member types should have the same ordered value
2644: // just use the first one. Can we assume this?
2645: this .fOrdered = fMemberTypes[0].fOrdered;
2646: } else if (allFalse) {
2647: this .fOrdered = ORDERED_FALSE;
2648: } else {
2649: this .fOrdered = ORDERED_PARTIAL;
2650: }
2651: }
2652:
2653: }//setOrdered
2654:
2655: private void setNumeric() {
2656: if (fVariety == VARIETY_ATOMIC) {
2657: this .fNumeric = fBase.fNumeric;
2658: } else if (fVariety == VARIETY_LIST) {
2659: this .fNumeric = false;
2660: } else if (fVariety == VARIETY_UNION) {
2661: XSSimpleType[] memberTypes = fMemberTypes;
2662: for (int i = 0; i < memberTypes.length; i++) {
2663: if (!memberTypes[i].getNumeric()) {
2664: this .fNumeric = false;
2665: return;
2666: }
2667: }
2668: this .fNumeric = true;
2669: }
2670:
2671: }//setNumeric
2672:
2673: private void setBounded() {
2674: if (fVariety == VARIETY_ATOMIC) {
2675: if ((((this .fFacetsDefined & FACET_MININCLUSIVE) != 0) || ((this .fFacetsDefined & FACET_MINEXCLUSIVE) != 0))
2676: && (((this .fFacetsDefined & FACET_MAXINCLUSIVE) != 0) || ((this .fFacetsDefined & FACET_MAXEXCLUSIVE) != 0))) {
2677: this .fBounded = true;
2678: } else {
2679: this .fBounded = false;
2680: }
2681: } else if (fVariety == VARIETY_LIST) {
2682: if (((this .fFacetsDefined & FACET_LENGTH) != 0)
2683: || (((this .fFacetsDefined & FACET_MINLENGTH) != 0) && ((this .fFacetsDefined & FACET_MAXLENGTH) != 0))) {
2684: this .fBounded = true;
2685: } else {
2686: this .fBounded = false;
2687: }
2688:
2689: } else if (fVariety == VARIETY_UNION) {
2690:
2691: XSSimpleTypeDecl[] memberTypes = this .fMemberTypes;
2692: short ancestorId = 0;
2693:
2694: if (memberTypes.length > 0) {
2695: ancestorId = getPrimitiveDV(memberTypes[0].fValidationDV);
2696: }
2697:
2698: for (int i = 0; i < memberTypes.length; i++) {
2699: if (!memberTypes[i].getBounded()
2700: || (ancestorId != getPrimitiveDV(memberTypes[i].fValidationDV))) {
2701: this .fBounded = false;
2702: return;
2703: }
2704: }
2705: this .fBounded = true;
2706: }
2707:
2708: }//setBounded
2709:
2710: private boolean specialCardinalityCheck() {
2711: if ((fBase.fValidationDV == XSSimpleTypeDecl.DV_DATE)
2712: || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEARMONTH)
2713: || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEAR)
2714: || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTHDAY)
2715: || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GDAY)
2716: || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTH)) {
2717: return true;
2718: }
2719: return false;
2720:
2721: } //specialCardinalityCheck()
2722:
2723: private void setCardinality() {
2724: if (fVariety == VARIETY_ATOMIC) {
2725: if (fBase.fFinite) {
2726: this .fFinite = true;
2727: } else {// (!fBase.fFinite)
2728: if (((this .fFacetsDefined & FACET_LENGTH) != 0)
2729: || ((this .fFacetsDefined & FACET_MAXLENGTH) != 0)
2730: || ((this .fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
2731: this .fFinite = true;
2732: } else if ((((this .fFacetsDefined & FACET_MININCLUSIVE) != 0) || ((this .fFacetsDefined & FACET_MINEXCLUSIVE) != 0))
2733: && (((this .fFacetsDefined & FACET_MAXINCLUSIVE) != 0) || ((this .fFacetsDefined & FACET_MAXEXCLUSIVE) != 0))) {
2734: if (((this .fFacetsDefined & FACET_FRACTIONDIGITS) != 0)
2735: || specialCardinalityCheck()) {
2736: this .fFinite = true;
2737: } else {
2738: this .fFinite = false;
2739: }
2740: } else {
2741: this .fFinite = false;
2742: }
2743: }
2744: } else if (fVariety == VARIETY_LIST) {
2745: if (((this .fFacetsDefined & FACET_LENGTH) != 0)
2746: || (((this .fFacetsDefined & FACET_MINLENGTH) != 0) && ((this .fFacetsDefined & FACET_MAXLENGTH) != 0))) {
2747: this .fFinite = true;
2748: } else {
2749: this .fFinite = false;
2750: }
2751:
2752: } else if (fVariety == VARIETY_UNION) {
2753: XSSimpleType[] memberTypes = fMemberTypes;
2754: for (int i = 0; i < memberTypes.length; i++) {
2755: if (!(memberTypes[i].getFinite())) {
2756: this .fFinite = false;
2757: return;
2758: }
2759: }
2760: this .fFinite = true;
2761: }
2762:
2763: }//setCardinality
2764:
2765: private short getPrimitiveDV(short validationDV) {
2766:
2767: if (validationDV == DV_ID || validationDV == DV_IDREF
2768: || validationDV == DV_ENTITY) {
2769: return DV_STRING;
2770: } else if (validationDV == DV_INTEGER) {
2771: return DV_DECIMAL;
2772: } else if (Constants.SCHEMA_1_1_SUPPORT
2773: && (validationDV == DV_YEARMONTHDURATION || validationDV == DV_DAYTIMEDURATION)) {
2774: return DV_DURATION;
2775: } else {
2776: return validationDV;
2777: }
2778:
2779: }//getPrimitiveDV()
2780:
2781: public boolean derivedFromType(XSTypeDefinition ancestor,
2782: short derivation) {
2783: // REVISIT: implement according to derivation
2784:
2785: // ancestor is null, retur false
2786: if (ancestor == null)
2787: return false;
2788: // ancestor is anyType, return true
2789: // anyType is the only type whose base type is itself
2790: if (ancestor.getBaseType() == ancestor)
2791: return true;
2792: // recursively get base, and compare it with ancestor
2793: XSTypeDefinition type = this ;
2794: while (type != ancestor && // compare with ancestor
2795: type != fAnySimpleType) { // reached anySimpleType
2796: type = type.getBaseType();
2797: }
2798:
2799: return type == ancestor;
2800: }
2801:
2802: public boolean derivedFrom(String ancestorNS, String ancestorName,
2803: short derivation) {
2804: // REVISIT: implement according to derivation
2805:
2806: // ancestor is null, retur false
2807: if (ancestorName == null)
2808: return false;
2809: // ancestor is anyType, return true
2810: if (URI_SCHEMAFORSCHEMA.equals(ancestorNS)
2811: && ANY_TYPE.equals(ancestorName)) {
2812: return true;
2813: }
2814:
2815: // recursively get base, and compare it with ancestor
2816: XSTypeDefinition type = this ;
2817: while (!(ancestorName.equals(type.getName()) && ((ancestorNS == null && type
2818: .getNamespace() == null) || (ancestorNS != null && ancestorNS
2819: .equals(type.getNamespace()))))
2820: && // compare with ancestor
2821: type != fAnySimpleType) { // reached anySimpleType
2822: type = (XSTypeDefinition) type.getBaseType();
2823: }
2824:
2825: return type != fAnySimpleType;
2826: }
2827:
2828: /**
2829: * Checks if a type is derived from another by restriction, given the name
2830: * and namespace. See:
2831: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2832: *
2833: * @param ancestorNS
2834: * The namspace of the ancestor type declaration
2835: * @param ancestorName
2836: * The name of the ancestor type declaration
2837: * @param derivationMethod
2838: * The derivation method
2839: *
2840: * @return boolean True if the ancestor type is derived from the reference type by the specifiied derivation method.
2841: */
2842: public boolean isDOMDerivedFrom(String ancestorNS,
2843: String ancestorName, int derivationMethod) {
2844:
2845: // ancestor is null, return false
2846: if (ancestorName == null)
2847: return false;
2848:
2849: // ancestor is anyType, return true
2850: if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(ancestorNS)
2851: && SchemaSymbols.ATTVAL_ANYTYPE.equals(ancestorName)
2852: && (((derivationMethod & DERIVATION_RESTRICTION) != 0) || (derivationMethod == DERIVATION_ANY))) {
2853: return true;
2854: }
2855:
2856: // restriction
2857: if ((derivationMethod & DERIVATION_RESTRICTION) != 0) {
2858: if (isDerivedByRestriction(ancestorNS, ancestorName, this )) {
2859: return true;
2860: }
2861: }
2862:
2863: // list
2864: if ((derivationMethod & DERIVATION_LIST) != 0) {
2865: if (isDerivedByList(ancestorNS, ancestorName, this )) {
2866: return true;
2867: }
2868: }
2869:
2870: // union
2871: if ((derivationMethod & DERIVATION_UNION) != 0) {
2872: if (isDerivedByUnion(ancestorNS, ancestorName, this )) {
2873: return true;
2874: }
2875: }
2876:
2877: // extension
2878: if (((derivationMethod & DERIVATION_EXTENSION) != 0)
2879: && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
2880: && ((derivationMethod & DERIVATION_LIST) == 0) && ((derivationMethod & DERIVATION_UNION) == 0))) {
2881: return false;
2882: }
2883:
2884: // If the value of the parameter is 0 i.e. no bit (corresponding to
2885: // restriction, list, extension or union) is set to 1 for the
2886: // derivationMethod parameter.
2887: if (((derivationMethod & DERIVATION_EXTENSION) == 0)
2888: && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
2889: && ((derivationMethod & DERIVATION_LIST) == 0) && ((derivationMethod & DERIVATION_UNION) == 0))) {
2890: return isDerivedByAny(ancestorNS, ancestorName, this );
2891: }
2892:
2893: return false;
2894: }
2895:
2896: /**
2897: * Checks if a type is derived from another by any combination of restriction, list ir union. See:
2898: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2899: *
2900: * @param ancestorNS
2901: * The namspace of the ancestor type declaration
2902: * @param ancestorName
2903: * The name of the ancestor type declaration
2904: * @param type
2905: * The reference type definition
2906: *
2907: * @return boolean True if the type is derived by restriciton for the reference type
2908: */
2909: private boolean isDerivedByAny(String ancestorNS,
2910: String ancestorName, XSTypeDefinition type) {
2911:
2912: boolean derivedFrom = false;
2913: XSTypeDefinition oldType = null;
2914: // for each base, item or member type
2915: while (type != null && type != oldType) {
2916:
2917: // If the ancestor type is reached or is the same as this type.
2918: if ((ancestorName.equals(type.getName()))
2919: && ((ancestorNS == null && type.getNamespace() == null) || (ancestorNS != null && ancestorNS
2920: .equals(type.getNamespace())))) {
2921: derivedFrom = true;
2922: break;
2923: }
2924:
2925: // check if derived by restriction or list or union
2926: if (isDerivedByRestriction(ancestorNS, ancestorName, type)) {
2927: return true;
2928: } else if (isDerivedByList(ancestorNS, ancestorName, type)) {
2929: return true;
2930: } else if (isDerivedByUnion(ancestorNS, ancestorName, type)) {
2931: return true;
2932: }
2933: oldType = type;
2934: // get the base, item or member type depending on the variety
2935: if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_ABSENT
2936: || ((XSSimpleTypeDecl) type).getVariety() == VARIETY_ATOMIC) {
2937: type = type.getBaseType();
2938: } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_UNION) {
2939: for (int i = 0; i < ((XSSimpleTypeDecl) type)
2940: .getMemberTypes().getLength(); i++) {
2941: return isDerivedByAny(
2942: ancestorNS,
2943: ancestorName,
2944: (XSTypeDefinition) ((XSSimpleTypeDecl) type)
2945: .getMemberTypes().item(i));
2946: }
2947: } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_LIST) {
2948: type = ((XSSimpleTypeDecl) type).getItemType();
2949: }
2950: }
2951:
2952: return derivedFrom;
2953: }
2954:
2955: /**
2956: * DOM Level 3
2957: * Checks if a type is derived from another by restriction. See:
2958: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2959: *
2960: * @param ancestorNS
2961: * The namspace of the ancestor type declaration
2962: * @param ancestorName
2963: * The name of the ancestor type declaration
2964: * @param type
2965: * The reference type definition
2966: *
2967: * @return boolean True if the type is derived by restriciton for the
2968: * reference type
2969: */
2970: private boolean isDerivedByRestriction(String ancestorNS,
2971: String ancestorName, XSTypeDefinition type) {
2972: XSTypeDefinition oldType = null;
2973: while (type != null && type != oldType) {
2974: if ((ancestorName.equals(type.getName()))
2975: && ((ancestorNS != null && ancestorNS.equals(type
2976: .getNamespace())) || (type.getNamespace() == null && ancestorNS == null))) {
2977:
2978: return true;
2979: }
2980: oldType = type;
2981: type = type.getBaseType();
2982: }
2983:
2984: return false;
2985: }
2986:
2987: /**
2988: * Checks if a type is derived from another by list. See:
2989: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2990: *
2991: * @param ancestorNS
2992: * The namspace of the ancestor type declaration
2993: * @param ancestorName
2994: * The name of the ancestor type declaration
2995: * @param type
2996: * The reference type definition
2997: *
2998: * @return boolean True if the type is derived by list for the reference type
2999: */
3000: private boolean isDerivedByList(String ancestorNS,
3001: String ancestorName, XSTypeDefinition type) {
3002: // If the variety is union
3003: if (type != null
3004: && ((XSSimpleTypeDefinition) type).getVariety() == VARIETY_LIST) {
3005:
3006: // get the {item type}
3007: XSTypeDefinition itemType = ((XSSimpleTypeDefinition) type)
3008: .getItemType();
3009:
3010: // T2 is the {item type definition}
3011: if (itemType != null) {
3012:
3013: // T2 is derived from the other type definition by DERIVATION_RESTRICTION
3014: if (isDerivedByRestriction(ancestorNS, ancestorName,
3015: itemType)) {
3016: return true;
3017: }
3018: }
3019: }
3020: return false;
3021: }
3022:
3023: /**
3024: * Checks if a type is derived from another by union. See:
3025: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
3026: *
3027: * @param ancestorNS
3028: * The namspace of the ancestor type declaration
3029: * @param ancestorName
3030: * The name of the ancestor type declaration
3031: * @param type
3032: * The reference type definition
3033: *
3034: * @return boolean True if the type is derived by union for the reference type
3035: */
3036: private boolean isDerivedByUnion(String ancestorNS,
3037: String ancestorName, XSTypeDefinition type) {
3038:
3039: // If the variety is union
3040: if (type != null
3041: && ((XSSimpleTypeDefinition) type).getVariety() == VARIETY_UNION) {
3042:
3043: // get member types
3044: XSObjectList memberTypes = ((XSSimpleTypeDefinition) type)
3045: .getMemberTypes();
3046:
3047: for (int i = 0; i < memberTypes.getLength(); i++) {
3048: // One of the {member type definitions} is T2.
3049: if (memberTypes.item(i) != null) {
3050: // T2 is derived from the other type definition by DERIVATION_RESTRICTION
3051: if (isDerivedByRestriction(ancestorNS,
3052: ancestorName,
3053: (XSSimpleTypeDefinition) memberTypes
3054: .item(i))) {
3055: return true;
3056: }
3057: }
3058: }
3059: }
3060: return false;
3061: }
3062:
3063: static final XSSimpleTypeDecl fAnySimpleType = new XSSimpleTypeDecl(
3064: null, "anySimpleType", DV_ANYSIMPLETYPE, ORDERED_FALSE,
3065: false, true, false, true, XSConstants.ANYSIMPLETYPE_DT);
3066:
3067: static final XSSimpleTypeDecl fAnyAtomicType = new XSSimpleTypeDecl(
3068: fAnySimpleType, "anyAtomicType", DV_ANYATOMICTYPE,
3069: ORDERED_FALSE, false, true, false, true,
3070: XSSimpleTypeDecl.ANYATOMICTYPE_DT);
3071:
3072: /**
3073: * Validation context used to validate facet values.
3074: */
3075: static final ValidationContext fDummyContext = new ValidationContext() {
3076: public boolean needFacetChecking() {
3077: return true;
3078: }
3079:
3080: public boolean needExtraChecking() {
3081: return false;
3082: }
3083:
3084: public boolean needToNormalize() {
3085: return false;
3086: }
3087:
3088: public boolean useNamespaces() {
3089: return true;
3090: }
3091:
3092: public boolean isEntityDeclared(String name) {
3093: return false;
3094: }
3095:
3096: public boolean isEntityUnparsed(String name) {
3097: return false;
3098: }
3099:
3100: public boolean isIdDeclared(String name) {
3101: return false;
3102: }
3103:
3104: public void addId(String name) {
3105: }
3106:
3107: public void addIdRef(String name) {
3108: }
3109:
3110: public String getSymbol(String symbol) {
3111: return symbol.intern();
3112: }
3113:
3114: public String getURI(String prefix) {
3115: return null;
3116: }
3117: };
3118:
3119: private boolean fAnonymous = false;
3120:
3121: /**
3122: * A wrapper of ValidationContext, to provide a way of switching to a
3123: * different Namespace declaration context.
3124: */
3125: static final class ValidationContextImpl implements
3126: ValidationContext {
3127:
3128: final ValidationContext fExternal;
3129:
3130: ValidationContextImpl(ValidationContext external) {
3131: fExternal = external;
3132: }
3133:
3134: NamespaceContext fNSContext;
3135:
3136: void setNSContext(NamespaceContext nsContext) {
3137: fNSContext = nsContext;
3138: }
3139:
3140: public boolean needFacetChecking() {
3141: return fExternal.needFacetChecking();
3142: }
3143:
3144: public boolean needExtraChecking() {
3145: return fExternal.needExtraChecking();
3146: }
3147:
3148: public boolean needToNormalize() {
3149: return fExternal.needToNormalize();
3150: }
3151:
3152: // schema validation is predicated upon namespaces
3153: public boolean useNamespaces() {
3154: return true;
3155: }
3156:
3157: public boolean isEntityDeclared(String name) {
3158: return fExternal.isEntityDeclared(name);
3159: }
3160:
3161: public boolean isEntityUnparsed(String name) {
3162: return fExternal.isEntityUnparsed(name);
3163: }
3164:
3165: public boolean isIdDeclared(String name) {
3166: return fExternal.isIdDeclared(name);
3167: }
3168:
3169: public void addId(String name) {
3170: fExternal.addId(name);
3171: }
3172:
3173: public void addIdRef(String name) {
3174: fExternal.addIdRef(name);
3175: }
3176:
3177: public String getSymbol(String symbol) {
3178: return fExternal.getSymbol(symbol);
3179: }
3180:
3181: public String getURI(String prefix) {
3182: if (fNSContext == null) {
3183: return fExternal.getURI(prefix);
3184: } else {
3185: return fNSContext.getURI(prefix);
3186: }
3187: }
3188: }
3189:
3190: public void reset() {
3191:
3192: // if it's immutable, can't be reset:
3193: if (fIsImmutable)
3194: return;
3195: fItemType = null;
3196: fMemberTypes = null;
3197:
3198: fTypeName = null;
3199: fTargetNamespace = null;
3200: fFinalSet = 0;
3201: fBase = null;
3202: fVariety = -1;
3203: fValidationDV = -1;
3204:
3205: fFacetsDefined = 0;
3206: fFixedFacet = 0;
3207:
3208: //for constraining facets
3209: fWhiteSpace = 0;
3210: fLength = -1;
3211: fMinLength = -1;
3212: fMaxLength = -1;
3213: fTotalDigits = -1;
3214: fFractionDigits = -1;
3215: fPattern = null;
3216: fPatternStr = null;
3217: fEnumeration = null;
3218: fEnumerationType = null;
3219: fEnumerationItemType = null;
3220: fLexicalPattern = null;
3221: fLexicalEnumeration = null;
3222: fMaxInclusive = null;
3223: fMaxExclusive = null;
3224: fMinExclusive = null;
3225: fMinInclusive = null;
3226: lengthAnnotation = null;
3227: minLengthAnnotation = null;
3228: maxLengthAnnotation = null;
3229: whiteSpaceAnnotation = null;
3230: totalDigitsAnnotation = null;
3231: fractionDigitsAnnotation = null;
3232: patternAnnotations = null;
3233: enumerationAnnotations = null;
3234: maxInclusiveAnnotation = null;
3235: maxExclusiveAnnotation = null;
3236: minInclusiveAnnotation = null;
3237: minExclusiveAnnotation = null;
3238:
3239: fPatternType = SPECIAL_PATTERN_NONE;
3240: fAnnotations = null;
3241: fFacets = null;
3242:
3243: // REVISIT: reset for fundamental facets
3244: }
3245:
3246: /**
3247: * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
3248: */
3249: public XSNamespaceItem getNamespaceItem() {
3250: // REVISIT: implement
3251: return null;
3252: }
3253:
3254: /**
3255: * @see java.lang.Object#toString()
3256: */
3257: public String toString() {
3258: return this .fTargetNamespace + "," + this .fTypeName;
3259: }
3260:
3261: /**
3262: * A list of constraining facets if it exists, otherwise an empty
3263: * <code>XSObjectList</code>. Note: This method must not be used to
3264: * retrieve values for <code>enumeration</code> and <code>pattern</code>
3265: * facets.
3266: */
3267: public XSObjectList getFacets() {
3268: if (fFacets == null
3269: && (fFacetsDefined != 0 || fValidationDV == DV_INTEGER)) {
3270:
3271: XSFacetImpl[] facets = new XSFacetImpl[10];
3272: int count = 0;
3273: if ((fFacetsDefined & FACET_WHITESPACE) != 0) {
3274: facets[count] = new XSFacetImpl(FACET_WHITESPACE,
3275: WS_FACET_STRING[fWhiteSpace],
3276: (fFixedFacet & FACET_WHITESPACE) != 0,
3277: whiteSpaceAnnotation);
3278: count++;
3279: }
3280: if (fLength != -1) {
3281: facets[count] = new XSFacetImpl(FACET_LENGTH, Integer
3282: .toString(fLength),
3283: (fFixedFacet & FACET_LENGTH) != 0,
3284: lengthAnnotation);
3285: count++;
3286: }
3287: if (fMinLength != -1) {
3288: facets[count] = new XSFacetImpl(FACET_MINLENGTH,
3289: Integer.toString(fMinLength),
3290: (fFixedFacet & FACET_MINLENGTH) != 0,
3291: minLengthAnnotation);
3292: count++;
3293: }
3294: if (fMaxLength != -1) {
3295: facets[count] = new XSFacetImpl(FACET_MAXLENGTH,
3296: Integer.toString(fMaxLength),
3297: (fFixedFacet & FACET_MAXLENGTH) != 0,
3298: maxLengthAnnotation);
3299: count++;
3300: }
3301: if (fTotalDigits != -1) {
3302: facets[count] = new XSFacetImpl(FACET_TOTALDIGITS,
3303: Integer.toString(fTotalDigits),
3304: (fFixedFacet & FACET_TOTALDIGITS) != 0,
3305: totalDigitsAnnotation);
3306: count++;
3307: }
3308: if (fValidationDV == DV_INTEGER) {
3309: facets[count] = new XSFacetImpl(FACET_FRACTIONDIGITS,
3310: "0", true, fractionDigitsAnnotation);
3311: count++;
3312: } else if (fFractionDigits != -1) {
3313: facets[count] = new XSFacetImpl(FACET_FRACTIONDIGITS,
3314: Integer.toString(fFractionDigits),
3315: (fFixedFacet & FACET_FRACTIONDIGITS) != 0,
3316: fractionDigitsAnnotation);
3317: count++;
3318: }
3319: if (fMaxInclusive != null) {
3320: facets[count] = new XSFacetImpl(FACET_MAXINCLUSIVE,
3321: fMaxInclusive.toString(),
3322: (fFixedFacet & FACET_MAXINCLUSIVE) != 0,
3323: maxInclusiveAnnotation);
3324: count++;
3325: }
3326: if (fMaxExclusive != null) {
3327: facets[count] = new XSFacetImpl(FACET_MAXEXCLUSIVE,
3328: fMaxExclusive.toString(),
3329: (fFixedFacet & FACET_MAXEXCLUSIVE) != 0,
3330: maxExclusiveAnnotation);
3331: count++;
3332: }
3333: if (fMinExclusive != null) {
3334: facets[count] = new XSFacetImpl(FACET_MINEXCLUSIVE,
3335: fMinExclusive.toString(),
3336: (fFixedFacet & FACET_MINEXCLUSIVE) != 0,
3337: minExclusiveAnnotation);
3338: count++;
3339: }
3340: if (fMinInclusive != null) {
3341: facets[count] = new XSFacetImpl(FACET_MININCLUSIVE,
3342: fMinInclusive.toString(),
3343: (fFixedFacet & FACET_MININCLUSIVE) != 0,
3344: minInclusiveAnnotation);
3345: count++;
3346: }
3347: fFacets = new XSObjectListImpl(facets, count);
3348: }
3349: return (fFacets != null) ? fFacets
3350: : XSObjectListImpl.EMPTY_LIST;
3351: }
3352:
3353: /**
3354: * A list of enumeration and pattern constraining facets if it exists,
3355: * otherwise an empty <code>XSObjectList</code>.
3356: */
3357: public XSObjectList getMultiValueFacets() {
3358: if (fMultiValueFacets == null
3359: && ((fFacetsDefined & FACET_ENUMERATION) != 0
3360: || (fFacetsDefined & FACET_PATTERN) != 0
3361: || fPatternType != SPECIAL_PATTERN_NONE || fValidationDV == DV_INTEGER)) {
3362:
3363: XSMVFacetImpl[] facets = new XSMVFacetImpl[2];
3364: int count = 0;
3365: if ((fFacetsDefined & FACET_PATTERN) != 0
3366: || fPatternType != SPECIAL_PATTERN_NONE
3367: || fValidationDV == DV_INTEGER) {
3368: facets[count] = new XSMVFacetImpl(FACET_PATTERN, this
3369: .getLexicalPattern(), patternAnnotations);
3370: count++;
3371: }
3372: if (fEnumeration != null) {
3373: facets[count] = new XSMVFacetImpl(FACET_ENUMERATION,
3374: this .getLexicalEnumeration(),
3375: enumerationAnnotations);
3376: count++;
3377: }
3378: fMultiValueFacets = new XSObjectListImpl(facets, count);
3379: }
3380: return (fMultiValueFacets != null) ? fMultiValueFacets
3381: : XSObjectListImpl.EMPTY_LIST;
3382: }
3383:
3384: public Object getMinInclusiveValue() {
3385: return fMinInclusive;
3386: }
3387:
3388: public Object getMinExclusiveValue() {
3389: return fMinExclusive;
3390: }
3391:
3392: public Object getMaxInclusiveValue() {
3393: return fMaxInclusive;
3394: }
3395:
3396: public Object getMaxExclusiveValue() {
3397: return fMaxExclusive;
3398: }
3399:
3400: public void setAnonymous(boolean anon) {
3401: fAnonymous = anon;
3402: }
3403:
3404: private static final class XSFacetImpl implements XSFacet {
3405: final short kind;
3406: final String value;
3407: final boolean fixed;
3408: final XSObjectList annotations;
3409:
3410: public XSFacetImpl(short kind, String value, boolean fixed,
3411: XSAnnotation annotation) {
3412: this .kind = kind;
3413: this .value = value;
3414: this .fixed = fixed;
3415:
3416: if (annotation != null) {
3417: this .annotations = new XSObjectListImpl();
3418: ((XSObjectListImpl) this .annotations).add(annotation);
3419: } else {
3420: this .annotations = XSObjectListImpl.EMPTY_LIST;
3421: }
3422: }
3423:
3424: /*
3425: * (non-Javadoc)
3426: *
3427: * @see org.apache.xerces.xs.XSFacet#getAnnotation()
3428: */
3429: /**
3430: * Optional. Annotation.
3431: */
3432: public XSAnnotation getAnnotation() {
3433: return (XSAnnotation) annotations.item(0);
3434: }
3435:
3436: /*
3437: * (non-Javadoc)
3438: *
3439: * @see org.apache.xerces.xs.XSFacet#getAnnotations()
3440: */
3441: /**
3442: * Optional. Annotations.
3443: */
3444: public XSObjectList getAnnotations() {
3445: return annotations;
3446: }
3447:
3448: /* (non-Javadoc)
3449: * @see org.apache.xerces.xs.XSFacet#getFacetKind()
3450: */
3451: public short getFacetKind() {
3452: return kind;
3453: }
3454:
3455: /* (non-Javadoc)
3456: * @see org.apache.xerces.xs.XSFacet#getLexicalFacetValue()
3457: */
3458: public String getLexicalFacetValue() {
3459: return value;
3460: }
3461:
3462: /* (non-Javadoc)
3463: * @see org.apache.xerces.xs.XSFacet#isFixed()
3464: */
3465: public boolean getFixed() {
3466: return fixed;
3467: }
3468:
3469: /* (non-Javadoc)
3470: * @see org.apache.xerces.xs.XSObject#getName()
3471: */
3472: public String getName() {
3473: return null;
3474: }
3475:
3476: /* (non-Javadoc)
3477: * @see org.apache.xerces.xs.XSObject#getNamespace()
3478: */
3479: public String getNamespace() {
3480: return null;
3481: }
3482:
3483: /* (non-Javadoc)
3484: * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
3485: */
3486: public XSNamespaceItem getNamespaceItem() {
3487: // REVISIT: implement
3488: return null;
3489: }
3490:
3491: /* (non-Javadoc)
3492: * @see org.apache.xerces.xs.XSObject#getType()
3493: */
3494: public short getType() {
3495: return XSConstants.FACET;
3496: }
3497:
3498: }
3499:
3500: private static final class XSMVFacetImpl implements
3501: XSMultiValueFacet {
3502: final short kind;
3503: final XSObjectList annotations;
3504: final StringList values;
3505:
3506: public XSMVFacetImpl(short kind, StringList values,
3507: XSObjectList annotations) {
3508: this .kind = kind;
3509: this .values = values;
3510: this .annotations = (annotations != null) ? annotations
3511: : XSObjectListImpl.EMPTY_LIST;
3512: }
3513:
3514: /* (non-Javadoc)
3515: * @see org.apache.xerces.xs.XSFacet#getFacetKind()
3516: */
3517: public short getFacetKind() {
3518: return kind;
3519: }
3520:
3521: /* (non-Javadoc)
3522: * @see org.apache.xerces.xs.XSMultiValueFacet#getAnnotations()
3523: */
3524: public XSObjectList getAnnotations() {
3525: return annotations;
3526: }
3527:
3528: /* (non-Javadoc)
3529: * @see org.apache.xerces.xs.XSMultiValueFacet#getLexicalFacetValues()
3530: */
3531: public StringList getLexicalFacetValues() {
3532: return values;
3533: }
3534:
3535: /* (non-Javadoc)
3536: * @see org.apache.xerces.xs.XSObject#getName()
3537: */
3538: public String getName() {
3539: return null;
3540: }
3541:
3542: /* (non-Javadoc)
3543: * @see org.apache.xerces.xs.XSObject#getNamespace()
3544: */
3545: public String getNamespace() {
3546: return null;
3547: }
3548:
3549: /* (non-Javadoc)
3550: * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
3551: */
3552: public XSNamespaceItem getNamespaceItem() {
3553: // REVISIT: implement
3554: return null;
3555: }
3556:
3557: /* (non-Javadoc)
3558: * @see org.apache.xerces.xs.XSObject#getType()
3559: */
3560: public short getType() {
3561: return XSConstants.MULTIVALUE_FACET;
3562: }
3563: }
3564:
3565: public String getTypeNamespace() {
3566: return getNamespace();
3567: }
3568:
3569: public boolean isDerivedFrom(String typeNamespaceArg,
3570: String typeNameArg, int derivationMethod) {
3571: return isDOMDerivedFrom(typeNamespaceArg, typeNameArg,
3572: derivationMethod);
3573: }
3574:
3575: private short convertToPrimitiveKind(short valueType) {
3576: /** Primitive datatypes. */
3577: if (valueType <= XSConstants.NOTATION_DT) {
3578: return valueType;
3579: }
3580: /** Types derived from string. */
3581: if (valueType <= XSConstants.ENTITY_DT) {
3582: return XSConstants.STRING_DT;
3583: }
3584: /** Types derived from decimal. */
3585: if (valueType <= XSConstants.POSITIVEINTEGER_DT) {
3586: return XSConstants.DECIMAL_DT;
3587: }
3588: /** Other types. */
3589: return valueType;
3590: }
3591:
3592: } // class XSSimpleTypeDecl
|